【发布时间】:2019-04-19 06:54:44
【问题描述】:
为什么下面的行打印错误?我认为它应该打印为 true。
TimeZone.getTimeZone("UTC+5:30").hasSameRules(TimeZone.getTimeZone("GMT+5:30")
【问题讨论】:
-
注意 UTC 有 Java 不支持的闰秒,所以它实际上只是 GMT。
为什么下面的行打印错误?我认为它应该打印为 true。
TimeZone.getTimeZone("UTC+5:30").hasSameRules(TimeZone.getTimeZone("GMT+5:30")
【问题讨论】:
答案在JavaDoc of TimeZone#getTimeZone:
TimeZone 的 ID,可以是“PST”等缩写、“America/Los_Angeles”等全名或“GMT-8:00”等自定义 ID
返回: 指定的时区,如果无法理解给定的 ID,则为 GMT 时区。
和(来自class documentation)
[...] 自定义时区 ID 的语法是:
CustomID:
GMT Sign Hours : Minutes
GMT Sign Hours Minutes
GMT Sign Hours
ID "UTC+5:30" 不是有效的 TimeZone ID(根据方法/类的规范)并被解释为“GMT”区域,与“GMT+5:30”区域明显不同。
【讨论】:
null 可能会更好,因为它可以让调用者决定在这种情况下要做什么。
TimeZone 在这一点上的糟糕设计,它的现代替代品 ZoneId 在这种情况下确实会引发异常。我强烈建议在旧的日期和时间类(包括 TimeZone)上使用 java.time, the modern Java date and time API,。
由于您位于印度,因此您应该使用
ZoneId india = ZoneId.of("Asia/Kolkata");
两条消息:
TimeZone 类存在设计问题并且早已过时。像Calender 和SimpleDateFormat 这样的朋友也是如此。所以不要使用它们。而是使用 java.time,现代 Java 日期和时间 API。 TimeZone 的替代品是 ZoneId 类(ZoneOffset 是与 UTC 的偏移量,但不要将其用作时区,它不是时区,请参阅下一项)。Asia/Kolkata 清楚地传达了这一点。此外,Asia/Kolkata 是面向未来的,以防政治家在某个时间点更改印度的 UTC 偏移量或引入夏令时 (DST)。虽然这在印度不太可能发生,但在世界其他地方一直都在发生,因此最好养成始终使用 region/city 格式的习惯。要想了解现代 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 tutorial: Date Time解释如何使用java.time。
【讨论】: