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

如何判断指定时间是否处于MySQL存储的两个日期区间?支持忽略时间判断

问题排查

现存问题

  • 索引失效性能差:对start、end字段使用DATE_FORMAT函数处理后再比较,MySQL无法命中这两个字段的普通索引,数据量大时查询效率会大幅下降。且非全天模式下timestamp类型可以直接和标准格式的日期时间字符串比较,完全不需要格式化处理。
  • SQL注入风险高:直接把$date变量拼接到SQL语句中,没有做参数绑定,一旦传入的$date参数不可控,会被利用进行SQL注入攻击。
  • 查询结果异常原因:你当前的全天模式逻辑本身没有语法错误,查询不到结果大概率是两个原因:一是你的PresenceModel默认配置了额外查询条件(比如软删除过滤、状态字段过滤),二是DATE_FORMAT返回的字符串和传入的$date字符串存在编码或格式隐式转换问题,导致比较结果不符合预期。
修正方案

直接用原生字段比较,配合参数绑定即可解决所有问题,同时逻辑更贴合需求:

function is_available($date, $fullday = false)
{
    $presenceModel = new PresenceModel();
    $timestamp = strtotime($date);
    if ($fullday) {
        // 全天模式:判断区间是否覆盖当日
        $dayStart = date('Y-m-d 00:00:00', $timestamp);
        $dayEnd = date('Y-m-d 23:59:59', $timestamp);
        $presences = $presenceModel
            ->where('start <=', $dayEnd)
            ->where('end >=', $dayStart)
            ->findAll();
    } else {
        // 精确时间模式:直接比较时间戳
        $formatDate = date('Y-m-d H:i:s', $timestamp);
        $presences = $presenceModel
            ->where('start <=', $formatDate)
            ->where('end >=', $formatDate)
            ->findAll();
    }
    return count($presences) > 0;
}

逻辑验证

对应你给出的测试用例,修正后结果完全符合预期:

  • is_available('2021-11-02', true):区间覆盖2021-11-02全天,返回true
  • is_available('2021-11-01 09:30:00'):9:30早于start的10:00,返回false
  • is_available('2021-11-01 10:01:00'):时间在区间内,返回true
  • is_available('2021-11-05 18:00:00'):等于end时间,返回true

内容的提问来源于stack exchange,提问作者John Doener

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:45:05