You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将ISO格式日期时间设为0?Mongo日期对比问题

解决Mongo ISO日期与本地“今日”对比的时区问题

这个问题本质是本地时区和UTC时区的差异在搞鬼!你用setHours(0,0,0,0)设置的是本地时区的0点,但toISOString()会把日期转换成UTC时区的字符串,所以当你的本地时区是GMT-0800时,本地0点就等于UTC的8点,最终ISO字符串自然会显示T08:00:00.000Z

下面根据你的实际需求,给出两种常用解决方案:

需求1:对比UTC时区的“今日”

如果你要找Mongo中属于UTC当天的记录(即ISO日期为YYYY-MM-DDT00:00:00.000ZYYYY-MM-DDT23:59:59.999Z之间),直接基于UTC创建日期对象即可:

// 获取UTC时区的当天0点
const utcTodayStart = new Date(Date.UTC(
  new Date().getUTCFullYear(),
  new Date().getUTCMonth(),
  new Date().getUTCDate()
));
// 获取UTC时区的次日0点(用于范围查询)
const utcTodayEnd = new Date(utcTodayStart.getTime() + 24 * 60 * 60 * 1000);

console.log(utcTodayStart.toISOString()); // 输出类似 "2018-01-20T00:00:00.000Z"
console.log(utcTodayEnd.toISOString());   // 输出类似 "2018-01-21T00:00:00.000Z"

之后在Mongo中可以用范围查询:

db.collection.find({
  yourDateField: {
    $gte: utcTodayStart,
    $lt: utcTodayEnd
  }
})

需求2:对比本地时区的“今日”

如果你的业务逻辑是基于用户本地时区的“今天”(比如国内用户的北京时间当天),需要把本地时区的当天起止时间转换成UTC时区的范围,再去Mongo查询:

// 先获取本地时区的当天0点
const localTodayStart = new Date();
localTodayStart.setHours(0, 0, 0, 0);
// 本地时区的次日0点
const localTodayEnd = new Date(localTodayStart.getTime() + 24 * 60 * 60 * 1000);

// 转换成UTC格式的字符串(或Date对象)用于Mongo查询
const utcLocalStart = localTodayStart.toISOString(); // 示例输出 "2018-01-20T08:00:00.000Z"
const utcLocalEnd = localTodayEnd.toISOString();     // 示例输出 "2018-01-21T08:00:00.000Z"

对应的Mongo查询:

db.collection.find({
  yourDateField: {
    $gte: utcLocalStart,
    $lt: utcLocalEnd
  }
})

关键提醒

Mongo中存储的日期默认都是UTC时区的,所以对比时一定要明确业务逻辑是基于UTC还是本地时区,避免因为时区偏移导致查询结果出错。

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

火山引擎 最新活动