计算方法是取开始时间后的第一个星期一,如果结束时间大于等这一天则用第一个星期一至结束时间的时间的间隔取整周数与余数计算工作日与周末,再加上第一个周一前一周的工作日与节假日
/** 计算时间段内的工作日 与节假日 * @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 ]; } }