我想您已经阅读了 cmets 说明这是多么(几乎)不可能以及多么脆弱。无论如何,我都敢于提出一些建设性的建议。
首先,您当然可以专门处理 GMT 和 UTC,因为它们的解释是相当安全的,您可能希望确保它们得到处理。
我认为,接下来最安全的做法有点复杂:试试ZoneId.of(yourNonIanaTimeZoneId)。这要么给你一个ZoneId,要么抛出一个异常(根据我的经验,通常是一个ZoneRulesException,但根据文档,它也可能抛出一些其他的DateTimeException)。它给了我一个ZoneId GMT,但既不是PLT、IST 也不是NET。例如,它确实为EET 提供了ZoneId。如果你有一个ZoneId,你还没有走多远,因为它的 ID 就是你给的 ID。您现在可以搜索ZoneId.getAvailableZoneIds() 以查看是否可以找到具有 IANA 名称和相同区域规则的区域。您只需要知道如何识别 IANA 名称;我认为它至少应该有一个斜线。
接下来要尝试的事情,请在 ZoneId.SHORT_IDS 中查找。例如,所有PLT、IST 和NET 都在那里。它们被翻译成亚洲/卡拉奇、亚洲/加尔各答和亚洲/埃里温。如果你想要,比如说,爱尔兰夏令时,那你就大错特错了。此外,SHORT_IDS 并不总是会给您一个 IANA 名称,但有时只是像 -05:00 这样的偏移量,这并不能真正让您获得任何帮助。对于执行此操作的三个条目,您可以对自己的转换进行硬编码,例如:
- EST = 美国/纽约
- HST = 太平洋/檀香山
- MST = 美国/丹佛
同样,如果您想要澳大利亚东部标准时间(也称为 AEST 或 AET)的 EST,那您就错了。你会一遍又一遍地遇到这些模棱两可的问题。
您在评论中询问是否可以使用TimeZone.getAvailableIDs()。你可以,但它不会给你任何你从上面没有得到的东西。就我而言,我更喜欢使用现代类ZoneId,而不是过时的TimeZone。在 Java 8 中,他们将短 ID(已弃用)取出到 ZoneId.SHORT_IDS 中,并将所有其他 ID 包含在 ZoneId.getAvailableZoneIds() 中。所以TimeZone.getAvailableIDs() 的每个 ID 都在 ZoneId.getAvailableZoneIds() 或 ZoneId.SHORT_IDS 中。
我的最后一个建议,我认为它很脏,可能无法满足您的需求:
SimpleDateFormat sdf = new SimpleDateFormat("z");
sdf.parse(yourNonIanaTimeZoneId);
String ianaName = sdf.getTimeZone().getID();
我正在使用早已过时的SimpleDateFormat 类,所以我对此不太满意。对于 PLT 和 NET,它会抛出 ParseException。对于 GMT,它只是给了我 JVM 的默认时区!对于 IST,我得到了亚洲/耶路撒冷,所以如果你更喜欢亚洲/加尔各答?但是,一些以前的方法无法处理的缩写现在被转换了,例如:
- 美国东部标准时间到美国/纽约
- EET(东欧时间)到欧洲/布加勒斯特
- WET(西欧时间)至非洲/卡萨布兰卡
我不保证转换的质量,尤其是最后一个在我眼里看起来很吓人。
使用风险自负! :-)