php - 计算PHP中的工作时间时差
问题描述
我想计算编码日期和完成日期之间的小时数。到目前为止,我可以计算两个日期时间之间的时差,不包括周六和周日。我的问题是我需要排除午休时间(上午 12:00 到下午 1:00)和节假日。
这是我的代码:
<?php
function business_hours($start, $end){
$startDate = new DateTime($start);
$endDate = new DateTime($end);
$periodInterval = new DateInterval( "PT1H" );
$period = new DatePeriod( $startDate, $periodInterval, $endDate );
$count = 0;
$holidays = [
"Human Rights Day" => new DateTime(date('Y') . '-03-21'),
"Good Friday" => new DateTime(date('Y') . '-03-30'),
"Family Day" => new DateTime(date('Y') . '-04-02'),
"Freedom Day" => new DateTime(date('Y') . '-04-27'),
"Labour Day" => new DateTime(date('Y') . '-05-01'),
"Youth Day" => new DateTime(date('Y') . '-06-16'),
"National Women's Day" => new DateTime(date('Y') . '-08-09'),
"Heritage Day" => new DateTime(date('Y') . '-09-24'),
"Day of Reconciliation" => new DateTime(date('Y') . '-12-16'),
];
foreach($period as $date){
$startofday = clone $date;
$startofday->setTime(8,00);
$endofday = clone $date;
$endofday->setTime(17,00);
if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday'))){
$count++;
}
}
echo $count;
}
$start = '2020-02-14 08:00:00';
$end = '2020-02-17 08:00:00';
$go = business_hours($start,$end);
//output 9 hours
?>
根据我的代码,我将工作时间设置为 8:00 到 17:00,然后排除周六和周日。根据我的示例,输出将为 9(包括午休时间)。如何排除午休和节假日?
更新
完成时间可以超过1天。例如,开始日期/时间为 2020-02-14 08:00:00,完成时间为 2020-02-19 08:00:00,输出为 27 小时。该计算应排除每天中午 12:00 至下午 1:00 和节假日之间的午休时间。
更新
我添加了一系列假期,如何排除这些假期?
解决方案
由于您使用的是静态/定义的午休时间,因此您可以使用以下逻辑:
- 如果 $startDate 是工作日,并且在 12:00 之前,这是午餐计算的开始日期;否则就是下一个工作日。
- 如果 $endDate 是工作日,并且在 13:00 之后,则为午餐计算的结束日期;否则为前一个工作日
- 午休的实际数量等于重新计算的日期之间的差异,每次一小时。以下是伪代码:
if(!in_array($startDate->format('l'), array('Sunday','Saturday')) && ($startDate->format('g') < 12) {
$startForLunch = $startDate;
}
else {
$startForLunch = new DateTime($start, '+1 day');
while(in_array($startDate->format('l'), array('Sunday','Saturday'))){
$startForLunch->add('1 day');
}
}
if(!in_array($endDate->format('l'), array('Sunday','Saturday')) && ($endDate->format('g') > 13) {
$endForLunch = $end;
}
else {
$endForLunch = new DateTime($endDate, '-1 day');
while(in_array($endDate->format('l'), array('Sunday','Saturday'))){
$endForLunch->add('-1 day');
}
}
$lunchPeriods = $endForLunch - $startForLunch + 1;
推荐阅读
- lua - 如何使用快捷方式重新加载用 lua 编写的 Neovim 配置?
- python - 如何使用 lxml 更改不同的层次结构标签?
- python - 即使将中位数用作枢轴,快速排序也比合并排序慢 20 倍?
- sql - 检查表内的条件是否可能自联接?
- algorithm - 计算模 2^32 - 1 不除法运算
- java - 服务器端超时
- docker - Docker Hub 映像存储库是否包含来自 .env 文件的环境变量?
- blazor - 如何将自定义授权属性添加到 AuthorizeView?
- reactjs - 如何仅在第二次渲染时更新列表?
- windows - 在 Build 中 Flutter Windows App 参考文件,从项目目录中加载文件