【问题标题】:Ruby: Time.parse() Incorrectly Returning Alaskan TimezoneRuby:Time.parse() 错误地返回阿拉斯加时区
【发布时间】:2015-06-08 16:20:25
【问题描述】:

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

> 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

这一切都很好,但是一旦我开始询问夏威夷或阿拉斯加时区,它就会返回一个不正确的结果:

> 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 的时间有任何建议吗?

【问题讨论】:

  • 您使用的是哪个 Ruby 版本?
  • 可能是您的系统不知道这些时区是什么。您使用的是什么操作系统和 Ruby 版本?这里 `Time.parse('12:30 pm HST').utc` 在 Ruby 2.1.5、OS X 10.10 上生成 2015-06-08 16:30:00 UTC,尽管那不是夏威夷时间。
  • 我也在 10.10 和 ruby​​ 2.1.1 和 rails 4.1.1,但我确实尝试使用 ruby​​ 2.1.5,这也产生了2015-06-08 12:30:00 UTC。您的回复 f Time.parse('12:30 pm HST').utc 产生 2015-06-08 16:30:00 UTC 也令人担忧,它应该产生 21:30:00 UTC,对吧?这是一个红宝石错误吗?

标签: ruby datetime timezone


【解决方案1】:

Time.parseThe documentation 包含(强调我的):

由于本地定义的时区之间存在许多冲突 世界各地的缩写,此方法不适用于 了解所有这些。例如,使用缩写“CST” 不同的是:

-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.

基于这个事实,这个方法只理解时区 RFC 822 中描述的缩写和系统时区,在 命令命名。 (即 RFC 822 中的定义覆盖系统时间 时区定义。)系统时区取自Time.local(year, 1, 1).zoneTime.local(year, 7, 1).zone如果提取时间 区域缩写与它们中的任何一个都不匹配,它被忽略并且 给定时间被视为当地时间。

以下来自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 类。

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

【讨论】:

    猜你喜欢
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 2013-09-26
    • 2016-11-13
    • 2014-06-30
    相关资源
    最近更新 更多