Java 8 Instant 类没有 plusHours 方法,尽管在 Oracle Tutorial 示例代码中显示甲骨文教程不正确 Instant对ZonedDateTime

2022-08-31 13:04:16

即时类的 Oracle 教程页面显示了此示例代码:

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

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

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

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

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


答案 1

甲骨文教程不正确

不幸的是,Oracle教程在这个问题上是不正确的。这行示例代码是完全错误的。你很好。

这个错误非常不幸,因为本教程是学习和学习Java的良好资源。

Instant::plus

Instant 类没有 Java 8 或 Java 9 中定义的方法。plusHours

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

Instant later = instant.plus( 1 , ChronoUnit.HOURS ) ;

ZonedDateTime::plusHours

Instant 类是一个基本的构建基块类,以 UTC 表示时间轴上的某个时刻。通常,在执行操作(如添加小时)时,您可能希望考虑异常(如夏令时),因此您会关心时区。为此,请使用 ZonedDateTime 类。该类确实提供了一个方便的plusHours方法,这可能是教程作者感到困惑的根源。

以 的格式指定适当的时区名称,例如 美国/蒙特利尔非洲/卡萨布兰卡或 。切勿使用3-4个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/regionPacific/AucklandESTIST

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),尤其是美国/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[美国/New_York]

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

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

即时:2018-18-08T06:00:00Z

即时一小时今日咨询: 2017-03-12T07:00:00Z

即时始终采用 UTC 格式。所以没有异常,没有DST。将一小时添加到凌晨 1 点,每次都会在凌晨 2 点产生。


答案 2

推荐