在甲骨文教程是不正确
不幸的是,Oracle教程在此问题上是不正确的。那行示例代码简直是错误的。好的方面。
这个错误是非常不幸的,因为本教程是学习和研究Java的很好资源。
Instant::plus
的Instant
类具有与没有这样的方法plusHours
在任一的Java 8或Java 9限定。
相反,您可以调用该plus
方法并指定小时数。
Instant later = instant.plus( 1 , ChronoUnit.HOURS ) ;
ZonedDateTime::plusHours
该Instant
班是一个基本构建块类,指示在时间轴上一个时刻UTC。通常,在执行诸如增加小时数的操作时,您可能需要考虑诸如夏令时之类的异常,因此您将关心时区。为此,请使用ZonedDateTime
类。该类确实提供了一种方便的plusHours
方法,这对于本教程的作者可能是造成困惑的原因。
指定适当的时区名称,格式continent/region
,如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用3-4字母的缩写,例如EST
或,IST
因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
ZonedDateTime zdtLater = zdt.plusHours( 1 ) ;
Instant
与 ZonedDateTime
让我们看一个添加小时数异常的示例。划分区域后,我们在2017年3月23日凌晨1点的特定时刻增加了一个小时,当然预计为凌晨2点,但是我们很惊讶地看到凌晨3点。但是,当我们考虑UTC的同一时刻而不是特定的时区时,时间轴上的同一点会加上一个小时,这与预期的一样。
这种特殊的异常是由于北美大部分地区(尤其是此处的时区)采用了夏令时(DST)America/New_York
。在春天,时钟“向前”跳一个小时。时钟在凌晨2点响起时,它们跳到凌晨3点。因此,那天两点钟的时间永远不存在。
LocalDate ld = LocalDate.of( 2017 , Month.MARCH , 12 ) ;
LocalTime lt = LocalTime.of( 1 , 0 ) ;
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
ZonedDateTime zdtOneHourLater = zdt.plusHours( 1 ) ;
System.out.println( "zdt: " + zdt ) ;
System.out.println( "zdtOneHourLater: " + zdtOneHourLater ) ;
System.out.println( "Yikes! 1 AM plus an hour is 3 AM? Yes, that is an anomaly known as Daylight Saving Time (DST)." ) ;
System.out.println( "" ) ;
Instant instant = zdt.toInstant() ;
Instant instantOneHourLater = instant.plus( 1 , ChronoUnit.HOURS ) ;
System.out.println( "instant: " + instant ) ;
System.out.println( "instantOneHourLater: " + instantOneHourLater ) ;
System.out.println( "Instant is always in UTC. So no anomalies, no DST. Adding an hour to 1 AM results in 2 AM every time." ) ;
看到此代码在IdeOne.com上实时运行。
zdt:2017-03-12T01:00-05:00 [美国/纽约]
zdtOneHour以后:2017-03-12T03:00-04:00 [美国/纽约]
kes!1 AM加一个小时是3 AM?是的,这是一种称为夏时制(DST)的异常。
即时:2017-03-12T06:00:00Z
InstantOneHour以后:2017-03-12T07:00:00Z
即时始终使用UTC。因此,没有异常,没有DST。将1小时加到1 AM,每次将导致2 AM。