不推荐使用哪个三个字母的时区ID?

TimeZone的Javadoc中有一个弃用警告:

为了与JDK 1.1.x兼容,还支持其他一些三字母时区ID(例如“PST”,“CTT”,“AST”)。 但是,它们的使用已被弃用……

它在这里说“其他”,但我看不清它在哪里定义哪些三字母ID不被弃用。 这些记录在哪里?

GMT在文档中被称为后备,因此可以安全地假设这是一个非弃用的ID; 但:

  • 是否弃用了UTC ? 您是否打算使用Etc/UTC ? 或者你应该使用GMT ? ( TimeZone.getTimeZone("UTC").hasSameRules(TimeZone.getTimeZone("GMT")为真)
  • CET (中欧时间)是否被弃用? 如果没有,您应该使用什么时区标识符? 根据这个演示 ,只有一个其他标识符产生相同的规则,即MET (中欧时间)。

    还有另一个时区ID, ECT ,它的显示名称与CET (中欧时间)相同,但它没有相同的规则(我认为它们在20世纪70年代中期有所不同),其规则与Europe/Paris相同Europe/Paris 。 但是,由于他们有不同的规则,这两者是不可互换的。

因此,我的结论是,支持的三字母ID的最小集合是GMTCET ; 但似乎很奇怪,没有记录。 有任何想法吗?


我注意到@shmosel建议的可能重复: “GMT”是Java TimeZone中的缩写,是否可以使用它? 。 这部分涵盖了我的问题; 但我问更一般的问题“支持什么(以及我们如何知道)”,而不仅仅是“支持X”。

首先,回答您的具体问题:

  1. 所有基于缩写的标识符都应被视为已弃用。 它们不足以识别保留所有细节的特定时区。 例如,您可以在此处查看使用中欧时间的所有位置。 他们中的一些人整年都使用CET ,其中一些人在冬天使用CET ,而在夏天使用CEST 。 其中,并非所有人都使用相同的DST过渡日,或者在他们的历史中具有相同的时区偏移。 CET没有足够的信息来决定使用哪组规则。

  2. 使用GMTUTC是相对安全的,因为这些是明确的。 然而,使用Etc/GMTEtc/UTC会更正确。 如果你只挑选一个,恕我直言,它应该是Etc/UTC

  3. 正如我所提到的, CET应该被视为已弃用,以及其他缩写。 但是,值得注意的是, 一些缩写(如CET )来自TZ数据库,而一些(如AST )则来自Java的遗留。 这种区别很重要,因为只有TZDB才能用于可能在其他地方传输并由非基于Java的系统解释的数据。

    特别值得注意的是,认识到美国缩写PSTCST不在TZDB中,即使MSTEST

  4. 您应该选择与您的方案相关的基于位置的时区,而不是CET 。 如果您正在谈论法国,请使用Europe/Paris 。 如果你在谈论波兰,请使用Europe/Warsaw等。

接下来,要了解底层TZ数据库有几种可以使用的标识符:

  • 位置,以Area/Locality的forms

    • 例如: America/New_YorkEurope/LondonPacific/Honolulu
  • 位置,以Area/Region/Locality的forms

    • 例如: America/Argentina/Buenos_AiresAmerica/Indiana/Knox
  • 管理区域,在Etc名称空间中:

    • 例如: Etc/UTCEtc/GMT+2Etc/GMT-5
    • +/-基于POSIX标准,与通常预期的ISO标准相反
    • 常用于海上船舶

它还有几种forms是历史的工件,不应再使用:

  • 位置,以CountryCountry/StateOrRegionCountry/StateOrRegion的forms

    • 例如: US/PacificUS/HawaiiBrazil/EastCanada/NewfoundlandEgyptCuba
  • 美国大陆的POSIX标识符:

    • 例如: EST5EDTCST6CDTMST7MDTPST8PDT
  • 缩写 – 无论如何其中一些

    • 例如: ESTEETPRCWET

此外,Java之前已将这些标识符扩展为包含属于TZ数据库的其他缩写。 我能够在这里找到它们,作为其相应的TZ数据库现代标识符的链接:

 Link Australia/Darwin ACT Link Australia/Sydney AET Link America/Argentina/Buenos_Aires AGT Link Africa/Cairo ART Link America/Anchorage AST Link America/Sao_Paulo BET Link Asia/Dhaka BST Link Africa/Harare CAT Link America/St_Johns CNT Link America/Chicago CST Link Asia/Shanghai CTT Link Africa/Addis_Ababa EAT Link Europe/Paris ECT Link America/New_York EST Link Pacific/Honolulu HST Link America/Indianapolis IET Link Asia/Calcutta IST Link Asia/Tokyo JST Link Pacific/Apia MIT Link America/Denver MST Link Asia/Yerevan NET Link Pacific/Auckland NST Link Asia/Karachi PLT Link America/Phoenix PNT Link America/Puerto_Rico PRT Link America/Los_Angeles PST Link Pacific/Guadalcanal SST Link Asia/Saigon VST 

当然,这些映射可能也可能没有意见 – 但据报道它们是Java的TZUpdater工具用来inheritance对这些遗留Java时区缩写的支持。

也许ZoneId可以用作参考。

 ZoneId.getAvailableZoneIds().stream() .filter(z -> z.length() == 3) .forEach(System.out::println); 

产量

 GMT CET UTC ROK MET PRC WET UCT EET 

如果你调用ZoneId.of("CST")它会抛出

 java.time.zone.ZoneRulesException: Unknown time-zone ID: CST