whereTime仅适用于datetime/date或字符串日期字段,对整数时间戳无效;正确用法是whereTime('field', '>=', '-3 days'),避免直接传时间戳或模糊字符串,并注意时区与索引失效问题。

whereTime 的基本写法和常见错误
ThinkPHP 的 whereTime 不是万能时间过滤器,它只对字段类型为 datetime、date 或字符串格式的日期字段生效,且底层依赖数据库的日期函数(如 MySQL 的 DATE())。直接对整数型时间戳字段用 whereTime 会静默失效或报错。
- 正确场景:数据库字段是
create_time(类型DATETIME),值为'2024-05-20 14:30:00' - 错误写法:
whereTime('create_time', '>', time() - 86400 * 3)——time()返回整数,和字符串日期比大小,MySQL 会转成 0 或报错 - 真正生效的是:
whereTime('create_time', '>=', '-3 days')这类相对表达式,TP 会自动解析并生成DATE_SUB(NOW(), INTERVAL 3 DAY)
支持的时间表达式格式与陷阱
whereTime 接收的第二个参数是操作符('>'、'>='、'between' 等),第三个参数才是时间值。这个“时间值”不是 PHP 时间戳,而是 TP 自定义的可解析字符串,规则很窄。
- 推荐用法:
whereTime('create_time', '>=', '-3 days')、whereTime('create_time', 'between', ['-7 days', 'today']) - 不能写:
'-3d'(少空格)、'last 3 days'(语法不识别)、'2024-05-20'(虽然能用,但没时区保障,建议配合strtotime显式转换) - 注意时区:TP 默认用 PHP 的
date_default_timezone_set(),若数据库用 UTC 而 PHP 设了Asia/Shanghai,'-1 day'可能差 8 小时
替代方案:更可控的 where + date_format / strtotime
当 whereTime 表达力不够(比如要查“今天上午 9 点之后”或跨月统计),直接用 where 更稳妥,也更容易调试。
- 查最近 3 天(含今天):
where('create_time', '>=', date('Y-m-d H:i:s', strtotime('-3 days'))) - 查本周一零点开始:
where('create_time', '>=', date('Y-m-d 00:00:00', strtotime('this week Monday'))) - 如果字段是整数时间戳(如
create_at类型INT),必须用where:where('create_at', '>=', strtotime('-3 days')) - 注意:
strtotime在 PHP 8.2+ 对模糊字符串(如'last monday')行为有变化,生产环境建议固定格式
性能和兼容性提醒
whereTime 最终会被编译成 SQL 函数调用(如 DATE(create_time) >= DATE_SUB(NOW(), INTERVAL 3 DAY)),这会导致该字段无法使用普通 B-Tree 索引——除非你建了函数索引(MySQL 8.0+)或表达式索引(PostgreSQL)。
立即学习“PHP免费学习笔记(深入)”;
- 高频查询建议:在
create_time上建普通索引,并改用where('create_time', '>=', '2024-05-20 00:00:00')这种范围查询 - SQLite 不支持
DATE_SUB,whereTime会退化为 PHP 端过滤,大数据量下极慢 - TP 6.0+ 支持
whereTime的第四个参数指定数据库类型,但实际很少需要手动干预
真正卡住人的往往不是语法,而是字段类型和索引策略不匹配——写完 whereTime 一定要 ->fetchSql(true) 看一眼生成的 SQL,再 explain 一下执行计划。



















