php 计算时间段内的工作日 与节假日
程序员文章站
2022-05-20 09:40:00
...
计算方法是取开始时间后的第一个星期一,如果结束时间大于等这一天则用第一个星期一至结束时间的时间的间隔取整周数与余数计算工作日与周末,再加上第一个周一前一周的工作日与节假日.
/** 计算时间段内的工作日 与节假日
* @param $begin_date \DateTime
* @param $end_date \DateTime
* @return array
* @throws \Exception
*/
static function computeDays($begin_date,$end_date)
{
if ($end_date >= $begin_date) {
$begin_week_day = $begin_date->format("N");
if ($begin_week_day == 1) {
$cut_week_days = 0;
} else {
$cut_week_days = 7 - $begin_week_day + 1;
}
$dateInterval = new \DateInterval("P" . $cut_week_days . "D");
$first_monday = $begin_date->add($dateInterval);
//总工作日
$total_work_days = 0;
//总节假日
$total_holidays = 0;
//总天数,包括起始日期
$total_days = 0;
if ($end_date >= $first_monday) {
$diff = $first_monday->diff($end_date);
$diff_days = $diff->days + 1; // 包括开始日期 +1
$weeks_yu = $diff_days % 7;
$weeks = floor($diff_days / 7);
$total_days = $diff_days;
if ($weeks > 0) {
$total_work_days = $weeks * 5;
$total_holidays = $weeks * 2;
}
if ($weeks_yu == 6) {
$total_holidays += 1;
$total_work_days += 5;
} else {
$total_work_days += $weeks_yu;
}
if ($cut_week_days > 0) {
if ($cut_week_days >= 2) {
$total_work_days += $cut_week_days - 2;
$total_holidays += $cut_week_days + 2;
} else {
$total_holidays += 1;
}
}
} else {
$diff = $first_monday->diff($end_date);
$diff_days = $diff->days + 1; // 包括开始日期 +1
$end_week_day = $end_date->format("N");
if ($begin_week_day <= 5 && $end_week_day <= 5) {
$total_work_days += $end_week_day - $begin_week_day + 1;
} elseif ($begin_week_day > 5 && $end_week_day > 5) {
$total_holidays += $end_week_day - $begin_week_day + 1;
} elseif ($begin_week_day <= 5 && $end_week_day > 5) {
$total_work_days += 5 - $begin_week_day + 1;
$total_holidays += $end_week_day - 5;
}
$total_days = $end_week_day - $begin_week_day + 1;
}
//判断国家规定节假日
/*$project_holidays = ProjectHolidaysModel::where("1=1")
->whereBetweenTime("thedate",$begin_date->format("Y-m-d"),$end_date->format("Y-m-d"))
->all();*/
//以2020 五一为例 ,在数据库中加入上班与节假日调整
//is_holidays 1假期 0上班
$project_holidays = [
["thedate"=>'2020-5-1',"is_holidays"=>1],
["thedate"=>'2020-5-4',"is_holidays"=>1],
["thedate"=>'2020-5-5',"is_holidays"=>1],
["thedate"=>'2020-5-9',"is_holidays"=>0],
];
foreach ($project_holidays as $one){
$the_date = new \DateTime($one["thedate"]);
$the_week_day = $the_date->format("N");
if($the_week_day > 5 && $one["is_holidays"] =="0"){
$total_holidays -= 1;
$total_work_days += 1;
}
if($the_week_day <=5 && $one["is_holidays"] == "1"){
$total_holidays += 1;
$total_work_days -= 1;
}
}
return [
"total_work_days" => $total_work_days,
"total_holidays" => $total_holidays,
"total_days" => $total_days
];
}
}