微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Rails:获取时区偏移量名称

如何解决Rails:获取时区偏移量名称

在Ruby或Rails中,给定诸如America/Los_Angeles之类的时区标识符,我看到了如何获得特定的时区偏移量缩写,如PDT:

Time.current.in_time_zone('America/Los_Angeles').zone
=> "PDT"

Time.Now.in_time_zone("America/Los_Angeles").strftime('%Z')
=> "PDT"

Time.Now.in_time_zone("America/Los_Angeles").strftime('%z')
=> "-0700"

甚至是时区本身的友好名称

ActiveSupport::TimeZone::MAPPING.key('America/Los_Angeles')
=> "Pacific Time (US & Canada)"

但是如何获得Pacific Daylight Time之类的字符串而不是PDT来表示特定日期的完整时区偏移量名称

输入:America/Los_Angeles和特定的日期或日期时间

所需的输出Pacific Daylight Time

解决方法

短篇小说:〜由于某种原因,〜(由于@bata mentioned in his answer的缩写不是唯一的,因此这可能是没有正式的缩写-人性化名称映射的原因)该标准似乎不支持它。您可能需要自己实现此映射。但是请继续阅读,如果您想获得一些指导,为什么它可能没有那么容易。

所以...这是一个有趣的兔子洞,可以落入...

使用了哪些宝石,它们从何处获取信息

ActiveSupport uses tzinfo gem for that,它依次使用tz-info gem。 tz-infouses one of two data sources

    Unix类系统中的
  • zoneinfo目录
  • TZInfo :: Data

Rails的Gemfile模板confirms that TZInfo data is used on window

起初,我认为可能会有PR机会为流行的宝石做出贡献。 Quick search suggests没有PDT到任何“人类友好形式”的映射。

查看unix的{​​{1}}数据库

zoneinfo

看起来像一个二进制文件...

$ cat /usr/share/zoneinfo/America/Los_Angeles
TZif2H*ˉ#pa&t\؀Ðݩ޾߉iip~KIR^-)4GJQ',3qo_O?/v( fe HG *)
                                                     x                                                   
                                                       q(a'Q                                             
A       0C      ΐ

௠
 #j$5 %J& '*'))6 "S      54+ !"V
eGYe턠g';gfiiHjke lmvG noV) pq6: XX YZ [޵\ ]^d _y`Mޠab-cgwdE G-Gӵ I                                      
                                ros tOt v8vxx͠yz{f|~}H~^s*&                                               
                                                         LMTPDTPSTPWTPPTTZif2^H*ˉ#pa&t\؀Ðݩ޾߉iip~KIR^-)4GJQ',3qo_O?/v( fe HG *)
                    x
                      q(a'Q
A       0C      ΐ

௠
 #j$5 %J& '*'))6 "S      54+ !"V
eGYe턠g';gfiiHjke lmvG noV) pq6: XX YZ [޵\ ]^d _y`Mޠab-cgwdE G-Gӵ I                                      
                                ros tOt v8vxx͠yz{f|~}H~^s*&                                               
                                                         LMTPDTPSTPWTPPT                                 
PST8PDT,M3.2.0,M11.1.0

嗯。无论采用哪种方式,此TZ似乎都没有“人类友好”的名称。

更多地挖掘$ strings /usr/share/zoneinfo/America/Los_Angeles TZif2 v+ ! 2s$ 3Gt 4S 5'V 62 mvG n oV) p TZif2 v+ 3Gt 5'V mvG oV) PST8PDT,M11.1.0 格式,显然有unix tzinfozic工具

zdump

不是很有用...

$ zdump /usr/share/zoneinfo/America/Los_Angeles
/usr/share/zoneinfo/America/Los_Angeles  Thu Sep 10 03:07:49 2020 PDT 

gh。

但是阅读其中的一种工具的$ zic /usr/share/zoneinfo/America/Los_Angeles "/usr/share/zoneinfo/America/Los_Angeles",line 1: line too long 时,我发现manpages是官方的RFC8536。我不太擅长阅读这些,但是格式中有标头(带有版本)和

  • data block(将其签出,显然它存储了TZ的所有历史更改)
  • footer似乎包含PDT字符串等,并且未提及提供“友好”名称的可能性。

如果您在阅读RFC时遇到困难,似乎timezoneinfo gem会尝试为不包含tzinfo-data数据库(例如Windows)的系统重现相同的数据:

https://github.com/tzinfo/tzinfo-data/blob/4ab39f022f5537b97eed133c1169f9ace3a82e2b/lib/tzinfo/data/definitions/PST8PDT.rb

tzinfo

这里的 timezone 'America/Los_Angeles' do |tz| tz.offset :o0,-28378,:LMT tz.offset :o1,-28800,:PST tz.offset :o2,3600,:PDT tz.offset :o3,:PWT tz.offset :o4,:PPT tz.transition 1883,11,:o1,-2717640000,7227400,3 tz.transition 1918,3,:o2,-1633269600,29060207,12 tz.transition 1918,10,-1615129200,19375151,8 tz.transition 1919,-1601820000,29064575,12 tz.transition 1919,-1583679600,19378063,8 tz.transition 1942,2,:o3,-880207200,29164799,12 # ... [cut!] 方法定义为:https://github.com/tzinfo/tzinfo/blob/f361d7d0b859ba5b91d30ffd6b66c3c59f90e969/lib/tzinfo/format2/timezone_definer.rb#L37:L59(至少我认为是这样,直到在ruby中运行代码之前,您才知道)

如您所见,夏令时没有offset:LMT的缩写。

这是:PST方法https://github.com/tzinfo/tzinfo/blob/8c549373736a7873e18bb787b818d8786591e5e5/lib/tzinfo/format1/timezone_definer.rb#L30:L61

随时自行探索更多内容。但是,看来transition中存在从DST到DST的每个过渡。而且洛杉矶似乎已经计划了2060年之前的工作。如果您尝试计算2060年之后的时间,是否会遇到与DST相关的TZ错误,这真的很有趣吗?

最后一点:缩写

不知道tzinfo的{​​{1}}数据库是否是这种情况,但是在gem中它们是在本地定义的!

如果所有定义(https://github.com/tzinfo/tzinfo-data/search?q=%3APDT&unscoped_q=%3APDT)都unix的含义相同

但是请注意

  • lib / tzinfo / data / definitions / Asia / Manila.rb定义正偏移量tzinfo,但
  • lib / tzinfo / data / definitions / America / Dawson.rb用相同的缩写定义负偏移量:PDT

这是什么意思-不知道。但这可能就是我们在任何地方都没有“全球友好时区名称”的原因。

数据库中可能存在错误。 official DB自述文件说:

此历史本地时间信息数据库具有以下目标:

  • 提供有关民事时间历史的数据摘要, 即使不是100%准确,也很有用。

  • 了解现有的各种本地时间规则 在过去,因此可能在未来。

  • 测试本地时间规则描述系统的普遍性。

时区数据文件中的信息绝对不是权威的; 修复和增强功能是受欢迎的。请查看文件CONTRIBUTING 有关详细信息。

,

我认为没有缩写的标准。此外,它们也不是唯一的,如您在此处看到的:https://www.timeanddate.com/time/zones/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。