我有一台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));
}
}
代码的输出为:
1970-01-01T04:00:00.000 +0400
2019-09-29T18:30:14.766 +0300
Java版本:“1.8.0_181”
如果我在Windows中运行相同的代码,它的工作正常。我的Instant.EPOCH也得到+0300。
最佳答案
TL; DR:您从Linux获得的结果是正确的,符合预期。
1970年,卡塔尔偏离格林尼治标准时间+04:00。纪元是1970年1月1日。1972年,卡塔尔从偏移+04:00更改为+03:00。来源:在Time Zone in Doha, Qatar (Ad Dawhah)上,时区将更改为:下拉列表,选择1970–1979。
那么,在Windows计算机上出了什么问题?我的猜测是:在Windows文档中阅读Default Time Zones的方式,Windows在Windows中没有提供亚洲/卡塔尔时区作为设置。因此,我的猜测是,根据我刚刚链接的表,您的Windows已设置为“阿拉伯标准时间”,这反过来又转换为UTC + 03:00。阿拉伯标准时间(或阿拉伯标准时间;缩写为AST)也用于例如科威特,伊拉克和也门。但是这些国家自1970年及之前以来一直偏移+03:00。因此,当Java尝试从Windows获取默认时区时,它很容易获得具有此历史记录的时区,而不是卡塔尔的正确历史记录。就像我说的那样,这只是一个猜测。但是您可以轻松地进行验证。在Windows计算机上,尝试:
System.out.println(ZoneId.systemDefault());
如果输出
Asia/Qatar
,我的猜测是错误的。如果它显示类似GMT+03:00
的内容,那我是对的。如果它打印其他内容,我可能会也可能不会。编辑:几个其他链接:AST – Arabia Standard Time (Standard Time)给出科威特为例城市。 Time Changes in Kuwait City Over the Years通知我们,科威特自1950年以来也一直偏移+03:00。
进一步编辑:感谢您确认Windows计算机上的Java将Asia / Riyadh打印为默认时区。自1947年以来,沙特阿拉伯利雅得(Riyadh)的偏移量一直是+03:00。这至少部分解释了为什么即使对于卡塔尔来说,偏移量也不正确,您还是得到了偏移量。 Source