1

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

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

4

3 回答 3

2

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

# 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")
于 2013-10-07T19:49:42.213 回答
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

我将 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 上有效。

另外:
这似乎是线程安全的,根据: 在请求期间设置 Time.zone:线程安全?

于 2013-10-08T05:41:46.213 回答
0

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

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

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

于 2013-10-07T23:17:06.307 回答