【问题标题】:Timezone problems with MongoDB and NodeJsMongoDB 和 NodeJs 的时区问题
【发布时间】:2020-02-27 15:04:50
【问题描述】:

所以我目前遇到的问题是:

我有一个体育课程列表,每个课程都有一个开放时间。我想从当天获取所有课程,但是。我在本地和生产中没有得到相同的结果,由于某种原因,当我将后端部署到 Heroku 时,时区默认设置为 UTC(当我有 GMT-3 时区时)。

这是我的查询:

 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 } }] })

所以,就像我之前说的,问题发生在例如:

当我在本地时间(例如:02-26-19 21:00hs (GMT-3))获取课程时,查询实际上显示的是 02-27 的课程,因为,在 MINE 21:00hs,服务器端已经是 00:00,所以日期不再是 02-26。而且我不想要这种输出。

我怎样才能找到解决此问题的解决方法?

提前致谢! :)

【问题讨论】:

  • 您是否尝试过规范化您的客户端查询以解释其时区是差异(负 3)这一事实,然后将增量小时传递给您接受参数的服务器 api(小时 + 或- ) 并将其传递给您的函数进行数据库调用

标签: node.js mongodb heroku mongodb-query aggregation-framework


【解决方案1】:

不要使用.format(),这会产生一个字符串。直接比较Date的值,即使用

var now = moment();

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

默认moment 使用当地时间,所以moment().startOf('day') 返回当地时间的午夜。如果您想获得 UTC 的午夜,请使用 moment.utc().startOf('day')

如果你不依赖“本地”时区,那么你可以像moment.tz("America/New_York").startOf('day')一样指定它

无论您需要什么时间,从不按字符串比较日期值,始终使用实际的Date 值。

【讨论】:

    【解决方案2】:

    默认情况下,在 MongoDB 中,日期字段存储在 UTC 中,您可以在写入时创建一个带偏移量的日期,以将其存储在您的时区中。但是您在编写文档时还没有这样做,那么您需要在从数据库中读取数据时将日期字段转换为所需的时区。检查以下示例。

    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
    

    查询:

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

    以上查询是针对纽约时区编写的,您可以根据您的时区进行转换,在测试 url 中您可以看到第一个文档未返回,尽管它位于 2020-02-26 上,因为截至今天与纽约的偏移量为 5 小时,所以转换后日期变成2020-02-25

    测试: MongoDB-Playground

    参考:$dateToString

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-10
      • 1970-01-01
      • 2022-08-14
      • 2019-03-04
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多