如何存储夏令时调整时间

时间:2013-10-07 19:45:16

标签: ruby datetime

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

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,但我的应用程序最终将是跨时区。

3 个答案:

答案 0 :(得分:2)

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")

答案 1 :(得分:1)

想出来。特别感谢@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

我将cleaning_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?

答案 2 :(得分:0)

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

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

您可以使用具有一些自定义时区的Rails' ActiveSupport::TimeZone,或者如果您更喜欢更普遍标准的内容,则应使用TZInfo Ruby Gem,它会使用IANA区域标识符。