php - 计算天数,不包括周末
问题描述
我有一个网站可以计算订单的交货日期。所以我们有从 1 到 30 的日子所以主要条件是,
- 如果有人在周六或周日下订单,则应从周一开始(工作日为周一至周五)
- 如果有人在 18:00 之前下订单,则天数应从今天开始,否则应从第二天开始。例如:如果订单是在 2020-07-07 18:00 之前下订单,则 7 日为开始日,否则为8号
- 如果交货日期在星期天,那么它应该移到星期一
下面是我的代码,问题是它只在某些日子有效。大多数情况下,它会增加额外的一天。
$thedays = array('1','2','3','4','5');
foreach ($thedays as $days) {
if (date('H') > 17) {
$cutoff = 1;
} else {
$cutoff = 0;
}
$extra_days = 0;
//is today a weekend
if(date('l', strtotime(date('Y-m-d'))) == 'Sunday') {
$extra_days = 1;
}
if(date('l', strtotime(date('Y-m-d'))) == 'Saturday') {
$extra_days = 2;
}
$total1= $cutoff+$extra_days+$days;
$date_1 = date('Y-m-d', strtotime("+".$total1." day"));
$date = date('Y-m-d');
$date2 = $date_1;
$period = new DatePeriod(
new DateTime($date),
new DateInterval('P1D'),
new DateTime($date2)
);
$q = 0;
$d= 0;
foreach ($period as $key => $value) {
$d++;
if ($value->format('N') > 5) {
$q++;
}
}
$total_days_with_weekends = ($days+$q+$extra_days);
$date_1 = date('Y-m-d', strtotime("+".$total_days_with_weekends." day"));
if(date('l', strtotime($date_1)) == 'Saturday') {
$date_1 = date('Y-m-d', strtotime("-1 day"));
}
if(date('l', strtotime($date_1)) == 'Sunday') {
$days= $days+1;
$date_1 = date('Y-m-d', strtotime("+".$days." day"));
}
echo $data_1;
}
有人可以建议最好的方法吗?
谢谢
解决方案
考虑到星期六也不是有效的交货日期,我得到了这样的东西:
function getDeliveryDate(DateTime $orderDate, int $days): DateTime {
$deliveryDate = clone $orderDate;
$remainingDays = $days;
// if it is after 18:00 we skip current day
if ($orderDate->format('H') >= 18) {
$deliveryDate->add(new DateInterval('P1D'));
}
// we process days until we reach specified amount
while ($remainingDays > 0) {
$deliveryDate->add(new DateInterval('P1D'));
// we skip saturday and sunday
if (!in_array($deliveryDate->format('D'), ['Sat', 'Sun'])) {
$remainingDays--;
}
}
return $deliveryDate;
}
可以用工作日简化:
function getDeliveryDate(DateTime $orderDate, int $days): DateTime {
$deliveryDate = clone $orderDate;
if ($orderDate->format('H') >= 18) {
$days++;
}
return $deliveryDate->modify('+'.$days.' weekday');
}
测试:
function check(string $orderDate, int $days, string $expectedDeliveryDate) {
$deliveryDate = getDeliveryDate(new DateTime($orderDate), $days);
if ($deliveryDate->format('Y-m-d') !== $expectedDeliveryDate) {
echo 'Order date: '.$orderDate.', days: '.$days.', expected: '.$expectedDeliveryDate.' got: '.$deliveryDate->format('Y-m-d').PHP_EOL;
} else {
echo 'Order date: '.$orderDate.', days: '.$days.', expected: '.$expectedDeliveryDate.' - OK'.PHP_EOL;
}
}
check('2020-07-08 12:00', 1, '2020-07-09');
check('2020-07-08 12:00', 2, '2020-07-10');
check('2020-07-08 18:00', 1, '2020-07-10');
check('2020-07-08 12:00', 6, '2020-07-16');
check('2020-07-08 12:00', 5, '2020-07-15');
测试输出:
Order date: 2020-07-08 12:00, days: 1, expected: 2020-07-09 - OK
Order date: 2020-07-08 12:00, days: 2, expected: 2020-07-10 - OK
Order date: 2020-07-08 18:00, days: 1, expected: 2020-07-10 - OK
Order date: 2020-07-08 12:00, days: 6, expected: 2020-07-16 - OK
Order date: 2020-07-08 12:00, days: 5, expected: 2020-07-15 - OK
推荐阅读
- compiler-construction - 如何在堆栈上传递其他参数?
- video-streaming - 如何使用 Shaka Player 播放具有多种分辨率的视频?
- node.js - 如何从猫鼬查询结果中省略字段?
- css - Bootstrap Lumen 主题的 NavBar 问题
- c++ - 如何检测字符串中的不同字母和数字
- java - Liberty 空指针异常
- html - 通过 css 将 .svg 内部定义的样式应用到 .svg 元素基于它们的 `id` 属性
- python-3.x - 将 antlr4 Interval 类导入 Python
- c# - 我需要做什么才能让这个按钮运行后面代码中的代码?
- javascript - 选择不更新数据