我正在使用这个简单的代码来获取系统中已设置的当前时区的时区 ID。
public class Main {
public static void main(String[] args)
{ TimeZone timezone = TimeZone.getDefault();
System.out.println(timezone.getID());
}
}
我使用 tzutil/g 来确定时区,并使用 tzutil/s 来设置时区。
我观察到,当时区设置为东部标准时间时,上述代码返回 id 为America/New_York
,但当它设置为东部标准时间_dstoff时> 然后我得到的 id 为 GMT-05:00
这是不受欢迎的。我想要大陆/城市形式的输出。
我怎样才能得到它?
最佳答案
我的第一个答案是,你不应该关心 JVM 的默认时区设置。无论如何,您的 Java 代码都不应该依赖它。默认设置可以随时从程序的另一部分或同一 JVM 中运行的另一个程序更改,因此很脆弱。相反,请在时区敏感操作中指定明确的时区。
如果您仍然想依赖默认值,可以通过以下技巧将其设置为某个大陆/城市时区(如果恰好是GMT-05:00
)您认为不受欢迎的。
ZoneId defaultZoneId = ZoneId.systemDefault();
ZoneId desiredTimeZone = null;
if (defaultZoneId.equals(ZoneId.of("GMT-05:00"))) {
// Pick a date in summer
LocalDate dateInSummer = Year.now().atMonthDay(MonthDay.of(Month.JULY, 7));
DateTimeFormatter zoneFormatter = DateTimeFormatter.ofPattern("zzzz", Locale.ENGLISH);
for (String zid : ZoneId.getAvailableZoneIds()) {
ZoneId zone = ZoneId.of(zid);
String timeZoneName = dateInSummer.atStartOfDay(zone).format(zoneFormatter);
if (zid.startsWith("America/") && timeZoneName.equals("Eastern Standard Time")) {
desiredTimeZone = zone;
break;
}
}
}
System.out.println("Time zone: " + desiredTimeZone);
在我的 JDK 11 上,我得到了:
Time zone: America/Panama
不幸的是,要将其设置为默认值,我们必须经历设计不佳且早已过时的 TimeZone
类:
TimeZone.setDefault(TimeZone.getTimeZone(desiredTimeZone));
还有一个原因警告不要使用美洲/巴拿马或其他时区 ID 而不是 GMT-05:00:虽然巴拿马自 1908 年的某个时间以来一直使用 GMT/UTC 的偏移量 -05:00,但并不总是如此,因此对于历史日期,您会使用它得到错误的时间。
根据 timeanddate.com,全年使用东部标准时间(无夏令时/DST)的地方是:
- 努勒维特 - 仅限南安普敦岛(珊瑚港)(加拿大)(America/Coral_Harbour 时区)
- 金塔纳罗奥州(墨西哥)(美国/坎昆时区)
- 开曼群岛(美洲/开曼)
- 牙买加(美国/牙买加)
- 巴拿马(美洲/巴拿马)
我的 Java 还列出了 America/Atikokan(也在加拿大)。
该列表不包括美国的任何地点。我相信以上都没有一直使用偏移量 -05:00
。也就是说,它们中的每一个在历史上的某个时刻都有不同的偏移量,Java 将为历史日期使用该不同的偏移量。
那么使用哪个时区?
编辑:Andreas 在评论中指出,Etc/GMT+5 和 SystemV/EST5 都没有我提到的将偏移量应用于可能意外的历史日期的问题。所以你可以考虑其中之一。在我看来,它们各自的优点是:
America/Xxx Etc/GMT+5 SystemV/EST5 GMT-05:00
Official IANA time zone? Yes Yes
With slash? Yes Yes Yes
Continent/city? Yes
Good for historical dates? Yes Yes Yes
Prints as EST/Eastern Standard Time? Yes Yes
(您的起点 GMT-05:00 仅用于比较。当然,哪些确实适合历史日期取决于您对这些日期的要求。)
链接
关于java - Java中的时区问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60236559/