不推荐使用哪个三个字母的时区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的最小集合是GMT
和CET
; 但似乎很奇怪,没有记录。 有任何想法吗?
我注意到@shmosel建议的可能重复: “GMT”是Java TimeZone中的缩写,是否可以使用它? 。 这部分涵盖了我的问题; 但我问更一般的问题“支持什么(以及我们如何知道)”,而不仅仅是“支持X”。
首先,回答您的具体问题:
-
所有基于缩写的标识符都应被视为已弃用。 它们不足以识别保留所有细节的特定时区。 例如,您可以在此处查看使用中欧时间的所有位置。 他们中的一些人整年都使用
CET
,其中一些人在冬天使用CET
,而在夏天使用CEST
。 其中,并非所有人都使用相同的DST过渡日,或者在他们的历史中具有相同的时区偏移。CET
没有足够的信息来决定使用哪组规则。 -
使用
GMT
或UTC
是相对安全的,因为这些是明确的。 然而,使用Etc/GMT
或Etc/UTC
会更正确。 如果你只挑选一个,恕我直言,它应该是Etc/UTC
。 -
正如我所提到的,
CET
应该被视为已弃用,以及其他缩写。 但是,值得注意的是, 一些缩写(如CET
)来自TZ数据库,而一些(如AST
)则来自Java的遗留。 这种区别很重要,因为只有TZDB才能用于可能在其他地方传输并由非基于Java的系统解释的数据。特别值得注意的是,认识到美国缩写
PST
和CST
不在TZDB中,即使MST
和EST
是 。 -
您应该选择与您的方案相关的基于位置的时区,而不是
CET
。 如果您正在谈论法国,请使用Europe/Paris
。 如果你在谈论波兰,请使用Europe/Warsaw
等。
接下来,要了解底层TZ数据库有几种可以使用的标识符:
-
位置,以
Area/Locality
的forms- 例如:
America/New_York
,Europe/London
,Pacific/Honolulu
- 例如:
-
位置,以
Area/Region/Locality
的forms- 例如:
America/Argentina/Buenos_Aires
,America/Indiana/Knox
- 例如:
-
管理区域,在
Etc
名称空间中:- 例如:
Etc/UTC
,Etc/GMT+2
,Etc/GMT-5
- +/-基于POSIX标准,与通常预期的ISO标准相反
- 常用于海上船舶
- 例如:
它还有几种forms是历史的工件,不应再使用:
-
位置,以
Country
或Country/StateOrRegion
或Country/StateOrRegion
的forms- 例如:
US/Pacific
,US/Hawaii
,Brazil/East
,Canada/Newfoundland
,Egypt
,Cuba
- 例如:
-
美国大陆的POSIX标识符:
- 例如:
EST5EDT
,CST6CDT
,MST7MDT
,PST8PDT
- 例如:
-
缩写 – 无论如何其中一些
- 例如:
EST
,EET
,PRC
,WET
- 例如:
此外,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