Добавить местные праздники в расчет даты / времени в PHP - PullRequest
1 голос
/ 13 июля 2020

Я хочу показать примерное время доставки в свой магазин. Если клиент делает заказ до 16:00, он получает свой заказ на следующий день. Но если заказ в пятницу или в выходные, он получит заказ в следующий понедельник.

Все работает нормально. Но мне нужно добавить несколько праздников, таких как Рождество, Новый год и местные праздники, в зависимости от штата в моей стране.

Я нашел решение для определения фиксированных и гибких (например, пасхальных) праздников в моем штате.

Но я не знаю, как с ними работать в текущей функции. Если заказ размещен до одного из этих праздников, мне нужно переместить будущую дату на несколько дней вперед.

Вот текущий код (на основе этого кода ):

date_default_timezone_set( 'Europe/Berlin' );

$current_year   = date('Y');
$next_year      = date('Y', strtotime( $current_year." + 1 year" ));

// Holidays
$neujahr        = date('d.m.Y',strtotime(date($next_year.'-01-01')));
$ostern         = date('d.m.Y', easter_date($current_year));
$karfreitag     = date( "l jS F", strtotime( $ostern." - 2 days" ) );
$ostermontag    = date( "l jS F", strtotime( $ostern." + 1 days" ) );
$tagderarbeit   = date('d.m.Y',strtotime(date('Y-05-01')));
$himmelfahrt    = date( "l jS F", strtotime( $ostern." + 39 days" ) );
$pfingstmontag  = date( "l jS F", strtotime( $ostern." + 50 days" ) );
$fronleichnam   = date( "l jS F", strtotime( $ostern." + 60 days" ) );
$einheit        = date('d.m.Y',strtotime(date('Y-10-03')));
$allerheiligen  = date('d.m.Y',strtotime(date('Y-11-01')));
$weihnachten1   = date('d.m.Y',strtotime(date('Y-12-25')));
$weihnachten2   = date('d.m.Y',strtotime(date('Y-12-26')));

// if FRI/SAT/SUN delivery will be MON
if ( date( 'N' ) >= 5 ) {
  $del_day = date( "l jS F", strtotime( "next monday" ) );
  $order_by = "Monday";
}

// if MON/THU after 4PM delivery will be TOMORROW
elseif ( date( 'H' ) >= 16 ) {
  $del_day = date( "l jS F", strtotime( "tomorrow" ) );
  $order_by = "tomorrow";
}

// if MON/THU before 4PM delivery will be TODAY
else {
  $del_day = date( "l jS F", strtotime( "today" ) );
  $order_by = "today";
}

$html = "<br><div class='woocommerce-message' style='clear:both'>Order by 4PM {$order_by} for delivery on {$del_day}</div>";

echo $html;

1 Ответ

1 голос
/ 14 июля 2020

Рабочий метод, который вы в настоящее время применяете, может работать с несколькими различными операторами if / else для проверки всех условий, поэтому я предпочитаю другой подход.

Это выглядит следующим образом

  1. На сегодняшний день генерируется 8 возможных дат доставки (например: сегодня = 14/07/2020, возможные даты: 14, 15, 16, 17, 18, 19, 20 & 21/07/2020
  2. Если сегодня уже после 4 pm, дата сегодняшнего дня истекает (14/07/2020)
  3. Меньше, чем 4 pm, но пятница, суббота или воскресенье, удалите дату
  4. Затем удалите (другие) даты из выходных: пятница, суббота и воскресенье (17, 18, 19/07/2020)
  5. Затем из результата отфильтровываются все праздники (если есть).
  6. На последнем шаге используется первое значение результата, которое отображается в выходном сообщении.
  • Примечание: это легко проверить, изменив значения $today = date( 'd.m.Y' ); на любую дату в будущем, например $today = date( '25.12.2024' );, которая вернет
    • Доставка в понедельник 30 декабря
    • 25, 26 = праздники. 27, 28 & 29/12/2024 = пятница, суббота и воскресенье
date_default_timezone_set( 'Europe/Berlin' );

// Today
$today = date( 'd.m.Y' );

// Possible delivery dates from today
for ( $i = 0; $i <= 7; $i++) {
    $possible_delivery_dates[] = date( 'd.m.Y', strtotime( $today . '+' . $i . 'days' ) ); 
}

// Today ?
if ( date( 'H', strtotime( $today ) ) >= 16 ) {
    // Today NOT possible
    unset( $possible_delivery_dates[0] );
} elseif ( date( 'N', strtotime( $today ) ) >= 5 ) {
    // Today (weekend) NOT possible
    unset( $possible_delivery_dates[0] );
}

// Next Fri, Sat & Sun
$next_friday   = date( 'd.m.Y', strtotime( $today . 'next friday' ) );
$next_saturday = date( 'd.m.Y', strtotime( $today . 'next saturday' ) );
$next_sunday   = date( 'd.m.Y', strtotime( $today . 'next sunday' ) );

// Remove next fri, sat & sun
$possible_delivery_dates = array_diff( $possible_delivery_dates, [ $next_friday, $next_saturday, $next_sunday ] );

// Current & next year
$current_year  = date( 'Y', strtotime( $today ) );
$next_year     = date( 'Y', strtotime( $today . '+ 1 year' ));

// Holidays
$neujahr       = date( 'd.m.Y', strtotime( date( $next_year . '-01-01' ) ) );
$ostern        = date( 'd.m.Y', easter_date( $current_year ) );
$karfreitag    = date( 'd.m.Y', strtotime( $ostern . '- 2 days' ) );
$ostermontag   = date( 'd.m.Y', strtotime( $ostern . '+ 1 days' ) );
$tagderarbeit  = date( 'd.m.Y', strtotime( date( $current_year . '-05-01') ) );
$himmelfahrt   = date( 'd.m.Y', strtotime( $ostern . '+ 39 days' ) );
$pfingstmontag = date( 'd.m.Y', strtotime( $ostern . '+ 50 days' ) );
$fronleichnam  = date( 'd.m.Y', strtotime( $ostern . '+ 60 days' ) );
$einheit       = date( 'd.m.Y', strtotime( date( $current_year . '-10-03' ) ) );
$allerheiligen = date( 'd.m.Y', strtotime( date( $current_year . '-11-01' ) ) );
$weihnachten1  = date( 'd.m.Y', strtotime( date( $current_year . '-12-25' ) ) );
$weihnachten2  = date( 'd.m.Y', strtotime( date( $current_year . '-12-26' ) ) );

// Holidays (array)
$holidays = array( $neujahr, $ostern, $karfreitag, $ostermontag, $tagderarbeit, $himmelfahrt, $pfingstmontag, $fronleichnam, $einheit, $allerheiligen, $weihnachten1, $weihnachten2 );

// Remove holidays
$possible_delivery_dates = array_diff( $possible_delivery_dates, $holidays );

// First value
$first_val = reset( $possible_delivery_dates );

$html = 'Delivery on ' . date( 'l jS F', strtotime( $first_val ) );

echo $html;
...