
本文介绍如何用php精确计算两个时间区间(仅含时分)的重叠时长,核心是通过取两区间端点的最大值与最小值,判断是否存在交集并计算重叠部分的持续时间。
本文介绍如何用php精确计算两个时间区间(仅含时分)的重叠时长,核心是通过取两区间端点的最大值与最小值,判断是否存在交集并计算重叠部分的持续时间。
在处理排班、夜间计费、服务时段校验等业务场景时,常需判断某段时间(如 01:00–09:30)与另一固定时段(如夜间 00:00–04:00)有多少分钟/小时存在重叠。关键在于:不依赖日期,仅基于24小时制时间字符串进行逻辑运算。
核心算法原理
设主区间为 [start, end],参考区间为 [night_start, night_end],二者均为有效时间(HH:MM 格式,且 start ≤ end,night_start ≤ night_end)。重叠时长计算公式为:
overlap = max(0, min(end, night_end) - max(start, night_start))
-
max(start, night_start)是重叠区间的起始时间(较晚的开始时间); -
min(end, night_end)是重叠区间的结束时间(较早的结束时间); - 若结果为负或零,则无重叠;否则即为重叠的持续时间(单位:分钟或秒,取决于时间表示方式)。
PHP 实现示例(推荐使用 DateTime + 时间戳)
function timeOverlapInMinutes(string $start, string $end, string $nightStart, string $nightEnd): int
{
// 将 HH:MM 转为当日 Unix 时间戳(便于计算)
$date = date('Y-m-d'); // 任意基准日期,因只比对时间,不影响结果
$t1 = strtotime("$date $start");
$t2 = strtotime("$date $end");
$n1 = strtotime("$date $nightStart");
$n2 = strtotime("$date $nightEnd");
// 计算重叠的秒数,再转为分钟(向下取整)
$overlapSeconds = max(0, min($t2, $n2) - max($t1, $n1));
return (int) floor($overlapSeconds / 60);
}
// 示例调用
echo timeOverlapInMinutes('01:00', '09:30', '00:00', '04:00'); // 输出:180(即 3 小时)
echo "\n";
echo timeOverlapInMinutes('03:15', '05:45', '02:00', '04:30'); // 输出:75(1 小时 15 分钟)注意事项与边界处理
- ✅ 时间合法性校验:实际项目中应先验证输入是否为合法
HH:MM格式(可用正则/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/),并确保start ≤ end; - ⚠️ 跨日场景:本方案默认所有时间为同一天的24小时制。若需支持跨日(如
23:00–02:00),需额外处理时间循环逻辑(例如将end 视为次日),此时建议改用 <code>DateTimeImmutable并显式指定日期偏移; - ? 精度选择:上述示例返回分钟数;如需秒级精度,直接返回
$overlapSeconds即可; - ? 可复用封装:可进一步封装为
TimeRange类,支持intersect()、durationInMinutes()等方法,提升可读性与扩展性。
该方法简洁、高效、无第三方依赖,适用于绝大多数仅涉及时段重叠判断的PHP业务逻辑。



















