【问题标题】:Rails, Postgres and TimezoneRails、Postgres 和时区
【发布时间】:2016-02-05 18:40:46
【问题描述】:

我有一个表,其中有一个名为date 的日期时间字段。在执行 POST 以插入新行时,客户端(浏览器)发送的日期看起来像 2015-11-20T14:30:00+10:00,实际上是正确的日期和时区。

然而,在 Postgres 中,这个日期被插入为2015-11-20 04:30:00.000000,正如你所看到的,它与上面的完全不同。我知道问题与时区有关。但我似乎无法找到解决办法。

有关信息,我已经配置了我的应用时区:

class Application < Rails::Application
  config.time_zone = 'Brisbane'
end

想法?

【问题讨论】:

    标签: ruby-on-rails postgresql datetime timezone


    【解决方案1】:

    2015-11-20T14:30:00+10:00 表示14:30 的当地时间比UTC 时间早10 小时。您的数据库字段反映了正确的 UTC 值 04:30。这通常是期望的行为,特别是如果该值表示 timestamp - 某事发生的日期和时间(过去时)。

    在 PostgreSQL 中,有两种不同类型的时间戳字段 (reference)

    • TIMESTAMP WITH TIME ZONE 字段接受包含时区偏移的输入。然后它将值转换为 UTC 进行存储。在检索时,它使用会话的 timezone 设置。

    • TIMESTAMPTIMESTAMP WITHOUT TIME ZONE 仅存储给定的日期和时间,忽略任何偏移量,并且不转换为 UTC。

    大多数时候,您确实应该使用TIMESTAMP WITH TIME ZONE。如果您需要保留本地日期和时间值,例如在安排未来事件和计算营业时间时,您应该只使用TIMESTAMP WITHOUT TIME ZONE。对于这些场景,将日期和时间拆分为单独的 DATETIME 字段通常更有意义。

    最后一件事 - 如果可以避免,请避免使用 Rails time zones 并使用标准 tzdb zones。 "Australia/Brisbane" 是完整的 tzdb 标识符,相当于 Rails 的“布里斯班”时区。请参阅timezone tag wiki 底部的 Rails 时区部分。

    【讨论】:

    • 好的,感谢您的澄清。我已经检查过是否显示 Rails 的日期(04:30 one),你是对的,它确实符合我的时区。但是,有一点我不明白。为什么 Rails 时间戳实际上保存正确,而不是这个?我正在构建的系统是一个日程安排应用程序。为了维护,我们经常检查内部原始数据库查询以进行统计。看到04:30 而不是14:30 实际上很难维护。
    • 如果不了解您的具体场景和代码,很难回答,但请查看stackoverflow.com/questions/2532729/…
    • 感谢您的链接。真的很有用:)
    • 你能解释一下为什么要避开 Rails 时区吗?选择一个与另一个之间的实际区别是什么?
    • @KelseyHannan - 请参阅timezone tag wiki 的底部。大多数情况下,认为它们不包括整个世界。许多时区丢失,在 Rails 映射中没有条目。他们维护得很差,而且自以为是。它们在 Rails 之外也没有任何意义,因为 IANA TZDB 标识符几乎可以跨所有系统进行互操作。
    【解决方案2】:

    我发现这个 gem 非常有用并且很容易正确设置时间https://github.com/kbaum/browser-timezone-rails

    【讨论】:

    • 感谢您的回答。不幸的是,就我而言,服务器的时区不能依赖于浏览器。无论用户位于何处,该要求始终与服务器时区相关。不管怎样,这颗宝石总有一天会有用,所以感谢分享:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 2019-04-07
    • 2020-07-09
    相关资源
    最近更新 更多