下面这行代码为什么输出是false?我认为它应该输出true。
TimeZone.getTimeZone("UTC+5:30").hasSameRules(TimeZone.getTimeZone("GMT+5:30")
答案在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" 时区明显不同。
null
可能更好,因为这样可以让调用者决定在这种情况下该做什么。 - ThiloTimeZone
在这一点上的糟糕设计,它的现代替代品 ZoneId
在这种情况下确实会抛出异常。我强烈推荐使用 java.time
,即现代Java日期和时间API,而不是旧的日期和时间类,包括 TimeZone
。 - Ole V.V.因为您位于印度,因此应使用
ZoneId india = ZoneId.of("Asia/Kolkata");
两条信息:
TimeZone
类存在设计问题,已经过时。它的相关类似 Calender
和 SimpleDateFormat
也是如此。因此不要使用它们,而应该使用现代的 Java 日期和时间 API:java.time。它替代 TimeZone
的是 ZoneId
类(如果需要表示与 UTC 的偏移量,则使用 ZoneOffset
类,但不要将其作为时区使用,因为它不是一个真正的时区,这将在下一条里解释)。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
。