如何在 java 中获取 IANA 格式的时区?

How to get timezones in IANA format in java?

我的时区不是 IANA 格式,例如 PLTISTGMTNET 等。如何将它们转换为 java 中的 IANA 格式,例如 Asia/KarachiAsia/KolkattaEtc/Greenwich

我已经尝试使用 TimeZone.getOffset() 的偏移值,但它仍然需要 IANA 格式。

我想您已经阅读了说明这是多么(几乎)不可能以及多么脆弱的评论。无论如何,我还是大胆提出一些建设性的建议。

首先,您当然可以专门处理 GMT 和 UTC,因为它们的解释相当安全,您可能希望确保它们得到处理。

我认为,下一个最安全的做法有点复杂:尝试 ZoneId.of(yourNonIanaTimeZoneId)。这要么给你一个 ZoneId,要么抛出一个异常(根据我的经验,通常是 ZoneRulesException,但根据文档,它也可能抛出其他一些 DateTimeException)。它给了我 GMT 的 ZoneId,但 PLTISTNET 都没有。例如,它确实为 EET 提供了 ZoneId。如果你有一个 ZoneId,你就没有走得太远,因为它的 ID 就是你给的 ID。您现在可以做的是搜索 ZoneId.getAvailableZoneIds() 以查看是否可以找到具有 IANA 名称和相同区域规则的区域。您只需要知道如何识别 IANA 名称;我认为它至少应该有一个斜杠。

接下来要尝试的是,在 ZoneId.SHORT_IDS 中查找。例如,所有 PLTISTNET 都在那里。它们被翻译成 Asia/Karachi、Asia/Kolkata 和 Asia/Yerevan。如果你想要,比如说,爱尔兰夏令时,那你就过得很糟糕。此外,SHORT_IDS 不会总是给你一个 IANA 名称,有时只是一个像 -05:00 这样的偏移量,这并不能真正让你到任何地方。对于执行此操作的三个条目,您可以对自己的转换进行硬编码,例如:

  • EST = America/New_York
  • HST = Pacific/Honolulu
  • MST = America/Denver

同样,如果对于 EST,您想要澳大利亚东部标准时间(也称为 AEST 或 AET),那您就错了。你会一遍又一遍地遇到这些歧义。

您在评论中询问是否可以使用 TimeZone.getAvailableIDs()。你可以,但它不会给你任何你从上面得不到的东西。就我而言,我宁愿使用现代的 class 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 class,所以我对此不是很满意。对于 PLT 和 NET,它会抛出 ParseException。对于 GMT,它只为我提供了 JVM 的默认时区!对于 IST,我得到了 Asia/Jerusalem,所以如果你更喜欢这个而不是 Asia/Kolkata?但是,一些以前的方法无法处理的缩写现在被转换了,例如:

  • EST 至 America/New_York
  • EET(东欧时间)到 Europe/Bucharest
  • WET(西欧时间)到 Africa/Casablanca

我不保证转换的质量,尤其是最后一个在我眼中看起来很恐怖。

使用风险自负! :-)