我找不到任何具体的文档来回答这个问题。
我写了一些简单的测试代码来弄清楚在 OS X 10.12 上的 Java 1.8 上实际发生了什么:
public static void main(String[] _args) throws InterruptedException {
while (true) {
int calendarTimezoneOffset = Calendar.getInstance().get(Calendar.ZONE_OFFSET);
System.out.println("calendarTimezoneOffset = " + calendarTimezoneOffset);
ZoneOffset offset = ZonedDateTime.now().getOffset();
System.out.println("offset = " + offset);
Thread.sleep(1000);
}
}
旧方法(日历)和新方法(Java 8 的日期和时间库)都没有检测到我在 JVM 运行时对操作系统时区所做的任何更改。我需要停止并启动代码以获取更改后的时区。
这是设计使然吗?这种跨 JVM 实现和操作系统的行为是否可靠?
最佳答案
TimeZone.getDefault()
规范非常清楚它是如何获取时区的:
Gets the default TimeZone of the Java virtual machine. If the cached default TimeZone is available, its clone is returned. Otherwise, the method takes the following steps to determine the default time zone.
- Use the user.timezone property value as the default time zone ID if it's available.
- Detect the platform time zone ID. The source of the platform time zone and ID mapping may vary with implementation.
- Use GMT as the last resort if the given or detected time zone ID is unknown.
The default TimeZone created from the ID is cached, and its clone is returned. The user.timezone property value is set to the ID upon return.
文档指出该区域是缓存;此方法受 user.timezone 系统属性的影响,反之亦然。
规范还说缓存由 TimeZone.setDefault(null)
清除:
If zone is null, the cached default TimeZone is cleared.
也就是说,为了重新读取系统时区,你必须
- 通过调用
TimeZone.setDefault(null)
清除 TimeZone 缓存; - 通过调用
System.clearProperty("user.timezone"); 清除
user.timezone
系统属性;
尝试以下测试:
while (true) {
TimeZone.setDefault(null);
System.clearProperty("user.timezone");
System.out.println("Offset = " + TimeZone.getDefault().getRawOffset() / 3600);
System.out.println("Zone ID = " + System.getProperty("user.timezone"));
Thread.sleep(1000);
}
关于java - 正在运行的 JVM 是否检测到计算机时区的更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38913669/