PHP计算夜班与工作时间段重叠时长的代码实现求助
计算夜班(22:00:00-06:00:00)与工作时段的重叠时长(PHP实现)
问题说明
需要编写PHP代码,计算员工工作时间段与固定夜班时段(当日22:00:00至次日06:00:00)的重叠时长,结果保留两位小数。
示例场景
- 工作时段:04:30:00-12:00:00 → 重叠时长:1.50
- 工作时段:21:00:00-08:00:00 → 重叠时长:8.00
- 工作时段:21:00:00-03:30:00 → 重叠时长:5.50
原代码问题分析
你提供的代码存在两个核心问题:
- 跨天时间处理错误:
strtotime('06:00:00')默认解析为当日的6点,但夜班的06:00是次日的6点,直接对比会导致逻辑判断错误。 - 覆盖场景不全:仅处理了部分重叠情况,未覆盖工作时段完全包含夜班、夜班完全包含工作时段等多种重叠场景。
正确实现代码
使用PHP的DateTime类处理时间,能更精准地处理跨天时间逻辑:
<?php function calculateNightShiftOverlap($checkInTime, $checkOutTime) { // 定义夜班时段:当日22:00 到 次日06:00 $today = new DateTime(); $nightShiftStart = (clone $today)->setTime(22, 0, 0); $nightShiftEnd = (clone $today)->modify('+1 day')->setTime(6, 0, 0); // 解析员工的上下班时间 $checkIn = new DateTime($checkInTime); $checkOut = new DateTime($checkOutTime); // 处理工作时段跨天的情况(比如21:00-08:00) if ($checkOut < $checkIn) { $checkOut->modify('+1 day'); } // 计算重叠区间的开始和结束时间 $overlapStart = max($checkIn, $nightShiftStart); $overlapEnd = min($checkOut, $nightShiftEnd); // 计算重叠时长(秒转小时,保留两位小数) $overlapHours = 0; if ($overlapStart < $overlapEnd) { $interval = $overlapStart->diff($overlapEnd); $overlapHours = $interval->h + ($interval->i / 60) + ($interval->s / 3600); } return number_format($overlapHours, 2); } // 测试示例 echo calculateNightShiftOverlap('04:30:00', '12:00:00') . "\n"; // 输出1.50 echo calculateNightShiftOverlap('21:00:00', '08:00:00') . "\n"; // 输出8.00 echo calculateNightShiftOverlap('21:00:00', '03:30:00') . "\n"; // 输出5.50 ?>
代码说明
- 夜班时段定义:明确将夜班结束时间设为次日6点,避免跨天解析错误。
- 跨天工作时段处理:如果下班时间早于上班时间,自动将下班时间加1天,统一时间轴。
- 重叠区间计算:通过
max()取两个时段的较晚开始时间,min()取较早结束时间,得到重叠区间。 - 时长计算:利用
DateInterval计算时间差,转换为小时并保留两位小数。
内容的提问来源于stack exchange,提问作者Sergej Rommel
相关产品推荐
相关产品推荐

