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 ) ;
ZonedDateTime zdtLater = zdt.plusHours( 1 ) ;
Instant
проти ZonedDateTime
Давайте розглянемо приклад аномалії додавання годин. При зонуванні ми додаємо годину до конкретного моменту 1 ранку 23 березня 2017 року і, звичайно, очікуємо 2 ранку, але ми здивовані побаченням 3 ранку. І все ж коли ми розглядаємо той самий момент в UTC, а не той конкретний часовий пояс, той самий момент на часовій шкалі, додаючи годину, поводиться, як очікувалося.
Ця особлива аномалія обумовлена прийняттям літнього часу на більшій частині Північної Америки, зокрема тут, часового поясу America/New_York
. Навесні годинник "весняно-вперед" годину. Коли годинники б’ють о 2 ранку, вони підскакують до 3 ранку. Отже, години дві години цього дня ніколи не існувало.
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 = zdt.toInstant() ;
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 ранку.