Ruby: Time.parse() 错误返回阿拉斯加时区

Ruby: Time.parse() Incorrectly Returning Alaskan Timezone

在我的应用中,我正在使用

> Time.parse('12:30 pm MDT').utc
=> 2015-06-08 18:30:00 UTC
> Time.parse('12:30 pm EDT').utc
=> 2015-06-08 16:30:00 UTC
> Time.parse('12:30 pm CDT').utc
=> 2015-06-08 17:30:00 UTC
> Time.parse('12:30 pm PDT').utc
=> 2015-06-08 19:30:00 UTC
> Time.parse('12:30 pm MST').utc
=> 2015-06-08 19:30:00 UTC

一切正常,但是当我开始询问夏威夷或阿拉斯加时区时,returns 结果不正确:

> Time.parse('12:30 pm HST').utc
=> 2015-06-08 12:30:00 UTC
> Time.parse('12:30 pm HAST').utc
=> 2015-06-08 12:30:00 UTC
> Time.parse('12:30 pm AKDT').utc
=> 2015-06-08 12:30:00 UTC
> Time.parse('12:30 pm AKST').utc
=> 2015-06-08 12:30:00 UTC

即使这样也行不通:

> Time.parse('12:30 pm -800').utc
=> 2015-06-08 12:30:00 UTC

有人知道为什么会这样吗?也许更重要的是,有人对如何解析 -800 或 -900 的时间有任何建议吗?

The documentation of Time.parse 包含(强调我的):

Since there are numerous conflicts among locally defined time zone abbreviations all over the world, this method is not intended to understand all of them. For example, the abbreviation “CST” is used variously as:

-06:00 in America/Chicago,
-05:00 in America/Havana,
+08:00 in Asia/Harbin,
+09:30 in Australia/Darwin,
+10:30 in Australia/Adelaide,
etc.

Based on this fact, this method only understands the time zone abbreviations described in RFC 822 and the system time zone, in the order named. (i.e. a definition in RFC 822 overrides the system time zone definition.) The system time zone is taken from Time.local(year, 1, 1).zone and Time.local(year, 7, 1).zone. If the extracted time zone abbreviation does not match any of them, it is ignored and the given time is regarded as a local time.

以下摘自RFC 822(5.1)中的语法说明:

 zone        =  "UT"  / "GMT"                ; Universal Time
                                             ; North American : UT
             /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
             /  "CST" / "CDT"                ;  Central:  - 6/ - 5
             /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
             /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
             /  1ALPHA                       ; Military: Z = UT;
                                             ;  A:-1; (J not used)
                                             ;  M:-12; N:+1; Y:+12
             / ( ("+" / "-") 4DIGIT )        ; Local differential
                                             ;  hours+min. (HHMM)

如您所见,未提及您的时区名称。你必须写 -0800-0900 因为前导零是必需的(以匹配 4DIGIT 部分)。如果您想要或必须保留名称,可以使用更复杂的 DateTime class。

Time.parse('12:30 pm -0800').utc # => 2015-06-08 20:30:00 UTC
DateTime.parse('12:30 pm AKDT').to_time.utc # => 2015-06-08 20:30:00 UTC