Laravel中如何将用户输入日期与MongoDB ISO日期对比查询区间数据
Laravel MongoDB 日期区间查询解决方案
核心问题原因
MongoDB\BSON\UTCDateTime 构造函数要求传入毫秒级时间戳,而PHP strtotime() 函数返回的是秒级时间戳,直接传入的话会被解析为1970年附近的错误日期,自然无法匹配到目标区间的记录。
另外你示例代码中的date()调用缺少右括号属于语法错误,若实际运行无报错可忽略,大概率是粘贴时遗漏。
正确实现方式
方式1:直接使用UTCDateTime(手动处理时间戳单位)
将strtotime返回的秒级时间戳乘以1000转换为毫秒级即可:
// 开始时间:2021-09-02 00:00:00 UTC $stDate = new \MongoDB\BSON\UTCDateTime(strtotime('September 2, 2021') * 1000); // 结束时间:2021-09-07 23:59:59 UTC $edDate = new \MongoDB\BSON\UTCDateTime(strtotime('September 7, 2021 +1 day -1 second') * 1000); $query = $query->whereBetween('created_at', [$stDate, $edDate]);
方式2:使用Carbon(更适配Laravel生态)
Laravel 常用的MongoDB扩展jenssegers/laravel-mongodb原生支持Carbon对象,会自动转换为匹配的ISODate格式,无需手动处理时间戳单位,还能方便处理时区:
use Carbon\Carbon; // 若用户输入为本地时区,可替换utc()为对应时区方法,比如tz('Asia/Shanghai') $stDate = Carbon::parse('September 2, 2021')->startOfDay()->utc(); $edDate = Carbon::parse('September 7, 2021')->endOfDay()->utc(); $query = $query->whereBetween('created_at', [$stDate, $edDate]);
排查建议
如果修改后仍无结果,可先做两项校验:
- 打印生成的日期对象,确认时间范围和时区符合你的预期
- 检查集合中
created_at字段的存储类型,必须为ISODate类型,如果是字符串存储的日期则无法匹配该查询逻辑
内容的提问来源于stack exchange,提问作者P N Jain
相关产品推荐
相关产品推荐

