Instant.EPOCH的Java 8时区不正确

Mir*_*cle 5 java timezone timezone-offset java-8

我有一台Linux机器,其时区设置为Asia / Qatar。当我使用格式化程序打印Instant.EPOCH时,它给我错误的区域信息,而对于Instant.now(),区域信息是正确的。下面是我的代码及其输出。谁能帮我,为什么会有这个差异?

import java.util.Date;
import java.time.format.DateTimeFormatter;
import java.time.Instant;
import java.time.ZoneId;

public class DateTest {
   public static void main(String[] args) {
      String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS Z";
      Instant myInstant = Instant.EPOCH;
      Instant myInstantNow = Instant.now();
      DateTimeFormatter formatter =  DateTimeFormatter.ofPattern(pattern).withZone(ZoneId.systemDefault());
      System.out.println(formatter.format(myInstant));
      System.out.println(formatter.format(myInstantNow));
   }
}
Run Code Online (Sandbox Code Playgroud)

代码的输出为:

1970-01-01T04:00:00.000 +0400
2019-09-29T18:30:14.766 +0300
Run Code Online (Sandbox Code Playgroud)

Java版本:“ 1.8.0_181”

如果我在Windows中运行相同的代码,它的工作正常。我的Instant.EPOCH也得到+0300。

Ole*_*.V. 7

TL; DR:您从Linux获得的结果是正确的,符合预期。

1970年,卡塔尔偏离格林尼治标准时间+04:00。纪元是1970年1月1日。1972年,卡塔尔从偏移+04:00更改为+03:00。资料来源:卡塔尔多哈的时区(Ad Dawhah),在时区更改为:下拉列表中选择1970–1979。

那么,在Windows计算机上出了什么问题?我的猜测是:在Windows文档中阅读默认时区的方式中,Windows在Windows中没有提供亚洲/卡塔尔时区作为设置。因此,我的猜测是,根据我刚刚链接到的表,您的Windows已设置为“ 阿拉伯标准时间”,这反过来转换为UTC + 03:00。例如,科威特,伊拉克和也门也使用阿拉伯标准时间(或阿拉伯标准时间;简称AST)。但是这些国家自1970年及之前以来一直处于+03:00偏移。因此,当Java尝试从Windows获取默认时区时,它很容易获得具有此历史记录的时区,而不是卡塔尔的正确历史记录。就像我说的那样,现在只是猜测。但是您可以轻松地进行验证。在Windows计算机上,尝试:

    System.out.println(ZoneId.systemDefault());
Run Code Online (Sandbox Code Playgroud)

如果可以打印Asia/Qatar,我的猜测是错误的。如果打印出类似的内容GMT+03:00,那我是对的。如果它打印其他内容,我可能会也可能不会。

编辑:几个其他链接:AST –阿拉伯标准时间(Standard Time)以科威特为例。多年来科威特市的时间变化告诉我们,科威特自1950年以来也一直偏移+03:00。

进一步编辑:感谢您确认Windows计算机上的Java将Asia / Riyadh打印为默认时区。自1947年以来,沙特阿拉伯利雅得(Riyadh)的偏移量一直是+03:00。这至少部分解释了为什么即使对于卡塔尔来说,这种偏移量也不正确,您还是得到了该偏移量。资源