tl; dr
Вы зафиксировали дату и время дня в Аризоне, а затем нанесли удар по часовому поясу, чтобы заявить (неверно), что в этот момент в Нью-Йорке такое же время дня.
Поэтому, конечно, когда вы генерировали текст для отображения этих значений, вы впервые увидели время суток в Аризоне.Ни в коем случае вы не настраивали из Аризоны в Нью-Йорк.
LocalDateTime
- это неправильный класс
Никогда не используйте LocalDateTime
для отслеживания моментов.По определению, этот класс не может представлять определенный момент времени, точку на временной шкале.Он содержит дату и время суток, но в нем отсутствует контекст часового пояса или смещения от UTC.Говорить нам «Полдень 23 января этого года» бессмысленно, если мы не знаем, имели ли вы в виду полдень в Токио, Японии, Калькутте, Париже, Монреале и Квебеке - все это были разные моменты, с разницей в несколько часов.
Всегда указывайте часовой пояс
Чтобы использовать неправильный класс, вы набрали LocalDateTime.now
без указания часового пояса.Таким образом, текущий часовой пояс по умолчанию вашей JVM был применен неявно.Вы утверждаете, что по умолчанию используется часовой пояс в Аризоне.Так что это будет применяться к зоне.
Итак, вы зафиксировали дату и время суток, как это видно в Аризоне.Но затем вы отбросили тот факт, что значение было в часовом поясе Аризоны из-за использования LocalDateTime
.Отказ от часового пояса - это весь смысл класса LocalDateTime
.Есть случаи, когда это полезно, но, конечно, не в вашей ситуации.
Затем вы взяли ту дату и время дня в Аризоне и заявили, что это были дата и время в Нью-Йорке.Фактическое время дня в Нью-Йорке было на несколько часов раньше, так что вы сказали выдумку.Наконец, вы сгенерировали текст, показывающий эту выдумку.
Другими словами, по-видимому, вы подумали об этой строке:
ZonedDateTime.of ( datetime , ZoneId.of ( "America/New_York" ) )
… с поправкой от Аризоны до Нью-Йорка.Но этот аргумент datetime
больше не знает, что он пришел из Аризоны, потому что LocalDateTime
не имеет понятия зоны / смещения .Корректировка не была сделана.
Вы можете думать об этом следующим образом:
LocalDateTime
= дата + время суток
OffsetDateTime
= дата+ время суток + смещение
ZonedDateTime
= дата + время суток + зона
Instant
= дата + время суток + UTC
Вместо этого я рекомендую всегда , явно указав желаемый / ожидаемый часовой пояс.Даже если вам нужен текущий часовой пояс по умолчанию, скажите об этом явно, позвонив по номеру ZoneId.systemDefault
, чтобы любой программист, читающий ваш код, четко знал ваше намерение.Разрешение использования часового пояса или смещения от UTC является необязательным, и это одна из немногих вещей, которые я бы изменил в отличном дизайне класса, который можно найти в java.time Задание требуемых аргументов зоны / смещения поможет обучить больше программистов работе с датой и временем.
ZonedDateTime
- это правильный класс
Для представления момента, видимого через время настенных часовиспользуется людьми определенного региона (часового пояса), используйте ZonedDateTime
.
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
См. этот код, запущенный в прямом эфире на IdeOne.com .
zdt.toString (): 2019-03-04T18: 17: 08.014-05: 00 [America / New_York]
Создать текст
Мы можем сгенерировать текст, который выхочу легко.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu HH:mm:ss.SSS" ) ;
String output = zdt.format( f ) ;
См. этот код, запущенный в прямом эфире на IdeOne.com .
03/04/2019 18: 17: 08.014
Настройка зон
Если вы хотите выполнить настройку между зонами, вызовите метод ZonedDateTime::withZoneSameInstant
.
ZonedDateTime zdtPhoenix = ZoneDateTime.now( ZoneId.of( "America/Phoenix" ) ) ;
ZonedDateTime zdtNewYork = zdtPhoenix.withZoneSameInstant( ZoneId.of( "America/New_York" ) ) ; // Same moment, same point on the timeline, different wall-clock time.
Обратите внимание на фразу SameInstant
это означает, что вам нужен один и тот же момент, одна и та же одновременная точка на временной шкале, но вы хотите видеть это через время настенных часов, которое используют жители региона Нью-Йорк.
Часовые пояса
распечатывать текущее время EST
Spвведите собственное имя часового пояса в формате Continent/Region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
.Никогда не используйте и не обращайтесь к 2-4 буквенным аббревиатурам, таким как EST
или IST
, поскольку они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).