如何在PHP中正确展示两地交替的周四配送日期
交替配送日期计算问题
我正在编写PHP代码输出某店铺的配送日期。该店铺每周四配送货物,但会在Foo和Bar两个地点间交替配送:本周四配送至Foo,下周四至Bar,再下周四回到Foo,以此类推。
理想输出效果为:
The next delivery to Foo is: [date]
The next delivery to Bar is: [date]
我刚学习时间/DateTime相关内容,对此有些困惑,基于示例写出如下代码:
<?php $nextThursday= strtotime("next Thursday"); $secondThursday=strtotime("next Thursday",$nextThursday); echo "The next delivery to Foo is: <strong>" . date("l-jS-F",$nextThursday) . "</strong>, Please order before 7am on " . date("l-jS-F",$nextThursday) . " to ensure delivery.<br>"; echo "The next delivery to Foo is: <strong>" . date("l-jS-F",$secondThursday) . "</strong>, Please order before 7am on " . date("l-jS-F",$secondThursday) . " to ensure delivery.<br>"; ?>
但当前日期到达设定的nextThursday时,配送日期会出现顺序错误,不知是否有简单解决方法,是否需要按周数处理?
解决方法
问题出在strtotime("next Thursday")的行为逻辑上:它会返回当前时间之后的下一个周四。如果当天是周四但还没到7点截止时间,它依然会跳转到下一周的周四,导致跳过本周四的配送,这就是顺序错误的根源。
推荐用PHP的DateTime类处理,逻辑更清晰,也能精准控制时间判断:
修正后的代码
<?php // 设置时区,根据实际业务场景调整 date_default_timezone_set('Asia/Shanghai'); // 获取当前时间 $now = new DateTime(); // 设置配送截止时间为周四7点 $cutoff = (new DateTime())->setTime(7, 0, 0); // 确定最近的有效配送日 $nextDelivery = new DateTime('this Thursday'); // 如果今天是周四且已过7点,下一次配送日为下周四 if ($now > $cutoff && $now->format('l') === 'Thursday') { $nextDelivery->modify('+1 week'); } // 通过ISO周数的奇偶性判断当前配送日归属(可根据实际起始配送周调整规则) // 例:奇数周周四送Foo,偶数周送Bar $weekNumber = (int)$nextDelivery->format('W'); $isFooDelivery = $weekNumber % 2 === 1; // 计算两个地点的下一次配送日期 if ($isFooDelivery) { $fooDate = clone $nextDelivery; $barDate = (clone $nextDelivery)->modify('+1 week'); } else { $barDate = clone $nextDelivery; $fooDate = (clone $nextDelivery)->modify('+1 week'); } // 输出结果 echo "The next delivery to Foo is: <strong>" . $fooDate->format('l-jS-F') . "</strong>, Please order before 7am on " . $fooDate->format('l-jS-F') . " to ensure delivery.<br>"; echo "The next delivery to Bar is: <strong>" . $barDate->format('l-jS-F') . "</strong>, Please order before 7am on " . $barDate->format('l-jS-F') . " to ensure delivery.<br>"; ?>
代码说明
- 时区设置:先指定正确的时区,避免时间计算偏差。
- 截止时间判断:检查当前是否为周四且已过7点,确保不会错过当天的配送窗口。
- 配送归属判断:用ISO周数的奇偶性区分Foo和Bar的配送日,规则可根据实际起始配送周调整(比如起始周是偶数周送Foo,就把判断条件改成
$weekNumber % 2 === 0)。 - 日期克隆:使用
clone复制DateTime对象,避免修改原对象导致的计算错误。
更精准的起始规则(可选)
如果想严格遵循“某一个起始周四为Foo配送日”的规则,可固定起始日期计算周数差:
// 固定第一个Foo配送日(示例:2024年1月4日,周四) $startFooDate = new DateTime('2024-01-04'); // 计算当前配送日与起始日的周数差 $interval = $startFooDate->diff($nextDelivery); $weeksDiff = floor($interval->days / 7); // 偶数周差为Foo,奇数周差为Bar $isFooDelivery = $weeksDiff % 2 === 0;
这样无论年份变化,交替配送的规则都会保持准确。
内容的提问来源于stack exchange,提问作者Joel Crump
相关产品推荐
相关产品推荐

