Java 8 Мгновенный класс не имеет метода plusHours, несмотря на то, что он показан в примере примера Oracle Tutorial

Страница Страница Oracle Tutorial для класса Instant показывает этот пример кода:

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(), но я проверяю этот класс Instant и не содержит метода plusHours().

Впоследствии, зачем упоминать этот метод plusHours() в примере?

Ответ 1

Неправильное использование учебника Oracle

К сожалению, учебник Oracle не соответствует этому вопросу. Эта строка примера кода просто неверна. Хороший улов с вашей стороны.

Эта ошибка весьма неудачная, поскольку Учебное пособие в остальном является прекрасным ресурсом для обучения и изучения Java.

Instant::plus

Класс Instant не имеет такого метода, как plusHours, определенного в Java 8 или Java 9.

Вместо этого вы можете вызвать метод plus и указать часы.

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

ZonedDateTime::plusHours

Instant class - это базовый класс строительного блока, указывающий момент на временной шкале в 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 ) ; // Same moment, but viewed through the lens of a region’s wall-clock time.
ZonedDateTime zdtLater = zdt.plusHours( 1 ) ;

Instant по сравнению с ZonedDateTime

Посмотрим на пример аномалии в добавлении часов. При зонировании мы добавляем час к конкретному моменту 1:00 23 марта 2017 года и, конечно, ожидаем 2 часа ночи, но мы удивлены, увидев 3 часа ночи. Тем не менее, когда мы рассматриваем тот же самый момент в UTC, а не в этом конкретном часовом поясе, та же самая точка на временной шкале, добавив час, ведет себя так, как ожидалось.

Эта особая аномалия связана с принятием летнего времени (DST) в большинстве стран Северной Америки, в частности здесь, времени zone America/New_York. В Spring часы "spring -forward" час. Когда часы наступают 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 AM плюс час - 3 часа? Да, это аномалия, известная как "Летнее время" (DST).

мгновение: 2017-03-12T06: 00: 00Z

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

Мгновенное действие всегда в UTC. Так что никаких аномалий, ни ДСТ. Добавление часа к 1 AM приводит к 2 часам каждый раз.