4

我正在针对一个外部 API 进行编码,该 API 将似乎是 Windows 时区描述的内容返回为字符串,例如“浪漫标准时间”,我需要将这些解析为 javaZoneId或偏移量。此处提供了这些值的列表。

java.time.ZoneId文档指出:

时区规则由政府定义并经常更改。有许多组织(这里称为组)监控时区变化并对其进行整理。默认组是 IANA 时区数据库 (TZDB)。其他组织包括 IATA(航空业机构)和 Microsoft

所以我的问题是,是否存在java.time.zone.ZoneRulesProviderjavadoc 中提到的 Microsoft 的公共实现?

我知道 Microsoft 时区和标准 IANA TZDB 之间存在关系,例如参见这个问题。但我想知道的是是否存在ZoneRulesProvider我可以作为属性传入的标准实现,如javadoc中所述:

如果定义了系统属性 java.time.zone.DefaultZoneRulesProvider,则它被视为要作为默认提供程序加载的具体 ZoneRulesProvider 类的完全限定名称,使用系统类加载器。

4

2 回答 2

6

Java 文档是正确的,IANA、IATA 和 Microsoft 是时区信息的来源。但是,尽管可以ZoneRulesProvider为每个创建一个 a,但据我所知,我认为ZoneRulesProvider除了 IANA 数据之外没有任何标准实现。如果有人愿意的话,可能会写一篇。

不过有一个合理的解决方案。正如您提到的另一个问题,IANA 和 Microsoft 之间的时区映射是通过Unicode CLDR 中的 windowsZones.xml 文件维护的。您可以使用此数据将外部 API 返回的 Microsoft 时区 ID 转换为 IANA 时区名称。您可以直接使用它,也可以依赖为您提供此功能的库。一个好的库选择是International Components for Unicode (ICU),通过项目页面上的ICU4J实现。它的方法(此处的文档)使用 CLDR 数据来提供翻译。getIDForWindowsID

或者,如果您对外部 API 有任何影响,则很有可能它返回的是使用 .NET 构建的 Microsoft 时区 ID。如果是这样,您可以鼓励该 API 的开发人员在其 API 结果中返回标准 IANA 时区 ID(如果他们担心兼容性,可能作为辅助字段)。我的开源TimeZoneConverter库适用于此目的,并且也使用相同的 CLDR 数据。

请注意 IANA 时区 ID 已经在 Microsoft 的多个领域中使用,包括 Linux/MacOS 上的 .NET Core、通过诸如 Noda Time 等库的 .NET Framework、通用 Windows 平台 (UWP) 应用程序等。“Microsoft 时区”是历史的产物,可以追溯到 Windows NT 的早期。通常应鼓励开发人员使用 IANA 时区 ID,而不是 Microsoft 时区,尤其是在面向外部的 API 中以实现与非 Windows 系统的互操作性。更多关于 Microsoft 时区的信息可以在时区标签 wiki中找到。

另外 - 请注意,您链接到 Microsoft 时区列表的页面已有近十年的历史,并且是出于遗留目的。索引列只在 Windows CE 平台上使用过,其中几个时区不再存在。我们不再将这些时区的列表发布为静态网页,因为数据变化太频繁。您始终可以通过命令从任何 Windows 计算机获取列表TZUTIL /L​​,或者通过调用TimeZoneInfo.GetSystemTimeZones().NET 或 Powershell,或者通过检查位于 .NET 的注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

全面披露:我帮助维护 Microsoft 的时区,以及 .NET 的几个开源时区库。

于 2018-10-17T17:37:14.767 回答
1

我发现这些线程与您的问题相关,尽管这些问题本身似乎并不相关。这些问题的公认答案可能会阐明您的问题:

使用新的 java.time API 解析时区非常慢

Java 没有关于所有 IANA 时区的信息

将 ZoneRulesProvider 子类化并提供您的自定义实现似乎是个好主意...

对于您的问题,我尝试在线搜索并没有找到微软的 ZoneRulesProvider 实现......

于 2018-10-17T15:18:11.643 回答