为什么GMT和UTC时区规则不同?

8
下面这行代码为什么输出是false?我认为它应该输出true。
TimeZone.getTimeZone("UTC+5:30").hasSameRules(TimeZone.getTimeZone("GMT+5:30")

请注意,UTC 有闰秒,而 Java 不支持,因此实际上它只是 GMT。 - Peter Lawrey
2个回答

8

答案在TimeZone#getTimeZone的JavaDoc中:

时区的ID,可以是缩写(例如“PST”),全名(例如“America/Los_Angeles”)或自定义ID(例如“GMT-8:00”)

返回值:指定的时区,如果给定的ID无法理解,则为GMT区。

另外(来自类文档

[...] 自定义时区ID的语法如下:

  CustomID:
     GMT Sign Hours : Minutes
     GMT Sign Hours Minutes
     GMT Sign Hours

ID "UTC+5:30" 不是有效的时区ID(根据方法/类的规范),被解释为 "GMT" 时区,与 "GMT+5:30" 时区明显不同。


2
返回 GMT 作为无效输入的设计选择有点奇怪。抛出异常或返回 null 可能更好,因为这样可以让调用者决定在这种情况下该做什么。 - Thilo
3
@Thilo,你说得没错。考虑到 TimeZone 在这一点上的糟糕设计,它的现代替代品 ZoneId 在这种情况下确实会抛出异常。我强烈推荐使用 java.time,即现代Java日期和时间API,而不是旧的日期和时间类,包括 TimeZone - Ole V.V.

3

因为您位于印度,因此应使用

    ZoneId india = ZoneId.of("Asia/Kolkata");

两条信息:

  1. TimeZone 类存在设计问题,已经过时。它的相关类似 CalenderSimpleDateFormat 也是如此。因此不要使用它们,而应该使用现代的 Java 日期和时间 API:java.time。它替代 TimeZone 的是 ZoneId 类(如果需要表示与 UTC 的偏移量,则使用 ZoneOffset 类,但不要将其作为时区使用,因为它不是一个真正的时区,这将在下一条里解释)。
  2. 不要将与 UTC 或 GMT 的偏移量作为时区来使用。当然,在特定的情况下可能可行,但这样可能会让读者想知道为什么你选择了 +05:30,而 Asia/Kolkata 显然更能清晰表达。此外,Asia/Kolkata 在未来也能兼容政治家们改变印度的 UTC 偏移量或引入夏令时(DST)的情况。虽然这对印度来说不太可能,但在世界其他地方这种情况经常发生,因此最好养成始终使用“地区/城市”格式的习惯。

试试使用现代 API 的一个设计优势,尝试使用现代化版本的你的代码:

    ZoneId.of("UTC+5:30").getRules().equals(ZoneId.of("GMT+5:30").getRules())

这会抛出异常:java.time.DateTimeException: Invalid ID for offset-based ZoneId: UTC+5:30。从一开始就知道问题在哪里了:UTC+5:30 不是一个有效的时区ID。 链接:Oracle 教程:日期时间,解释如何使用 java.time

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接