
本文详解如何用 php 判断新输入的时间段是否与数据库中已存在的时段发生重叠,支持边界对齐(如 07:00 接续 07:00),并提供健壮、可复用的逻辑实现。
本文详解如何用 php 判断新输入的时间段是否与数据库中已存在的时段发生重叠,支持边界对齐(如 07:00 接续 07:00),并提供健壮、可复用的逻辑实现。
在日程管理、预约系统或资源排期类应用中,一个核心需求是:校验用户提交的新时间段是否与已有记录冲突。常见误区是仅检查“起点在区间内”或“终点在区间内”,而忽略了「新时段完全包裹旧时段」或「旧时段完全包裹新时段」等关键场景。下面给出专业、无遗漏的解决方案。
✅ 正确的区间冲突判定逻辑
两个时间区间 [A, B] 和 [C, D](均闭区间,含端点)不重叠的充要条件是:
D ≤ A 或 C ≥ B
即:新时段完全在旧时段之前,或完全在旧时段之后。
反之,存在重叠(冲突) 的条件为:
D > A && C < B
立即学习“PHP免费学习笔记(深入)”;
⚠️ 注意:此处使用 > 和 < 而非 >= / <=,是为了允许端点紧邻相接(如 07:00–15:00 与 15:00–17:00 视为合法,不冲突)。若需严格禁止端点重合(即 15:00 不能同时被两个时段占用),则改用 >= 和 <=。
? 完整可运行示例代码
<?php
// 数据库中已存在的时段(24小时制字符串)
$db_start = "07:00";
$db_end = "15:00";
// 用户新提交的时段
$start = "06:00";
$end = "07:00"; // ✅ 合法:紧邻开始,无重叠
// 统一转换为当日时间戳,便于比较
$today = date('Y-m-d');
$ts_db_start = strtotime("$today $db_start");
$ts_db_end = strtotime("$today $db_end");
$ts_start = strtotime("$today $start");
$ts_end = strtotime("$today $end");
echo "已有时段:$db_start – $db_end<br>";
echo "新时段:$start – $end<br>";
// 核心判断:是否存在时间重叠?
if ($ts_end > $ts_db_start && $ts_start < $ts_db_end) {
echo "❌ 冲突!新时段与已有时段重叠,无法添加。";
} else {
echo "✅ 通过!新时段可安全添加。";
}
?>? 测试用例验证(结果对照)
| 新时段(start–end) | 是否冲突 | 原因说明 |
|---|---|---|
| 06:00–07:00 | ❌ 否 | 紧邻旧时段起点,无重叠 |
| 15:00–17:00 | ❌ 否 | 紧邻旧时段终点,无重叠 |
| 06:00–16:00 | ✅ 是 | 包裹整个旧时段(07:00–15:00) |
| 13:00–17:00 | ✅ 是 | 部分重叠(13:00–15:00) |
| 11:00–14:00 | ✅ 是 | 完全位于旧时段内部 |
| 06:00–07:00 | ❌ 否 | 仅接触端点,按业务允许 |
⚠️ 注意事项与最佳实践
- 时区一致性:确保所有时间戳基于同一时区(推荐使用 date_default_timezone_set() 显式设定);
- 输入校验:生产环境务必先验证 $start 和 $end 是否为合法时间格式(可用 DateTime::createFromFormat());
- 数据库存储建议:将时间存为 TIME 类型而非字符串,便于 SQL 层直接校验(如 WHERE ? < end_time AND ? > start_time);
- 扩展性考虑:若需处理跨天时段(如 23:00–02:00),需额外逻辑判断,本文方案默认适用于同日时段。
掌握这一简洁而严谨的区间比较逻辑,可稳定支撑高并发预约、会议室调度、工单排期等核心业务场景。



















