Mongoose $lte操作符比较日期不符合预期的原因排查
Mongoose日期范围查询无法匹配31日记录的原因及解决办法
核心原因
主要是两个问题导致的:
endDate的时间部分默认是当日0点
如果你直接把endDate设为"2022-03-31",JavaScript会自动将其解析为本地时区的2022-03-31 00:00:00。哪怕转成UTC时间,数据库里的记录是"2022-03-31T11:32:40.000+00:00"(当天11点的UTC时间),用$lte对比时,这条记录的时间明显晚于endDate的0点,自然会被过滤掉。时区不一致
MongoDB默认以UTC时区存储日期,如果你在本地时区(比如东八区)创建endDate,转成UTC后会变成前一天的16点(比如本地3月31日0点 = UTC3月30日16点),这时候去匹配数据库里31日的UTC时间,肯定查不到目标记录。
解决办法
方法1:用次日0点配合$lt替代$lte
这是最稳妥的方案,不用纠结时间和时区问题:
比如要查询3月31日及之前的记录,把endDate设为4月1日的UTC0点,然后用$lt代替$lte,这样就能包含3月31日全天的所有记录:
// 示例:查询2022年3月1日到3月31日的记录 const startDate = new Date(Date.UTC(2022, 2, 1)); const endDate = new Date(Date.UTC(2022, 3, 1)); // 4月1日UTC0点 var docsByDateRange = await expense.find({ user_id: user_id, date_of_expense: { $gte: startDate, $lt: endDate } })
方法2:明确设置endDate为目标日期的UTC最后一刻
如果一定要用$lte,可以把endDate设为目标日期UTC的23:59:59.999,确保覆盖当天所有时间点:
const endDate = new Date(Date.UTC(2022, 2, 31, 23, 59, 59, 999)); var docsByDateRange = await expense.find({ user_id: user_id, date_of_expense: { $gte: startDate, $lte: endDate } })
方法3:统一日期处理为UTC时区
在创建所有日期对象时,都用Date.UTC()来生成UTC时间,避免本地时区干扰,确保和MongoDB存储的时区一致。
内容的提问来源于stack exchange,提问作者Deepeshkumar Pakhare
相关产品推荐
相关产品推荐

