如何为 Mongoose 中的日期字段设置正确的时区?

sam*_*ode 3 mongoose mongodb node.js momentjs moment-timezone

我正在使用moment来生成时间和日期:

const moment = require('moment-timezone');
const emailModel = require('./api/models/emails');

sentTime=moment().tz('America/Los_Angeles').format();
console.log(sentTime);    //console log  shows correct time
emailModel.findOneAndUpdate({ _id: emailInfo._id }, {sentTime: sentTime }, { upsert: true },function (err, doc) {
  if (err)
    console.log(err);
});
Run Code Online (Sandbox Code Playgroud)

这是我正在使用mongoose 的架构:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;
const EmailSchema = new Schema({
   .
   .
   .
    sentTime: {
        type: Date,
        trim: true
    }
   .
   .
   .
});
Run Code Online (Sandbox Code Playgroud)

问题是:控制台日志显示正确的时间2020-01-07T12:23:00-08:00 但猫鼬在数据库中保存了错误的时区:2020-01-07T20:23:01.000+00:00

amb*_*ing 5

目前 Mongodb 的默认行为是:(来自文档

MongoDB 默认以 UTC 格式存储时间,并将任何本地时间表示转换为这种形式。

作为一个解决方案(也是正确的),他们推荐的是:

必须操作或报告某些未修改的本地时间值的应用程序可以将时区与 UTC 时间戳一起存储,并在其应用程序逻辑中计算原始本地时间。

更新: 由于您已经使用了moment-timezone一种简单的方法,我会这样做:

更改EmailSchema为具有时区字段并在该架构上创建Mongoose 虚拟字段以获得调整后的时间。

const schemaOpts = { toJSON: { virtuals: true } };
const EmailSchema = new Schema(
  {
    sentTime: {
      type: Date,
      trim: true
    },
    timeZone: {
      type: String
    }
  },
  schemaOpts
);

EmailSchema.virtual("adjustedTime").get(function() {
  return moment.tz(this.sentTime, this.timeZone).format();
});

//fetching data
const result = await EmailSchema.findOne({}).exec();
console.info("result::", result.toJSON());

//note that if using .lean() for performance which has a caveat on using .toJSON()
Run Code Online (Sandbox Code Playgroud)