尽管在Oracle Tutorial示例代码中显示,但Java 8 Instant类没有plusHours方法

Ng *_*rma 74 java java-time

该类Oracle Tutorial页面Instant显示了此示例代码:

Instant oneHourLater = Instant.now().plusHours(1);
Run Code Online (Sandbox Code Playgroud)

当我尝试编译此代码时,编译器抛出错误:

  • 错误
InstantPrint.java:6: error: cannot find symbol
        Instant oneHourLater = Instant.now().plusHours(1);
                                            ^
  symbol:   method plusHours(int)
  location: class Instant

但是这个Java文档提到了plusHours()方法,但我检查了这个Instant类,它不包含plusHours()方法.

此后,为什么plusHours()在这个例子中提到这个方法呢?

Bas*_*que 58

甲骨文教程是不正确

不幸的是,Oracle Tutorial在这个问题上是不正确的.那行示例代码完全错误.你很好的抓住了.

这个错误非常不幸,因为Tutorial是学习和学习Java的好资源.

Instant::plus

Instant类具有与没有这样的方法plusHours在任一的Java 8或Java 9限定.

相反,您可以调用该plus方法,并指定小时数.

Instant later = instant.plus( 1 , ChronoUnit.HOURS ) ;
Run Code Online (Sandbox Code Playgroud)

ZonedDateTime::plusHours

Instant班是一个基本构建块类,指示在时间轴上一个时刻UTC.通常在执行诸如添加小时等操作时,您可能希望考虑夏令时等异常情况,因此您会关心时区.为此,请使用该ZonedDateTime课程.该类确实提供了一种方便的plusHours方法,可能是教程作者混淆的根源.

指定适当的时区名称,格式continent/region,如America/Montreal,Africa/CasablancaPacific/Auckland.切勿使用3-4字母缩写,例如ESTIST因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!).

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 ) ;
Run Code Online (Sandbox Code Playgroud)

InstantZonedDateTime

让我们看一个添加小时的异常示例.划线时,我们在2017年3月23日凌晨1点的特定时刻增加一小时,当然预计凌晨2点,但我们很惊讶地看到凌晨3点.然而,当我们考虑UTC中的相同时刻而不是特定时区时,时间线上的相同点,添加一小时就像预期的那样.

这种特殊的异常是由于在北美大部分地区,特别是在这个时区采用了夏令时(DST)America/New_York.在春天,时钟"春天前进"一小时.当时钟凌晨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." ) ;
Run Code Online (Sandbox Code Playgroud)

请参阅IdeOne.com上的代码.

zdt:2017-03-12T01:00-05:00 [America/New_York]

zdtOneHourLater:2017-03-12T03:00-04:00 [America/New_York]

哎呀!凌晨1点加1小时凌晨3点?是的,这是一种称为夏令时(DST)的异常现象.

瞬间:2017-03-12T06:00:00Z

instantOneHourLater:2017-03-12T07:00:00Z

Instant始终为UTC.所以没有异常,没有夏令时.每隔凌晨1点加1小时到凌晨1点.

  • @ AK.Sharma @Ravi**那个教程页面不正确**,都是根据"Instant"类的JavaDoc并根据实际操作使用Java 8 Update 144(我刚刚测试过这个).我建议提交一份错误报告,但页面顶部的警告让我感到恶心的是,Oracle正在放弃维护教程. (7认同)