如何判断两个时间点是否完全落在指定时间范围内

本文详解如何准确判断起止两个时间点是否**同时位于**给定的时间区间内(含端点),纠正常见逻辑错误,并推荐使用 php datetime 类实现健壮、可读性强的时序判断。

在开发排课系统、预约管理或营业时间校验等场景中,一个高频需求是:判断某段持续时间(如“9:00–11:15”)是否完全包含在另一时间段内(如“9:00–10:00”)。但许多开发者会误用逻辑条件,导致边界判断失效——例如将 9:00 和 11:15 判定为“属于 9:00–10:00”,这显然错误。

关键在于明确语义:
“两个时间点都落在区间内” 的数学定义是:

start_time ≥ interval_start 且 start_time ≤ interval_end 且end_time ≥ interval_start 且 end_time ≤ interval_end

而原代码中的错误在于第二个子条件写成了:

($hfin >= $ihdebutcours) && ($hfin >= $ihfincours)  // ❌ 错误:应为 <=,不是 >=

这实际要求结束时间不小于区间终点,与目标逻辑完全相反。

✅ 推荐方案:使用 PHP DateTime 类(安全、清晰、支持时区)

= $dtRangeStart && 
    $dtStart <= $dtRangeEnd && 
    $dtEnd   >= $dtRangeStart && 
    $dtEnd   <= $dtRangeEnd
) {
    $f++; // 满足条件,计数加一
}

⚠️ 注意事项与最佳实践

  • 避免 strtotime() + 数值比较:strtotime() 返回整型时间戳,虽可比较,但易受日期上下文干扰(如无日期时默认为当天,跨日逻辑难处理),且可读性差;
  • DateTime 支持自然字符串解析:'9:00'、'10:30 AM'、'16:45' 均可直接识别,无需手动格式化;
  • 边界包含策略明确:上述示例采用闭区间(含端点)。若需开区间(如 > /
  • 扩展建议:如需检测“部分重叠”或“完全不重叠”,可改用 DateTime::diff() 计算时间差,或借助 DatePeriod 构建时间序列进行精细化判断;
  • 生产环境提醒:涉及跨日(如 '23:00' → '01:00')、夏令时或不同时区时,务必显式设置时区(如 $dt->setTimezone(new DateTimeZone('Asia/Shanghai')))。

通过 DateTime 类,你不仅修复了逻辑漏洞,更获得类型安全、可维护性强、符合现代 PHP 实践的解决方案。一行清晰的比较,胜过十行易错的数值运算。