Ruby on rails 3 Rails通过DST边界给出了错误的strftime时间
我有一个字符串Ruby on rails 3 Rails通过DST边界给出了错误的strftime时间,ruby-on-rails-3,timezone,dst,Ruby On Rails 3,Timezone,Dst,我有一个字符串“东部时间2014-03-15下午3:30(美国和加拿大)”,我想将其转换为日期时间并存储在我的数据库中 这很简单: str = "3:30 PM 2014-03-15 Eastern Time (US & Canada)" event.starts_at = DateTime.strptime(str, "%l:%M %p %Y-%m-%d %Z") 这将创建具有正确时区的日期时间。但是,如果我将事件保存到数据库中,然后像这样将其读回: e.starts_at.in_t
“东部时间2014-03-15下午3:30(美国和加拿大)”
,我想将其转换为日期时间并存储在我的数据库中
这很简单:
str = "3:30 PM 2014-03-15 Eastern Time (US & Canada)"
event.starts_at = DateTime.strptime(str, "%l:%M %p %Y-%m-%d %Z")
这将创建具有正确时区的日期时间。但是,如果我将事件保存到数据库中,然后像这样将其读回:
e.starts_at.in_time_zone("Eastern Time (US & Canada)")
.strftime("%l:%M %p") => #outputs 4:30 PM, when I want it to say 3:30 PM
输出给出了错误的时间(似乎是因为它正在调整DST)!如何解决此问题?
DateTime.strtime
属于Ruby,而“东部时间(美国和加拿大)”等时区标识符仅由Rails通过提供
简单地说,DateTime
根本不理解时区。您可以发现%z
和%z
标记定义如下:
Time zone:
%z - Time zone as hour and minute offset from UTC (e.g. +0900)
%:z - hour and minute offset from UTC with a colon (e.g. +09:00)
%::z - hour, minute and second offset from UTC (e.g. +09:00:00)
%:::z - hour, minute and second offset from UTC
(e.g. +09, +09:30, +09:30:30)
%Z - Time zone abbreviation name or something similar information.
%z
的定义是有道理的,但是%z
的定义是可笑的。它并没有真正说明什么是允许的或期望的。也许它正在寻找一个缩写词,如“EST”或“EDT”,或者它将允许一些关键字,如“Eastern”。我真的不确定,但我认为它不太可能完全了解Rails的时区概念(这也很可笑,请看本书的最底层)
从逻辑上讲,代码示例中发生的情况是,该值在东部标准时间中被解析——即使东部夏时制对您经过的时间有效。只是一个猜测,但解析器中的某些东西可能正在提取“东方”并假设EST。然后它以-5偏移量错误地保存在数据库中。当Rails将其加载回并使用通用的“东部时间(美国和加拿大)”时区进行处理时,它知道EDT是有效的,因此它以正确的-4偏移量加载它。偏移量的差异就是为什么在一小时后看到结果
建议#1-放弃铁路时区标识符。改为使用Ruby,它提供了正常的ID,如America/NewYork
建议#2-如果必须使用Rails时区,请将其与from Rails结合使用,而不是DateTime.strtime
(我对Ruby不是特别熟练,或者我会给你举个例子。也许有人可以编辑我的回答来提供一个,或者在他们自己的答案中提供一个。)我最终使用了
Time.zone.parse
,目前它仍然有效,但我还没有完全测试它,因为DST边界已经过了。