猫鼬日期时间和时区,如何基于服务器时区获取日期时间

时间:2019-04-19 14:40:12

标签: node.js mongodb datetime mongoose timezone

this问题的第一个答案表明,猫鼬在检索数据时会根据服务器时区调整日期。

但是我没有这个称呼。 我使用以下命令设置(节点)服务器时区: process.env.TZ='Europe/Paris'

例如,如果我创建一个简单的模型,例如:

const mongoose = require("mongoose");
const testSchema = new mongoose.Schema({
    myDate: { type: Date, required: true },
}, { timestamps: true });

exports.Comment = mongoose.default.model('TestSchema', testSchema); 

但是,如果我使用2020-01-01 20:20:20创建日期,那么在进行TestSchema.find()时,日期将是:2020-01-01T19:20:20.000Z,所以有两件事我不理解:

  • 欧洲/巴黎实际上是UTC +2,所以我希望日期是UTC的2020-01-01T18:20:20.000Z或服务器时区的2020-01-01T20:20:20.000Z
  • 如何让猫鼬自动将日期设置为正确的时区?

我知道myDate是一个Date对象,因此我可以手动对其进行转换,但我宁愿自己也不必这样做,原因很简单,例如忘记转换应用程序中的某个日期或没有转换日期每次添加Date字段时都要这样做

我想到的一个简单解决方案是为mongoose注册一个全局插件,该插件将使用schema.set('toJSON', ...schema.set('toObject', ...)的transform方法,这样我就可以遍历shema字段,如果该字段是日期,将其更新到我的时区。 但是我发现此方法有两个问题:

  • 如果我要查询很多包含很多字段的文档,这听起来并不是很好的表现
  • 如您所见here,我目前无法注册全局插件...

以服务器时区格式获取日期的最佳方法是什么?我还是希望将它们存储在UTC中,但要根据服务器时区设置小时。

编辑:

我刚刚看到,虽然console.log(myDate)输出2018-01-01T19:20:20.000Z console.log(myDate.toString()输出Mon Jan 01 2018 20:20:20 GMT+0100 (Central European Standard Time),所以似乎可以使用它,即使我宁愿还有一个{{ 1}}对象,并在将其发送给客户端之前将其转换为字符串(由于此格式对用户不太友好,因此需要一些格式设置)。但是再说一次,我将如何在全球范围内而不是在每个日期都这样做

1 个答案:

答案 0 :(得分:1)

几件事:

    Europe/Paris
  • 2020-01-01T20:20:20是UTC + 1。直到3月29日夏令时开始,它才会切换到UTC + 2。 Reference here。因此,转换为2020-01-01T19:20:20Z是正确的。

  • 传递console.log对象时Date的输出是特定于实现的。一些实现将发出.toString()的输出(在本地时间为RFC 2822格式,有些实现将发出.toISOString()的输出(在UTC中为ISO 8601扩展格式)。这就是为什么您会看到差异。

  • 通常,在不发送时区偏移的情况下发送本地时间也不好。 ISO 8601格式是理想的格式,但是您应该发送2020-01-01T19:20:20Z2020-01-01T20:20:20+01:00。不要将没有偏移的日期和时间发送给客户端。否则,如果您的客户可能在其他时区,那么他们会错误地解释该值。

  • 请记住,Date个对象不是 时区。它们内部仅包含Unix时间戳,对于在本地时间工作的功能,它们仅转换为系统的本地时区。他们无法在其他任何时区工作。

  • 依靠系统本地时区不利于可移植性。一个并不总是具有更改它的能力,并且当您必须在多个时区工作时,它也不是很好。最好不要依赖于Node的TZ变量设置本地时区。相反,请考虑将代码编写为与任何本地时区设置无关。

  • 一个时区感知日期库可以帮助您解决大多数问题。我可以推荐Luxonjs-JodaMoment + Moment-Timezonedate-fns + date-fns-timezone

  • “我将如何在全球范围内做到这一点”是我未在您的问题中关注的内容。尝试我描述的方法,如果仍然有问题,请打开一个新问题。尝试具体,并提出一个单个问题。这样您可能会获得更好的结果。请阅读How do I ask a good question?How to create a Minimal, Complete, and Verifiable example。谢谢。

相关问题