首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么ZonedDateTime和日历在2050年的时刻不一致?

为什么ZonedDateTime和日历在2050年的时刻不一致?
EN

Stack Overflow用户
提问于 2020-02-07 08:20:11
回答 1查看 203关注 0票数 9

考虑以下代码:

代码语言:javascript
复制
ZoneId zoneId = ZoneId.of("America/Los_Angeles");
long currMillis = 2530778400000L;
Instant curr = Instant.ofEpochMilli(currMillis);
LocalDateTime dt = LocalDateTime.ofInstant(curr, zoneId); //the local one just for completeness
ZonedDateTime zdt = ZonedDateTime.ofInstant(curr, zoneId);
Calendar calendar = GregorianCalendar.from(zdt);

System.out.println(String.format("%-30s %s", "java-8 LocalDateTime hour:", dt.toLocalTime().getHour()));
System.out.println(String.format("%-30s %s", "java-8 ZonedDateTime hour:", zdt.toLocalTime().getHour()));
System.out.println(String.format("%-30s %s", "Calendar hour:", calendar.get(Calendar.HOUR_OF_DAY)));

印刷:

代码语言:javascript
复制
java-8 LocalDateTime hour:     3
java-8 ZonedDateTime hour:     3
Calendar hour:                 2

似乎这一小时的日历从2小时跳到了4小时(如果它对应于DST的变化,一般情况下不一定是个问题)。

我正在使用AdoptOpenJDK 1.8.0_242,但我也检查了HotSpot 1.8.0_181 --同样的问题。

为什么日历报告的时间与ZonedDateTime不同?

这种错配是否已知的问题?

在这种情况下,我应该更信任谁- ZonedDateTime还是Calendar?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-07 09:30:10

假设规则(向DST的转换发生在3月8日或之后的02:00的第一个星期日)在2050年没有变化,那么这个瞬间就发生了空位转换(3月13日),在那里时钟从01:59跳到03:00,所以02:00实际上并不存在。Calendar在这里完全错了。

通过检查每个时区类对所讨论的瞬间的说明,您可以进一步了解Calendar有多大的错误。ZonedDateTime使用ZoneId,而Calendar使用TimeZone。我使用以下代码比较了ZoneId上各种方法的输出和TimeZone对应方的输出:

代码语言:javascript
复制
ZoneId zoneId = ZoneId.of("America/Los_Angeles");
long currMillis = 2530778400000L;
Instant curr = Instant.ofEpochMilli(currMillis);
TimeZone tz = TimeZone.getTimeZone(zoneId);

// what's the actual offset at that instant?
System.out.println(zoneId.getRules().getOffset(curr).getTotalSeconds());
System.out.println(tz.getOffset(currMillis) / 1000);

// is DST observed at that instant?
System.out.println(zoneId.getRules().isDaylightSavings(curr));
System.out.println(tz.inDaylightTime(new Date(currMillis)));

// what's the standard offset at that instant?      
System.out.println(zoneId.getRules().getStandardOffset(curr).getTotalSeconds());
System.out.println(tz.getRawOffset() / 1000);

// how many seconds does DST add to the standard offset at that instant?
System.out.println(zoneId.getRules().getDaylightSavings(curr).getSeconds());
Calendar calendar = GregorianCalendar.from(ZonedDateTime.ofInstant(curr, zoneId));
System.out.println(calendar.get(Calendar.DST_OFFSET) / 1000);

结果如下:

代码语言:javascript
复制
-25200
-28800
true
true
-28800
-28800
3600
0

正如您所看到的,他们都认为DST是被观察到的,但是TimeZone认为DST在标准偏移量上增加了0秒,这使得它认为实际偏移量仍然是-8小时。

但谁知道30年后会发生什么呢?让我们希望每个人都摆脱DST :)

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60109531

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档