Black Friday & Cyber Monday SUPER SALE ALL WEEK:
Grab 40% OFF on plugins
00 Days
00 Hours
00 Minutes
00 Seconds

How to Set Custom Delivery Dates for Each WooCommerce Products (Including Holidays & Weekends)

As a WooCommerce store owner, one of the trickiest parts of running your business is to show the right delivery times to customers. Delivery dates and amount of time might differ for each product based on various factors. On top of that, weekends and holidays can mess with your delivery schedule, making it harder to give your customers the right information.

To address these challenges, plugins such as Product Delivery Date for WooCommerce
can help you to set a unique delivery schedule for different WooCommerce products. The plugin comes with handy features that will let you charge extra for deliveries during peak hours, block out a few days/time-slots, add extra delivery charges for certain products, particular shipping methods, location, delivery on holidays, and peak-hour time slots, etc.

In this post, we’ll show you how to set up custom delivery dates for each product that will exclude weekends and holidays, so your customers always know when to expect their orders, no matter what they’re buying. 

Solution: Set Custom Delivery Dates for Each WooCommerce Products (Including Holidays & Weekends)

This code adds a custom field to the WooCommerce product settings page where you can define the “Delivery Lead Time” for each product.

Note: If the Delivery lead time field is left empty, then the default value of 1 day will be considered as defined in the code. 

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Add a custom field for delivery lead time in product settings
add_action('woocommerce_product_options_general_product_data', 'ts_add_delivery_lead_time_field');
function ts_add_delivery_lead_time_field() {
woocommerce_wp_text_input(array(
'id' => 'delivery_lead_time',
'label' => __('Delivery Lead Time (in days)', 'woocommerce'),
'description' => __('Enter the number of days required for delivery for this product.', 'woocommerce'),
'desc_tip' => true,
'type' => 'number',
'custom_attributes' => array(
'min' => '0', // Minimum delivery time
),
));
}
// Save the custom field value
add_action('woocommerce_process_product_meta', 'ts_save_delivery_lead_time_field');
function ts_save_delivery_lead_time_field($post_id) {
$delivery_lead_time = isset($_POST['delivery_lead_time']) ? sanitize_text_field($_POST['delivery_lead_time']) : '';
update_post_meta($post_id, 'delivery_lead_time', $delivery_lead_time);
}
// Display the estimated delivery date on the product page
add_action('woocommerce_after_add_to_cart_form', 'ts_show_estimated_delivery_date');
function ts_show_estimated_delivery_date() {
global $product;
// Get the delivery lead time for the current product
$lead_time = get_post_meta($product->get_id(), 'delivery_lead_time', true);
// Fallback to a default lead time if none is set
$lead_time = $lead_time ? intval($lead_time) : 1;
// Define public holidays
$public_holidays = array(
'2025-01-20', // Monday (Martin Luther King Jr. Day)
'2025-01-22', // Wednesday (Custom Example Holiday)
);
// Calculate the initial delivery date
$delivery_date = new DateTime(current_time('mysql'));
$delivery_date->modify("+{$lead_time} days");
// Adjust for public holidays and weekends
while (in_array($delivery_date->format('Y-m-d'), $public_holidays) || in_array($delivery_date->format('N'), array(6, 7))) {
$delivery_date->modify('+1 day');
}
// Format the delivery date
$formatted_date = $delivery_date->format('l, jS F');
// Display the message
echo "<div class='woocommerce-message' style='clear:both'>Estimated delivery date: <strong>{$formatted_date}</strong></div>";
}
// Add a custom field for delivery lead time in product settings add_action('woocommerce_product_options_general_product_data', 'ts_add_delivery_lead_time_field'); function ts_add_delivery_lead_time_field() { woocommerce_wp_text_input(array( 'id' => 'delivery_lead_time', 'label' => __('Delivery Lead Time (in days)', 'woocommerce'), 'description' => __('Enter the number of days required for delivery for this product.', 'woocommerce'), 'desc_tip' => true, 'type' => 'number', 'custom_attributes' => array( 'min' => '0', // Minimum delivery time ), )); } // Save the custom field value add_action('woocommerce_process_product_meta', 'ts_save_delivery_lead_time_field'); function ts_save_delivery_lead_time_field($post_id) { $delivery_lead_time = isset($_POST['delivery_lead_time']) ? sanitize_text_field($_POST['delivery_lead_time']) : ''; update_post_meta($post_id, 'delivery_lead_time', $delivery_lead_time); } // Display the estimated delivery date on the product page add_action('woocommerce_after_add_to_cart_form', 'ts_show_estimated_delivery_date'); function ts_show_estimated_delivery_date() { global $product; // Get the delivery lead time for the current product $lead_time = get_post_meta($product->get_id(), 'delivery_lead_time', true); // Fallback to a default lead time if none is set $lead_time = $lead_time ? intval($lead_time) : 1; // Define public holidays $public_holidays = array( '2025-01-20', // Monday (Martin Luther King Jr. Day) '2025-01-22', // Wednesday (Custom Example Holiday) ); // Calculate the initial delivery date $delivery_date = new DateTime(current_time('mysql')); $delivery_date->modify("+{$lead_time} days"); // Adjust for public holidays and weekends while (in_array($delivery_date->format('Y-m-d'), $public_holidays) || in_array($delivery_date->format('N'), array(6, 7))) { $delivery_date->modify('+1 day'); } // Format the delivery date $formatted_date = $delivery_date->format('l, jS F'); // Display the message echo "<div class='woocommerce-message' style='clear:both'>Estimated delivery date: <strong>{$formatted_date}</strong></div>"; }
// Add a custom field for delivery lead time in product settings
add_action('woocommerce_product_options_general_product_data', 'ts_add_delivery_lead_time_field');
function ts_add_delivery_lead_time_field() {
    woocommerce_wp_text_input(array(
        'id' => 'delivery_lead_time',
        'label' => __('Delivery Lead Time (in days)', 'woocommerce'),
        'description' => __('Enter the number of days required for delivery for this product.', 'woocommerce'),
        'desc_tip' => true,
        'type' => 'number',
        'custom_attributes' => array(
            'min' => '0', // Minimum delivery time
        ),
    ));
}

// Save the custom field value
add_action('woocommerce_process_product_meta', 'ts_save_delivery_lead_time_field');
function ts_save_delivery_lead_time_field($post_id) {
    $delivery_lead_time = isset($_POST['delivery_lead_time']) ? sanitize_text_field($_POST['delivery_lead_time']) : '';
    update_post_meta($post_id, 'delivery_lead_time', $delivery_lead_time);
}

// Display the estimated delivery date on the product page
add_action('woocommerce_after_add_to_cart_form', 'ts_show_estimated_delivery_date');
function ts_show_estimated_delivery_date() {
    global $product;

    // Get the delivery lead time for the current product
    $lead_time = get_post_meta($product->get_id(), 'delivery_lead_time', true);

    // Fallback to a default lead time if none is set
    $lead_time = $lead_time ? intval($lead_time) : 1;

   // Define public holidays
    $public_holidays = array(
        '2025-01-20', // Monday (Martin Luther King Jr. Day)
        '2025-01-22', // Wednesday (Custom Example Holiday)
    );


    // Calculate the initial delivery date
    $delivery_date = new DateTime(current_time('mysql'));
    $delivery_date->modify("+{$lead_time} days");

    // Adjust for public holidays and weekends
    while (in_array($delivery_date->format('Y-m-d'), $public_holidays) || in_array($delivery_date->format('N'), array(6, 7))) {
        $delivery_date->modify('+1 day');
    }

    // Format the delivery date
    $formatted_date = $delivery_date->format('l, jS F');

    // Display the message
    echo "<div class='woocommerce-message' style='clear:both'>Estimated delivery date: <strong>{$formatted_date}</strong></div>";
}

Output

Firstly, let’s see the settings defined for the delivery lead time field of a particular product. I have set the delivery lead time of 1 day for a specific product.

How to Set Custom Delivery Dates for Each WooCommerce Products (Including Holidays & Weekends) - Tyche Softwares

Let’s test the output with different delivery lead times so that we can check whether the delivery dates are set as per the defined time. 

 Scenario 1: Lead Time = 1 Day (No weekends or holidays)

  • Today’s Date: January 18, 2025 (Saturday)
  • Lead Time: 1 Day
  • Expected Calculation:January 18 is a Saturday (weekend), so skip to Monday, January 20. January 20 is a public holiday, so skip to Tuesday, January 21.
  • Estimated Delivery Date: Tuesday, January 21, 2025
How to Set Custom Delivery Dates for Each WooCommerce Products (Including Holidays & Weekends) - Tyche Softwares

Scenario 2: Lead Time = 2 Days

  • Starting Date: January 18, 2025 (Saturday)
  • Lead Time: 2 Days
  • Expected Calculation:
    • January 18 is a Saturday (weekend), so skip to Monday, January 20.
    • January 20 is a public holiday, so skip to Tuesday, January 21.
    • January 21 is a regular working day, so the 1st day is January 21.
    • The 2nd day falls on January 22 (next working day).
  • Estimated Delivery Date: Wednesday, January 22, 2025
How to Set Custom Delivery Dates for Each WooCommerce Products (Including Holidays & Weekends) - Tyche Softwares

This configuration skips weekends and public holidays while accurately calculating delivery dates. You can modify the lead time to verify these results further.

You can check the output the different test scenarios in the output video below.

Solution: Show a Delivery Date Range for WooCommerce Products (Skipping Weekends & Holidays)

We have seen how to display a delivery lead time for all products. Instead of showing a single estimated delivery date, what if you could show a range, like:

Estimated delivery date: Monday, 7 July to Friday, 11 July

This is especially helpful for store owners who want to give customers a flexible delivery date range, while still considering in weekends and holidays.

In the original solution above, you already added code to display a single delivery date.

To show a delivery range, simply replace the third part of your code (the ts_show_estimated_delivery_date function) with the updated snippet below:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 3. Display estimated delivery range on product page
add_action('woocommerce_after_add_to_cart_form', 'ts_show_estimated_delivery_date_range');
function ts_show_estimated_delivery_date_range() {
global $product;
// Get the delivery lead time (or use default)
$lead_time = get_post_meta($product->get_id(), 'delivery_lead_time', true);
$lead_time = $lead_time ? intval($lead_time) : 1;
// Define public holidays
$public_holidays = array(
'2025-01-20',
'2025-01-22',
'2025-07-10' // Example: Add your holidays here
);
// Helper to skip weekends and holidays
function get_next_working_day($date, $skip = 1, $holidays = array()) {
$count = 0;
while ($count < $skip) {
$date->modify('+1 day');
$day_of_week = $date->format('N'); // 6 = Saturday, 7 = Sunday
if (!in_array($date->format('Y-m-d'), $holidays) && $day_of_week < 6) {
$count++;
}
}
return $date;
}
// 1. Calculate start date
$start_date = new DateTime(current_time('mysql'));
$start_date = get_next_working_day($start_date, $lead_time, $public_holidays);
// 2. Clone start date to calculate end date (+2 working days)
$end_date = clone $start_date;
$end_date = get_next_working_day($end_date, 3, $public_holidays);
// 3. Format both dates
$start_formatted = $start_date->format('l, j F');
$end_formatted = $end_date->format('l, j F');
// 4. Output the range
echo "<div class='woocommerce-message' style='clear:both'>
Estimated delivery date: <strong>{$start_formatted} to {$end_formatted}</strong>
</div>";
}
// 3. Display estimated delivery range on product page add_action('woocommerce_after_add_to_cart_form', 'ts_show_estimated_delivery_date_range'); function ts_show_estimated_delivery_date_range() { global $product; // Get the delivery lead time (or use default) $lead_time = get_post_meta($product->get_id(), 'delivery_lead_time', true); $lead_time = $lead_time ? intval($lead_time) : 1; // Define public holidays $public_holidays = array( '2025-01-20', '2025-01-22', '2025-07-10' // Example: Add your holidays here ); // Helper to skip weekends and holidays function get_next_working_day($date, $skip = 1, $holidays = array()) { $count = 0; while ($count < $skip) { $date->modify('+1 day'); $day_of_week = $date->format('N'); // 6 = Saturday, 7 = Sunday if (!in_array($date->format('Y-m-d'), $holidays) && $day_of_week < 6) { $count++; } } return $date; } // 1. Calculate start date $start_date = new DateTime(current_time('mysql')); $start_date = get_next_working_day($start_date, $lead_time, $public_holidays); // 2. Clone start date to calculate end date (+2 working days) $end_date = clone $start_date; $end_date = get_next_working_day($end_date, 3, $public_holidays); // 3. Format both dates $start_formatted = $start_date->format('l, j F'); $end_formatted = $end_date->format('l, j F'); // 4. Output the range echo "<div class='woocommerce-message' style='clear:both'> Estimated delivery date: <strong>{$start_formatted} to {$end_formatted}</strong> </div>"; }
// 3. Display estimated delivery range on product page
add_action('woocommerce_after_add_to_cart_form', 'ts_show_estimated_delivery_date_range');
function ts_show_estimated_delivery_date_range() {
    global $product;

    // Get the delivery lead time (or use default)
    $lead_time = get_post_meta($product->get_id(), 'delivery_lead_time', true);
    $lead_time = $lead_time ? intval($lead_time) : 1;

    // Define public holidays
    $public_holidays = array(
        '2025-01-20',
        '2025-01-22',
        '2025-07-10' // Example: Add your holidays here
    );

    // Helper to skip weekends and holidays
    function get_next_working_day($date, $skip = 1, $holidays = array()) {
        $count = 0;
        while ($count < $skip) {
            $date->modify('+1 day');
            $day_of_week = $date->format('N'); // 6 = Saturday, 7 = Sunday
            if (!in_array($date->format('Y-m-d'), $holidays) && $day_of_week < 6) {
                $count++;
            }
        }
        return $date;
    }

    // 1. Calculate start date
    $start_date = new DateTime(current_time('mysql'));
    $start_date = get_next_working_day($start_date, $lead_time, $public_holidays);

    // 2. Clone start date to calculate end date (+2 working days)
    $end_date = clone $start_date;
    $end_date = get_next_working_day($end_date, 3, $public_holidays);

    // 3. Format both dates
    $start_formatted = $start_date->format('l, j F');
    $end_formatted = $end_date->format('l, j F');

    // 4. Output the range
    echo "<div class='woocommerce-message' style='clear:both'>
            Estimated delivery date: <strong>{$start_formatted} to {$end_formatted}</strong>
          </div>";
}

Output

Scenario 1: Without Public Holiday

Suppose a customer visits your product page on Tuesday, 8 July 2025, and the lead time is set to 1 day. Since there are no public holidays in between:

  • The start date adds 1 working day from today’s date, showing Wednesday, 9 July 2025 as the start date.
  • It then calculates the end date with 2 additional working days
    • 10 July (Thursday): Working day
    • 11 July (Friday): Working day

So, when the customer views the product page, they’ll see:

Estimated delivery date: Wednesday, 9 July to Friday, 11 July

Scenario 2: With Public Holiday (10 July)

Let’s use the same lead time and start date again. But this time, assume 10 July is a public holiday:

  • The lead time still gives us Wednesday, 9 July 2025 as the start date.
  • Next, we skip over 10 July (public holiday), 12–13 July (weekend), and land on:
    • 11 July (Friday): 1st working day
    • 14 July (Monday): 2nd working day

So, when the customer views the product page, they’ll see:

Estimated delivery date: Wednesday, 9 July to Monday, 14 July

How to Show a Delivery Date Range for WooCommerce Products (Skipping Holidays & Weekends)

We have also covered different customizations that involve setting up delivery dates and timeframes that fit for unique business scenarios. Do you want customers to select their order delivery date from the checkout page with a delivery schedule that fits your requirement. Then the Order Delivery Date Pro For WooCommerce plugin empowers you to create custom delivery schedules tailored to your unique needs. Whether you need to adjust delivery dates by product, product category, shipping method, or even user role, this plugin has got you covered. 


Using code snippets you can implement such customizations easily but, a plugin like Product Delivery Date for WooCommerce can help integrate these features effortlessly, including setting delivery dates, time slots, preparation times, order limits, adding extra fees and many more.

Browse more in: Code Snippets, WooCommerce How Tos, WooCommerce Tutorials

Share It:

Subscribe
Notify of


2 Comments
Newest
Oldest
Inline Feedbacks
View all comments
leo
24 days ago

Great Article!
I want ‘echo’ a date range, like “Estimated delivery date: Monday, 22 July to Friday 25 July”.
I’m PHP newbie, please how do i add 3days to $formatted_date and echo a date range like above.

2
0
Would love your thoughts, please comment.x
()
x
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible.

Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.

By using our site, you acknowledge that you have read and understood our Privacy Policy and Terms & Conditions.