在我的本地计算机中,我正在使用RVM
>> ruby -v
=> ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux]
# in the terminal
>> date
=> Wed Feb 27 20:00:17 PHT 2013
在我们的登台服务器中,我们使用的是rbenv
>> ruby -v
=> ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
# in the terminal
>> date
=> Wed Feb 27 12:00:22 UTC 2013
在我的本地计算机中,我正在解析来自ajax调用的日期字符串
>> Time.zone
=> (GMT+00:00) UTC
>> Time.zone.parse('Wed Feb 27 2013 19:46:21 GMT+0800 (PHT)')
=> Wed, 27 Feb 2013 19:46:21 UTC +00:00
在我们的登台服务器中,我得到了不同的结果
>> Time.zone
=> (GMT+00:00) UTC
>> Time.zone.parse('Wed Feb 27 2013 19:46:21 GMT+0800 (PHT)')
=> Wed, 27 Feb 2013 11:46:21 UTC +00:00
如何在登台服务器上进行解析结果的任何想法都能识别出时区?
答案 0 :(得分:3)
Javascript和Ruby不使用相同的时间格式,因此存在差异。一个Javascript使用(RFC 1123)是过时的,并且被一些(但不是全部!)Ruby日期时间解析方法实现读取错误,这些实现需要类似RFC 2822或ISO 8601.这种差异通过将Javascript输出到ISO格式。
ActiveSupport::TimeZone#parse
内部直接在字符串上使用Time::parse
来获取时间,然后将其放入所需的时区。
在你的情况下,你的字符串是由默认的javascript方法Date.prototype.toString
输出的,它通常提供RFC 1123格式(但因实现而异),这大部分已经过时RFC2822和{{3 }}。
RFC1123允许使用“GMT”字符串表示时区,例如“GMT + 0800”,而ISO8601则废弃该字符串,支持统一的UTC表示“+0800”,而不说“GMT”/“UT ”。 ISO8601更加紧凑(例如20130227T0914-0500
),所以也不允许说“GMT”。
因此,使用RFC2822的Time::parse
无法识别时区信息(特别是与“GMT”混淆),并且会回退到系统时区。
事实上,正如Saurabh指出的那样,这是客户端如何将时间序列化为字符串的问题。我建议更改已解析的字符串以使用标准格式,如Time::zone_offset
(类似于您的格式)或RFC2822。在这种情况下,您的时间应该正确解析。
irb(main):049:0> Time.zone.parse('Wed Feb 27 2013 19:46:21 GMT+0800 (PHT)')
=> Thu, 28 Feb 2013 00:46:21 UTC +00:00
irb(main):050:0> Time.zone.parse('Wed Feb 27 2013 19:46:21 +0800 (PHT)')
=> Wed, 27 Feb 2013 11:46:21 UTC +00:00
在我刚刚做的快速测试中,Javascript似乎无法轻松输出RFC 2822字符串(没有“GMT”)。但是,暂时不要离开你的gsub
,不能保证永远存在“GMT”或“UTC”。幸运的是,ISO似乎很容易做到。 (如果格式符合你的想象,那就是; o))
> new Date();
Wed, 27 Feb 2013 13:22:20 GMT # bad
> (new Date()).toString();
'Wed Feb 27 2013 08:22:25 GMT-0500 (EST)' # bad
> (new Date()).toUTCString();
'Wed, 27 Feb 2013 13:22:31 GMT' # still bad :(
> (new Date()).toISOString();
'2013-02-27T13:22:57.310Z' # good
或者,如果改变客户端是不可能的,或者您正在寻找快速而肮脏的修复方法,那么您可以使用Date::_parse
代替它,它似乎正确地计算出您的偏移量。
irb(main):052:0> d = Date._parse('Wed Feb 27 2013 19:46:21 +0800 (PHT)')
=> {:wday=>3, :zone=>"+0800", :hour=>19, :min=>46, :sec=>21, :year=>2013, :mon=>2, :mday=>27, :offset=>28800}
irb(main):053:0> Time.new(d[:year], d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:offset])
=> 2013-02-27 19:46:21 +0800
但是,我不确定这个方法是否可以长期依赖,因为它使用内部日期解析函数。此外,使用标准时间字符串可能是个好主意。
所以记住小孩,标准是你的朋友!使用它们!