You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Carbon判断跨午夜时间区间between方法返回错误如何解决

纯时分格式时间区间判断实现(兼容跨午夜场景)

问题说明

使用Carbon做无日期的时分区间判断时,直接调用between方法仅能支持不跨天的区间(如08:00-20:00),当区间跨午夜(如20:00-次日08:00)时会出现判断错误。
常规不跨天的初始实现代码如下:

$now = Carbon::now(); 

$start = Carbon::createFromTimeString('08:00');
$end = Carbon::createFromTimeString('20:00');

if ($now->between($start, $end)) {
    // 区间内逻辑
}

跨午夜场景下的错误复现代码:

$time= Carbon::createFromTimeString('06:00'); 
$start = Carbon::createFromTimeString('20:00');
$end = Carbon::createFromTimeString('08:00');

$time->between($start, $end); // 返回空/假,不符合"06:00属于20:00-次日08:00区间"的预期

要求传入的开始、结束时间参数不附带日期信息,仅需时分格式即可完成正确判断。

正确实现逻辑

核心是先根据开始、结束时间的大小关系区分区间类型,再做对应判断:

  • 若开始时间 小于等于 结束时间:为普通不跨天区间,直接使用原生between判断即可
  • 若开始时间 大于 结束时间:为跨午夜区间,此时区间被午夜切为两段,目标时间大于等于开始时间、或小于等于结束时间,都属于区间内

可直接复用的封装方法如下:

use Carbon\Carbon;

/**
 * 判断指定时分是否在目标时间区间内(支持跨午夜,入参无需传日期)
 * @param Carbon $targetTime 待判断的时间对象
 * @param string $startTimeStr 开始时间 格式HH:MM
 * @param string $endTimeStr 结束时间 格式HH:MM
 * @param bool $includeBoundary 是否包含区间边界 默认true和原生between行为一致
 * @return bool
 */
function isTimeInRange(Carbon $targetTime, string $startTimeStr, string $endTimeStr, bool $includeBoundary = true): bool
{
    $start = Carbon::createFromTimeString($startTimeStr);
    $end = Carbon::createFromTimeString($endTimeStr);

    if ($start->lte($end)) {
        return $includeBoundary 
            ? $targetTime->between($start, $end)
            : $targetTime->gt($start) && $targetTime->lt($end);
    }

    return $includeBoundary
        ? $targetTime->gte($start) || $targetTime->lte($end)
        : $targetTime->gt($start) || $targetTime->lt($end);
}

测试验证

// 跨天场景 06:00在20:00-08:00区间内 返回true
var_dump(isTimeInRange(Carbon::createFromTimeString('06:00'), '20:00', '08:00'));
// 跨天场景 22:00在20:00-08:00区间内 返回true
var_dump(isTimeInRange(Carbon::createFromTimeString('22:00'), '20:00', '08:00'));
// 跨天场景 12:00不在20:00-08:00区间内 返回false
var_dump(isTimeInRange(Carbon::createFromTimeString('12:00'), '20:00', '08:00'));
// 普通不跨天场景 12:00在08:00-20:00区间内 返回true
var_dump(isTimeInRange(Carbon::createFromTimeString('12:00'), '08:00', '20:00'));

内容的提问来源于stack exchange,提问作者Faizan Kamal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 21:12:41