如果TimeZone.getTimeZone()方法给出的时区 ID 无效,为什么它不会抛出错误?相反,它返回“如果无法理解给定 ID,则返回 GMT 区域”。这个决定背后的理由是什么?
3 回答
I'm not sure of the rationale, but they did provide you with a getAvailableIDs()
method to allow you to ensure your timezone is vaild. They do mention this in the javadoc:
You can use the getAvailableIDs method to iterate through all the supported time zone IDs. You can then choose a supported ID to get a TimeZone. If the time zone you want is not represented by one of the supported IDs, then a custom time zone ID can be specified to produce a TimeZone
造成这种情况和 Java 类似问题的一个原因(必须特别注意避免依赖系统的默认语言环境、字符集和时区,以便在读取文本文件或写入文本文件失败时出现异常,因为磁盘已满等)可能是Java 最初应用于编程用户界面,而不是服务器后端:在 UI 中,显示错误输出可能比完全失败更好,因为用户通常可以找出错误并解释现有的正确输出。尽管如此,我认为省略异常TimeZone.getTimeZone(String)
是一个设计错误。
无论如何,现在有新的更好的 API 可用。获取时区的现代方法(从 Java 8 开始)是
TimeZone.getTimeZone(ZoneId.of(zoneId));
这确实会为无效的区域 ID 引发异常。接受的区域 ID 格式与ZoneId.of(String)
的不完全相同TimeZone.getTimeZone(String)
,但正如JavadocZoneId.of(String)
所说,大多数区域 ID 都是兼容的。
基于@Jaan 的回答建议使用ZoneId.of()
. 这是一种避免 ZoneId 的 ID 与 TimeZone 的 ID 不完全相同这一事实的方法:首先用于TimeZone.getAvailableIDs()
检查提供的时区 ID 是否为“Europe/Rome”之类的字符串,然后使用 ZoneId.of()如果是固定偏移ID,否则无效。
/* Returns null if the timezoneID is invalid */
private static TimeZone getTimeZone(String timezoneID) {
final String[] availableTimezoneIDs = TimeZone.getAvailableIDs();
if ( ! Arrays.asList(availableTimezoneIDs).contains(timezoneID) ) {
// Unknown timezone ID, maybe a fixed offset timezone id?
if (timezoneID.equals("Z") ||
timezoneID.startsWith("+") || timezoneID.startsWith("-") ||
timezoneID.startsWith("UTC") || timezoneID.startsWith("UT") || timezoneID.startsWith("GMT")
) {
try {
return TimeZone.getTimeZone(ZoneId.of(timezoneID));
} catch (DateTimeException e) {
// Invalid fixed-offset timezone id
return null;
}
} else
// Not even a fixed offset timezone id
return null;
} else
return TimeZone.getTimeZone(timezoneID);
}