Why setting timezone on the Java calendar object has no effect?
请考虑以下代码段。
1 2 3 4 5 6 7 8 9 10 |
结果如下:
1 2 3 | sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] before setting time zone: Mon Dec 25 22:39:53 EST 2017 after setting time zone: Mon Dec 25 22:39:53 EST 2017 |
在时区更改后,为什么日期的打印输出仍显示EST? 不应该是GMT吗?
TL;博士
1 2 | LocalDate.of( 2017 , Month.DECEMBER , 25 ) .atStartOfDay( ZoneId.of("America/New_York" ) ) |
避免遗留日期时间类
您正在使用现在遗留下来的非常麻烦的旧日期时间类。
要直接回答您的问题,
永远不要使用这些类。仅使用他们的替代品,业界领先的java.time类。
java.time
1 | LocalDate xmas2017 = LocalDate.of( 2017 , Month.DECEMBER , 25 ) ; |
如果您想要日期时间,即当天的第一时刻,则必须指定时区。时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔仍然是"昨天"。
以
永远不要假设这一天从00:00开始。在某些区域中,夏令时(DST)等异常表示该日可能会在某个其他时间开始,例如01:00:00。让java.time确定一天中的第一个时刻。
应用
1 2 | ZoneId z = ZoneId.of("America/New_York" ) ; ZonedDateTime zdtNewYork = xmas2017.atStartOfDay( z ) ; |
请注意,圣诞节在印度比在纽约早得多。
1 | ZonedDateTime zdtKolkta = xmas2017.atStartOfDay( ZoneId.of("Asia/Kolkata" ) ) ; |
这就是为什么精灵的后勤部门将圣诞老人送到基里巴斯进行首次交付。这些岛屿的最早圣诞节时区比UTC早14小时。从那里开始,当地球旋转到新的一天的阳光下时,驯鹿向东飞行,一个接一个地追逐连续的中午。
如果您希望将相同的时刻调整为UTC,请提取始终为UTC的
1 | Instant instant = zdt.toInstant() ; |
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
-
Java SE 8,Java SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小功能和修复。
-
Java SE 6和Java SE 7
- 许多java.time功能都被反向移植到Java 6& 7在ThreeTen-Backport。
-
Android的
- ThreeTenABP项目特别适用于Android的ThreeTen-Backport(如上所述)。
- 请参见如何使用ThreeTenABP ....
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。您可以在这里找到一些有用的类,例如