如何从过时的 TZInfo 标识符中获取 Rails 时区名称



已经有一个问题回答了如何将"美国/Los_Angeles"转换为"太平洋时间(美国和加拿大)"。但是,我想将"美国/太平洋"和其他过时的时区转换为Rails时区。我在图书馆中找不到任何帮助我完成此操作的内容。

来自 Rails ActiveSupport::TimeZone docs:

与主动支持捆绑在一起的 TZInfo 版本仅包含支持时区类定义的区域所需的定义。如果需要使用时区未定义的区域,则需要安装 TZInfo gem(如果本地安装了最新版本的 gem,则将使用此 gem 而不是捆绑版本。

就我个人而言,我认为Rails时区是愚蠢的。 它们被任意限制在Rails所描述的"146个区域中有意义的子集"。 但他们没有解释他们如何确定哪些区域是"有意义的",哪些区域被丢弃。

诸如"美国/太平洋"之类的标识符在TZDB数据中称为"链接"或"别名"。 我可以看到,也许它们可能会从 Rails 中省略,但还有许多其他现实世界的时区完全缺失。

我在现实世界中看到的唯一一个Rails时区标识符的地方是在Twitter API中。 另一方面,IANA/TZDB 标识符无处不在。

我能提供的最好的建议是忘记 Rails 时区,直接使用 Ruby TZInfo Gem。 它具有包含所有区域(包括别名)的完整 TZDB 实现。

如果你真的必须继续使用 Rails 区域,你可以先使用 TZInfo 将别名解析为实际区域,然后查看该区域是否在 Rails MAPPING字典中。 例如:

"US/Pacific" => "America/Los_Angeles"                    (via TZInfo)
"America/Los_Angeles" => "Pacific Time (US & Canada)"    (via Rails MAPPING)

我相信当您通过 TZInfo 加载"US/太平洋"时,它将被子类化为LinkedTimezoneInfo对象,因此您可以从那里使用 link_to_identifier 属性。

你可以这样做:

arr = TZInfo::Timezone.all_country_zone_identifiers.collect { |x| x + " " + ActiveSupport::TimeZone[x].formatted_offset }
arr.sort

在此命令中将显示 144 个时区名称。

活动支持::TimeZone.zones_map

最新更新