简体   繁体   English

MongoDB 和 NodeJs 的时区问题

[英]Timezone problems with MongoDB and NodeJs

So the problem I'm currently having is :所以我目前遇到的问题是:

I've a list of gym classes, which every class has an OpeningTime.我有一份健身课程的清单,每个课程都有一个 OpeningTime。 I want to fetch all the classes from the current day, but.我想从当天获取所有课程,但是。 I'm not getting the same result locally and in production, cause for some reason, when Im deploying my backend to Heroku, the timezone is being setted by default to UTC (when I've a GMT-3 timezone).我在本地和生产中没有得到相同的结果,由于某种原因,当我将我的后端部署到 Heroku 时,时区默认设置为 UTC(当我有一个 GMT-3 时区时)。

Here is my query :这是我的查询:

 var now = moment();

 var startOfDay = now.startOf('day').format();

 var endOfDay = now.endOf('day').format();

 var clasesDB = await Clase.find({ $and: [{ openingTime: { $gte: startOfDay } }, { openingTime: { $lte: endOfDay } }] })

So, like I said before, the problem is ocurring when, for example:所以,就像我之前说的,问题发生在,例如:

When I fetch the classes at my local time (Ex: 02-26-19 21:00hs ( GMT-3) ), the queries are actually showing the classes from 02-27 , because, at MINE 21:00hs, on the server side is already 00:00, so, the date is not 02-26 anymore.当我在本地时间(例如: 02-26-19 21:00hs ( GMT-3) )获取类时,查询实际上显示的是02-27的类,因为在 MINE 21:00hs,在服务器上那边已经是 00:00,所以,日期不再是02-26 And I dont want this kind of output.我不想要这种输出。

How can I get a workaround to solve this?我怎样才能找到解决这个问题的方法?

Thanks in advance!提前致谢! :) :)

By default in MongoDB a date field is stored in UTC , You can create a date with offset while writing to store it in your timeZone.默认情况下,在 MongoDB 中,日期字段以UTC格式存储,您可以在写入时创建带有偏移量的日期以将其存储在时区中。 But you've not done it while writing documents then you need to convert date field to your required timeZone while reading data from database.但是您在编写文档时没有这样做,那么您需要在从数据库读取数据时将日期字段转换为所需的时区。 Check this below example.检查下面的示例。

JavaScript Code : JavaScript 代码:

const today = new Date().toLocaleDateString(undefined, {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric'
})  // 02/26/2020. If your Heroic server is in different location then specify your locale in place of undefined - whereas undefined picks local time by default. Ex:- 'en-Us' for USA

Query :询问 :

db.collection.aggregate([
    { $addFields: { timewithOffsetNY: { $dateToString: { format: "%m/%d/%Y", date: "$openingTime", timezone: "America/New_York" } } } },
    { $match: { timewithOffsetNY: today } }, { $project: { timewithOffsetNY: 0 } }
])

Above query is written for New York timeZone, you can convert it according to your timeZone, In test url you can see 1st doc is not returned though it is on 2020-02-26 cause offset to New York as of today is 5hrs, So after converting date becomes as 2020-02-25 .上面的查询是为纽约时区编写的,您可以根据您的时区进行转换,在测试 url 中,您可以看到第一个文档没有返回,尽管它是在2020-02-26因为今天到纽约的偏移是 5 小时,所以转换日期后变为2020-02-25

Test : MongoDB-Playground测试: MongoDB-Playground

Ref : $dateToString参考: $dateToString

Don't use .format() , this makes a string .不要使用.format() ,这会生成一个string Compare directly Date values, ie use直接比较Date值,即使用

var now = moment();

var startOfDay = now.startOf('day').toDate();    
var endOfDay = now.endOf('day').toDate();

By default moment uses local times, so moment().startOf('day') returns midnight of local time.默认moment使用本地时间,因此moment().startOf('day')返回本地时间的午夜。 If you want to get midnight of UTC then use moment.utc().startOf('day') .如果您想获得 UTC 的午夜,请使用moment.utc().startOf('day')

If you don't rely on "local" time zone, then you can specify it like moment.tz("America/New_York").startOf('day')如果您不依赖“本地”时区,那么您可以像moment.tz("America/New_York").startOf('day')一样指定它

No matter which time you need, never compare Date values by string, use always actual Date value.无论您需要什么时间,都不要按字符串比较日期值,始终使用实际Date值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM