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
,所以有两件事我不理解:
2020-01-01T18:20:20.000Z
或服务器时区的2020-01-01T20:20:20.000Z
我知道myDate
是一个Date对象,因此我可以手动对其进行转换,但我宁愿自己也不必这样做,原因很简单,例如忘记转换应用程序中的某个日期或没有转换日期每次添加Date
字段时都要这样做
我想到的一个简单解决方案是为mongoose注册一个全局插件,该插件将使用schema.set('toJSON', ...
和schema.set('toObject', ...)
的transform方法,这样我就可以遍历shema字段,如果该字段是日期,将其更新到我的时区。
但是我发现此方法有两个问题:
以服务器时区格式获取日期的最佳方法是什么?我还是希望将它们存储在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}}对象,并在将其发送给客户端之前将其转换为字符串(由于此格式对用户不太友好,因此需要一些格式设置)。但是再说一次,我将如何在全球范围内而不是在每个日期都这样做
答案 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:20Z
或2020-01-01T20:20:20+01:00
。不要将没有偏移的日期和时间发送给客户端。否则,如果您的客户可能在其他时区,那么他们会错误地解释该值。
请记住,Date
个对象不是 时区。它们内部仅包含Unix时间戳,对于在本地时间工作的功能,它们仅转换为系统的本地时区。他们无法在其他任何时区工作。
依靠系统本地时区不利于可移植性。一个并不总是具有更改它的能力,并且当您必须在多个时区工作时,它也不是很好。最好不要依赖于Node的TZ
变量设置本地时区。相反,请考虑将代码编写为与任何本地时区设置无关。
一个时区感知日期库可以帮助您解决大多数问题。我可以推荐Luxon,js-Joda,Moment + Moment-Timezone或date-fns + date-fns-timezone。
“我将如何在全球范围内做到这一点”是我未在您的问题中关注的内容。尝试我描述的方法,如果仍然有问题,请打开一个新问题。尝试具体,并提出一个单个问题。这样您可能会获得更好的结果。请阅读How do I ask a good question?和How to create a Minimal, Complete, and Verifiable example。谢谢。