尽管Oracle教程示例代码中显示了Java 8 Instant类,但它没有plusHours方法


76

该类Oracle Tutorial页面Instant显示以下示例代码:

Instant oneHourLater = Instant.now().plusHours(1);

当我尝试编译此代码时,编译器将引发错误:

  • 错误
InstantPrint.java:6:错误:找不到符号
        Instant oneHourLater = Instant.now()。plusHours(1);
                                            ^
  符号:方法plusHours(int)
  位置:班级瞬发

但是此Java文档中提到了plusHours()方法,但是我检查了此类,Instant并且其中不包含plusHours()方法。

此后,为什么plusHours()在示例中提及此方法?


1
找不到链接。没有这样的方法docs.oracle.com/javase/8/docs/api/java/time/Instant.html
Ravi


1
再次检查@Ravi
Ng Sharma

2
是的,该教程是错误的:/
MadProgrammer

35
不赞成投票的人:请注意,此问题在官方Oracle教程中发现了错误的示例代码。确实是一个值得提出的问题。
罗勒·布尔克

Answers:


59

甲骨文教程是不正确

不幸的是,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/MontrealAfrica/CasablancaPacific/Auckland。切勿使用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 ) ;

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." ) ;

看到此代码在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。


7
@ AK.Sharma @Ravi根据该类的JavaDoc以及根据使用Java 8 Update 144的实际实践(我现在刚刚对此进行了测试),该Tutorial页面均不正确Instant。我建议提交一个错误报告,但是页面顶部的警告使我感到恶心,因为Oracle放弃了维护该教程。
罗勒·布尔克

“ Instant类是一个基本的构建块类,指示UTC时间轴上的时刻。”这种说法是不正确的,UTC中的时刻如何?
abc667

Instant根据定义,@ abc667是秒计数加上自UTC 1970年第一时刻的纪元参考时刻以来的秒数。因此,Instant在UTC中永远都是片刻。因此,该toString方法生成一个字符串,该字符串表示UTC中的日期和时间。阅读类文档以获取与面向业务的应用程序中的实际使用无关的琐碎细节。
罗勒·布尔克

两者instant.plus(1, ChronoUnit.HOURS)zdt.plushHours(1)对应于同一时间实例的返回时间(later.equals(zdtLater.toInstant())
jfs

@jfs是的,但是我不确定你的意思。ZonedDateTime只是具有指定时区的Instant。向其中一个小时添加一个小时会在时间轴上同时显示。
罗勒·布尔克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.