PHP 显示每周两次交货的下一个交货日期

PHP Display next delivery date for twice weekly deliveries

我有一个网站,我们会在其中显示下一个交货日期,例如每周二的每周交货——尽管有时需要手动更改交货的实际日期。我需要将其更新为(例如)周二和周五交货,我正在努力寻找一个好的方法。

这是我目前的设置方式:

<?php

$start_date = '2020-05-05';  //  Date in the past to start counting from: YYYY-MM-DD
$date_interval = new DateInterval('P7D');  //  DELIVERY EVERY x DAYS: PxD  (usually P7D)

// create a DateTime object that represents start of sequence
$start_datetime = DateTime::createFromFormat('Y-m-d', $start_date);

// create a DateTime object representing the current date
$current_datetime = new DateTime('today');

//  determine end date for DatePeriod object that will later be used.
//  This is no further out than current date plus the interval.
$end_datetime = new DateTime('tomorrow');
$end_datetime->add($date_interval);

$date_period = new DatePeriod($start_datetime, $date_interval, $end_datetime);

// iterate until the last date in the set
foreach($date_period as $dp) {
    $next_delivery = $dp;
}

echo $next_delivery->format('l, M j, Y');

?>

dateperiod class says that it accepts ISO 8601 time periods,但据我所知无法将其设置为 "next Tuesday or Friday, whichever is closer"。

我想到的一个可行的 hacky 方法是 运行 此函数两次,一次用于星期二,一次用于星期五,与今天的日期进行比较,并显示将来较早的日期。但肯定有更优雅的方式吗?

寻找下一个可用的星期二或星期五的方法非常冗长。一种方法是查看今天是星期几,然后根据它动态设置日期:

$day = (in_array((int) date('w'), [0,1,5,6], true)) ? 'Tuesday' : 'Friday';
echo (new DateTime("next {$day}"))->format('l, M j, Y');

输出:

Tuesday, May 12, 2020

上面的代码检查当天是星期日、星期一、星期五还是星期六。如果是这样,请将第二天设置为 "Tuesday"。否则,将其设置为 "Friday"。然后你可以使用 relative datetime value 来设置你的日期。

如果你想要一个更易于阅读的版本,你可以拼出日期:

$day = (in_array(date('l'), ['Sunday', 'Monday', 'Friday', 'Saturday'], true)) ? 'Tuesday' : 'Friday';

不难找到下一个可用的星期二或星期五。 这是两者中较小的日期。

echo min(date_create('next Tuesday'),date_create('next Friday'))->format('l, M j, Y');

或者使用 DateTime API 的 PHP 扩展名为 dt。你可以找到它 here.

此class 支持使用 crontab 表达式进行日期计算。星期几从 0 开始表示星期日。以14:00计算下周二或下周五为例,只需这样做:

$cron = "0 14 * * 2,5"; //next Tuesday or Friday 14:00 
$next_delivery = dt::create('today')->nextCron($cron);  //today is 2020-05-10

echo $next_delivery->format('l, M j, Y, H:i'); 
//Tuesday, May 12, 2020, 14:00