Node.js和MongoDB中去除日期对象时间及解决时区过滤问题
MongoDB聚合管道日期过滤时区偏差问题解决
问题详情
我在MongoDB聚合管道中尝试按日期筛选当月1日至12日的recharge_date数据,聚合管道代码如下:
var projectQry = [ { $match: { "prmid": userId } }, { "$unwind": { path : '$performanceData' } }, { $match: { "performanceData.recharge_date": { $gte: fromDate, $lte: toDate } } }, { $group : { _id: "$performanceData.campaign_name", basecount: { $sum: "$performanceData.basecount" } } }, { $project: { _id: 0, campaign_name: "$_id", basecount: 1 } } ];
生成日期范围的代码如下:
const date = new Date(); var fromDate = new Date(`${date.getFullYear()}-${date.getMonth()+1}-${01}`); var toDate = new Date(`${date.getFullYear()}-${date.getMonth()+1}-${12}`);
但控制台打印的日期带有时区偏移的时间部分,导致筛选结果出现偏差:
2023-02-21T18:30:00.000Z 2023-03-02T18:30:00.000Z
尝试使用setHours(0,0,0,0)也未能解决问题。
解决办法
1. 用UTC方法创建标准日期
直接通过字符串解析Date对象会采用本地时区,导致UTC时间偏移。改用Date.UTC()方法创建零时区的日期,确保时间部分为0:
const date = new Date(); const year = date.getFullYear(); const month = date.getMonth(); // getMonth()返回0-11,无需+1 // 当月1日00:00:00 UTC const fromDate = new Date(Date.UTC(year, month, 1)); // 当月12日23:59:59.999 UTC(覆盖当天所有时间点) const toDate = new Date(Date.UTC(year, month, 12, 23, 59, 59, 999));
2. 在聚合管道内直接生成目标日期
如果不想在外部处理日期,可以在$match阶段用MongoDB的$dateFromParts操作符生成UTC日期,彻底规避时区问题:
var projectQry = [ { $match: { "prmid": userId } }, { "$unwind": { path : '$performanceData' } }, { $match: { $expr: { $and: [ { $gte: [ "$performanceData.recharge_date", { $dateFromParts: { year: { $year: new Date() }, month: { $month: new Date() }, day: 1 } } ] }, { $lte: [ "$performanceData.recharge_date", { $dateFromParts: { year: { $year: new Date() }, month: { $month: new Date() }, day: 12, hour:23, minute:59, second:59, millisecond:999 } } ] } ] } } }, { $group : { _id: "$performanceData.campaign_name", basecount: { $sum: "$performanceData.basecount" } } }, { $project: { _id: 0, campaign_name: "$_id", basecount: 1 } } ];
3. 验证日期正确性
创建日期后,通过UTC格式打印确认:
console.log(fromDate.toUTCString()); // 预期输出:"Wed, 01 Mar 2023 00:00:00 GMT" console.log(toDate.toUTCString()); // 预期输出:"Sun, 12 Mar 2023 23:59:59 GMT"
内容的提问来源于stack exchange,提问作者Atul Kumar
相关产品推荐
相关产品推荐

