Миттєвий клас Java 8 не має методу plusHours, незважаючи на те, що показано в прикладі коду підручника Oracle


76

Сторінка підручника Oracle для Instantкласу показує такий приклад коду:

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

Коли я намагаюся скомпілювати цей код, компілятор видає помилку:

  • Помилка
InstantPrint.java:6: помилка: не вдається знайти символ
        Миттєвий oneHourLater = Instant.now (). PlusHours (1);
                                            ^
  символ: метод plusHours (int)
  місцезнаходження: клас Миттєво

Але в цій документації Java згадується plusHours()метод, але я перевіряю цей Instantклас, і він не містить plusHours()методу.

Потім, навіщо згадувати цей plusHours()метод у прикладі?


1
посилання не знайдено. Немає такого методу docs.oracle.com/javase/8/docs/api/java/time/Instant.html
Раві,


1
перевірити ще раз @Ravi
Ng Sharma

2
І так, підручник помилковий: /
MadProgrammer

35
Голосуючі: Зауважте, що це запитання виявило несправний приклад коду в офіційному підручнику Oracle. Справді гідне запитання.
Basil Bourque,

Відповіді:


59

Oracle Підручник невірний

На жаль, підручник Oracle щодо цього питання неправильний. Цей рядок прикладу коду просто неправильний. Хороший улов з вашого боку.

Ця помилка є дуже прикрою, оскільки підручник - це інакше чудовий ресурс для вивчення та вивчення Java.

Instant::plus

InstantКлас не має такого способу , як plusHoursвизначено в будь-якому Java 8 або 9 Java.

Натомість ви можете викликати plusметод і вказати години.

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

ZonedDateTime::plusHours

InstantКлас є основним класом многокомпонентного, вказуючи момент на шкалі часу в форматі UTC . Зазвичай, виконуючи такі маніпуляції, як додавання годин, ви, мабуть, захочете врахувати такі аномалії, як перехід на літній час , і тому вам буде цікавий часовий пояс . Для цього використовуйте ZonedDateTimeклас. Цей клас робить це зручний plusHoursметод, вірогідне джерело плутанини для Tutorial авторів.

Вкажіть правильний час ім'я зони в форматі 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 ранку 23 березня 2017 року і, звичайно, очікуємо 2 ранку, але ми здивовані побаченням 3 ранку. І все ж коли ми розглядаємо той самий момент в UTC, а не той конкретний часовий пояс, той самий момент на часовій шкалі, додаючи годину, поводиться, як очікувалося.

Ця особлива аномалія обумовлена ​​прийняттям літнього часу на більшій частині Північної Америки, зокрема тут, часового поясу 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 [Америка / Нью_Йорк]

zdtOneHourLater: 2017-03-12T03: 00-04: 00 [Америка / Нью-Йорк]

Так! 1 ранку плюс година - це 3 ранку? Так, це аномалія, відома як літній час.

миттєвий: 2017-03-12T06: 00: 00Z

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

Миттєвий завжди в UTC. Отже, немає аномалій, немає літнього часу. Додавання години до 1 ранку кожного разу призводить до 2 ранку.


7
@ AK.Sharma @Ravi Ця сторінка підручника неправильна , як згідно з JavaDoc Instantкласу, так і відповідно до фактичної практики використання Java 8 Update 144 (я щойно перевірив це зараз). Я б запропонував подати звіт про помилку, але це попередження у верхній частині сторінок викликає у мене неприємне відчуття, що Oracle відмовляється від ведення навчального посібника.
Basil Bourque,

«Миттєвий клас - це основний клас будівельних блоків, який вказує момент на часовій шкалі в UTC.» Це твердження неправильне, як може бути момент часу в UTC?
abc667

@ abc667 An Instant- це за визначенням відлік секунд плюс дробова секунда з моменту відліку епохи першого моменту 1970 року в UTC. Отже, ан Instant- це завжди момент у UTC. Відповідно, toStringметод генерує рядок, що представляє дату та час доби в UTC. Прочитайте документацію до класу для дрібниць, які не мають значення для практичного використання в бізнес-орієнтованих додатках.
Basil Bourque,

як instant.plus(1, ChronoUnit.HOURS)і zdt.plushHours(1)час повернення відповідних одному і тому ж часу , наприклад ( later.equals(zdtLater.toInstant()))
JFS

@jfs Правда, але я не впевнений у вашій думці. ZonedDateTime - це просто миттєвий з призначеним часовим поясом. Додавання години до будь-якого результату призводить до того самого моменту на шкалі часу.
Василь Бурк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.