为何Mongoose存储momentTz处理的日期非当天起始,如何解决?
解决Mongoose存储日期时区偏移问题
问题本质
MongoDB 默认以 UTC时间 存储日期数据。印度时区(Asia/Kolkata)比UTC快5小时30分钟,所以当你设置印度时区的00:00:00(当天起始时间)时,转换为UTC时间就是前一天的18:30:00——这是正常的时区转换结果,并非代码错误。
你可以验证这一点:把存储的日期值转回印度时区,会得到正确的当天起始时间:
// 假设dbDate是从MongoDB读取的日期值 const localStartDate = momentTz(dbDate).tz("Asia/Kolkata").format("MM/DD/YYYY HH:mm:ss"); // 输出会是类似 "12/01/2022 00:00:00"
解决方案
如果希望在读写时自动处理时区,让代码更直观,可以通过以下两种方式处理:
1. 给Mongoose Schema字段指定时区(推荐)
从Mongoose 5.10版本开始,支持为Date类型字段设置timezone选项,自动完成时区转换:
const yourSchema = new mongoose.Schema({ startDate: { type: Date, timezone: "Asia/Kolkata" // 指定目标时区 } });
这样:
- 写入时,Mongoose会自动将你传入的印度时区日期转换为UTC存储
- 读取时,会自动将UTC日期转换回印度时区的时间
2. 读取数据时手动转换时区
你的现有代码其实已经正确生成了印度时区的当天起始时间,只是存储的UTC显示容易造成误解。如果不需要Schema层面的配置,也可以在读取数据后手动转换时区:
// 从数据库读取文档后转换为印度时区的当天起始时间 doc.startDate = momentTz(doc.startDate).tz("Asia/Kolkata").startOf("day").toDate();
总结
你看到的18:30:00是UTC时间的正常表现,对应的印度时区时间仍然是当天的00:00:00。通过Schema指定时区或读取时手动转换,就能让显示的时间符合预期。
内容的提问来源于stack exchange,提问作者Fasal Rahman
相关产品推荐
相关产品推荐

