<?php class WorkTime { // 定義工作日 [1, 2, 3, 4, 5, 6, 0] public $week_workingday = [1, 2, 3, 4, 5]; // 定義上下班時間 public $on_duty_time = '9:00:00'; public $off_duty_time = '18:00:00'; //每天工作時長 public $oneday_hours = null; public function __construct() { if (empty($this->oneday_hours)) { $this->oneday_hours = $this->off_duty_time - $this->on_duty_time; } } public function get_working_hours(int $start_time, int $over_time) { // 如果工作日列表為空 返回0 $workingdays = $this->workingdays($start_time, $over_time); if (empty($workingdays)) { return 0; } // 如果開始時間不是工作日,將開始時間調整為第一個工作日的上班時間 // 如果截止時間不是工作日,將開始時間調整為最后一個工作日的下班時間 if (!in_array(date('Y/m/d', $start_time), $workingdays)) { $start_time = strtotime($workingdays[0] . ' ' . $this->on_duty_time); } if (!in_array(date('Y/m/d', $over_time), $workingdays)) { $over_time = strtotime(end($workingdays) . ' ' . $this->off_duty_time); } // 如果開始時間與截止時間是同一天,直接計算 // 反之分別計算開始時間與截止時間 if (date('Y/m/d', $start_time) == date('Y/m/d', $over_time)) { $sec = $over_time - $start_time; if ($sec > 3600 * $this->oneday_hours) { $sec = 3600 * $this->oneday_hours; } // 昨天到了計算秒數 } else { // 計算開始日工作時間 $start_day_sec = strtotime($workingdays[0] . ' ' . $this->off_duty_time) - $start_time; if ($start_day_sec > 3600 * $this->oneday_hours) { $start_day_sec = 3600 * $this->oneday_hours; } // 計算截止日工作時間 $over_day_sec = $over_time - strtotime(end($workingdays) . ' ' . $this->on_duty_time); if ($over_day_sec > 3600 * $this->oneday_hours) { $over_day_sec = 3600 * $this->oneday_hours; } $all_day_sec = ((count($workingdays) - 2) * $this->oneday_hours) * 3600; $sec = $start_day_sec + $over_day_sec + $all_day_sec; } return $sec / 3600; } # 計算工作日(包含開始與截止日期) protected function workingdays($start_time, $over_time) { $start_time = strtotime('-1 day', $start_time); $over_time = strtotime('-1 day', $over_time); $new_workingdays = $this->new_workingdays(); $new_holidays = $this->new_holidays(); $workingdays = []; while ($start_time < $over_time) { $start_time = strtotime('+1 day', $start_time); $is_holidays = in_array(date('w', $start_time), $this->week_workingday) && !in_array(date('Y/m/d', $start_time), $new_holidays); $is_workingdays = in_array(date('Y/m/d', $start_time), $new_workingdays); if ($is_holidays || $is_workingdays) { $workingdays[] = date('Y/m/d', $start_time); } } return $workingdays; } # 新增工作日 protected function new_workingdays() { $days = [ '2020/05/09', ]; return $days; } # 新增休息日 protected function new_holidays() { $days = [ '2020/05/01', '2020/05/04', '2020/05/05', ]; return $days; } }
$start_time = strtotime('2020-05-06 10:00:00'); $over_time = strtotime('2020-05-11 18:00:00'); $work = new WorkTime(); $working_hours = $work->get_working_hours($start_time, $over_time); var_dump($working_hours);