Java 8 Instant类尽pipe在Oracle Tutorial示例代码中显示,但没有plusHours方法
Instant
类的Oracle Tutorial页面显示了这个示例代码:
Instant oneHourLater = Instant.now().plusHours(1);
当我尝试编译此代码时,编译器会引发错误:
- 错误
InstantPrint.java:6:错误:找不到符号 即时oneHourLater = Instant.now()。plusHours(1); ^ 符号:方法plusHours(int) 位置:课堂即时
但是这个Java文档提到了plusHours()
方法,但是我检查了这个Instant
类,它不包含plusHours()
方法。
那么,为什么在这个例子中提到这个plusHours()
方法呢?
Oracle教程不正确
不幸的是, Oracle教程在这个问题上是不正确的。 这一行代码示例简直是错误的。 你很好的接受。
这个错误是相当不幸的,因为教程是学习和学习Java的好资源。
Instant::plus
Instant
类没有Java 8或Java 9中定义的plusHours
类的方法。
相反,您可以调用plus
方法,并指定小时数。
Instant later = instant.plus( 1 , ChronoUnit.HOURS ) ;
ZonedDateTime::plusHours
Instant
类是一个基本的构build块类,用UTC表示时间轴上的一个时刻。 通常,在执行诸如添加小时之类的操作时,您可能需要考虑诸如夏令时之类的exception情况,因此您会关心时区 。 为此,使用ZonedDateTime
类。 该类确实提供了一个方便的plusHours
方法,这可能是教程作者混淆的来源。
以America/Montreal
, Africa/Casablanca
, Pacific/Auckland
等continent/region
的格式指定适当的时区名称 。 切勿使用3-4字母缩写(如EST
或IST
因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ; ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, but viewed through the lens of a region's wall-clock time. ZonedDateTime zdtLater = zdt.plusHours( 1 ) ;
Instant
与ZonedDateTime
让我们来看一个添加小时的exception的例子。 划分区域时,我们在2017年3月23日凌晨1点增加一小时,当然期望凌晨2点,但我们惊讶地发现凌晨3点。 但是,当我们考虑UTC的时间而不是特定的时间段时,时间线上的相同点加上一个小时的行为就像预期的那样。
这种特殊的exception是由于在北美大部分地区采用了夏令时(DST) ,特别是在这个时区的America/New_York
。 在spring,钟表“向前”一个小时。 随着时钟敲2点,他们跳到凌晨3点。 所以当天两点的时间从来没有存在过。
// ZonedDateTime 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 instant = zdt.toInstant() ; // Adjust into UTC. Same moment, same point on the timeline, but viewed by a different wall-clock. 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 [America / New_York]
zdtOneHourLater:2017-03-12T03:00-04:00 [America / New_York]
哎呀! 凌晨1点加上一个小时是凌晨3点 是的,这是一个称为夏令时(DST)的exception情况。
即时:2017-03-12T06:00:00Z
instantOneHourLater:2017-03-12T07:00:00Z
即时通讯始终使用UTC。 所以没有exception,没有DST。 每上午1点加1小时,每次2点。