【问题标题】:How to store daylight savings time adjusted utc time如何存储夏令时调整的UTC时间
【发布时间】:2013-10-07 19:45:16
【问题描述】:

我正在创建一个需要存储日期和时间的应用程序。目前,我正在创建这样的时间:

Time.strptime("2013-12-08 04:15pm PST", "%Y-%m-%d %H:%M%P %Z")
=> 2013-12-09 00:15:00 +0000

我很乐意将其存储在数据库中,但我的问题是关于夏令时。当我这样做时:

Time.strptime("2013-06-08 04:15pm PST", "%Y-%m-%d %H:%M%P %Z")
=> 2013-06-09 00:15:00 +0000

它似乎没有针对夏令时进行自我调整。我这样想错了吗?我怎么知道当我创建一个具有时间属性的对象时,我将能够在未来检索到那个确切的时间?

我怎样才能最好地从用户那里读取字符串日期,将它以 utc 格式保存在数据库中,然后在以后检索它以准确显示而不用担心 DST?

我知道很多答案都说在rails中使用config.time_zone,但我的应用程序最终将是跨时区的。

【问题讨论】:

  • 我不确定您要达到什么目的,但假设 user1 在某个时区发布内容,user2 在另一个时区阅读。您可以使用 user1 时区节省时间,只需将其标准化为 +0。无论哪种方式,您都需要根据user2 配置手动调整时区以显示给他。我不确定是否有更好的方法来自动处理时区。

标签: ruby datetime


【解决方案1】:

PST太平洋标准时间。如果您想要夏令时,则字符串为PDT。我想如果你将PST 转换为PDT,它会做你想做的。

# this is summer (PDT)
Time.strptime("2013-06-08 04:15pm PDT", "%Y-%m-%d %H:%M%P %Z") 

# this is winter (PST)
Time.strptime("2013-12-08 04:15pm PST", "%Y-%m-%d %H:%M%P %Z")

【讨论】:

  • Time.strptime("2013-06-08 04:15pm PDT", "%Y-%m-%d %H:%M%P %Z") => 2013-06-08 23:15:00 +0000 Time.strptime("2013-12-08 04:15pm PDT", "%Y-%m-%d %H:%M%P %Z") => 2013-12-08 23:15:00 +0000
  • 我不确定您来自哪个国家,但通常硅谷的夏季时间是 PDT,冬季时间是 PST。试试Time.strptime("2013-06-08 04:15pm PDT", "%Y-%m-%d %H:%M%P %Z")Time.strptime("2013-12-08 04:15pm PST", "%Y-%m-%d %H:%M%P %Z")
  • 我现在看到它是如何工作的,我以前不明白。但是,我正在寻找一种方法来找出 PDT/PST 部分,因为我只从用户那里得到“2013-12-08 04:15pm”并且知道他们的地址在哪里。所以,从地址我可以得到“太平洋时间(美国和加拿大)”部分。接下来,我需要查明他们提供的日期是否为 DST。这让我大吃一惊,因为我觉得应该有一种方法可以为我做到这一点。
  • @user1493849 - 您是否尝试过省略 %Z 和“PST/PDT”部分?它可能只是工作。假设您正在运行的操作系统足够智能,可以了解时区的所有详细信息,那么它可能会正常工作。
【解决方案2】:

想通了。特别感谢 @MarkLakata 指出 PDT 和 PST 之间的区别。事实证明,我们不能依靠这些来玩日期。在我的应用程序中,我确实知道我的财产的地理位置。目前,它是“太平洋时间(美国和加拿大)”,但稍后我可能会拥有许多其他地方的房产。我想安排将来的清洁工作。在现实世界中,人们通常不会围绕 DST 重新安排时间。因此,如果我说我在下午 4:15 做某事,我的意思是无论是否是 DST,我需要我的应用程序以相同的方式运行。

property.timezone
=> "Pacific Time (US & Canada)"

Time.zone = property.timezone 
=> "Pacific Time (US & Canada)"

time = Time.zone.parse("2013-12-08 04:15pm").utc
=> 2013-12-09 00:15:00 UTC

time = Time.zone.parse("2013-10-08 04:15pm").utc #DST
=> 2013-10-08 23:15:00 UTC

我将 clean_date 属性存储在 Heroku 上的 PostgreSQL DateTime 字段中。我从属性中知道时区,所以我可以在前端解析后保存它。

property.update(:cleaning_time => time)

要从数据库中取回它,我只是这样做:

def cleaning_date_string
  self.cleaning_time.in_time_zone("Pacific Time (US & Canada)").strftime("%m/%d/%Y")
end

def cleaning_time_string
  self.cleaning_time.in_time_zone("Pacific Time (US & Canada)").strftime("%l:%M%P")
end

不幸的是,这是我发现在数据库中保存精确时间并以完全相同的方式检索它的唯一方法。这似乎适用于本地和 Heroku。

补充:
这似乎是线程安全的,根据: Setting Time.zone during a request: Thread Safe?

【讨论】:

  • 您说到了重要的一点。您正在安排 未来 时间,在这种情况下,UTC 不如本地时间 + 时区对重要。另请参阅this answer,它涉及这些要点,但适用于 Java 开发人员。
【解决方案3】:

您不应依赖时区缩写。它们可能对人类有用,但它们对计算机来说是可怕的。例如,“CST”可能表示“中部标准时间”,如果您在美国,您可能知道这意味着什么。但它也可能表示“中国标准时间”或“古巴标准时间”。有一个相当不错的时区缩写列表here,清楚地表明存在重复。甚至这份名单也不是基于任何官方的。

您应该使用时区标识符而不是“PST”,例如 IANA“America/Los_Angeles”或 Rails“太平洋时间(美国和加拿大)”。

您可以使用 Rails 的 ActiveSupport::TimeZone,它有一些自定义的时区,或者如果您喜欢更通用的标准,那么您应该使用 TZInfo Ruby Gem,它采用 IANA 区域标识符。

【讨论】:

    猜你喜欢
    • 2017-07-03
    • 2016-02-06
    • 2012-10-17
    • 2012-04-07
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 2019-11-20
    相关资源
    最近更新 更多