java8 ZonedDateTime не печатает текущее время EST.Что я тут не так делаю - PullRequest
0 голосов
/ 05 марта 2019

ниже - это код, который я должен распечатать текущее время даты EST, но он печатает время в моем часовом поясе, которое является временем Аризоны.Что мне не хватает в этом коде.Спасибо!

public static void main(String args[]) {
    LocalDateTime datetime = LocalDateTime .now();

    ZonedDateTime zdtNewYork = ZonedDateTime.of ( datetime , ZoneId.of ( "America/New_York" ) );
    System.out.println(zdtNewYork.format(DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss.SSS")));
}

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

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, поскольку они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).

0 голосов
/ 05 марта 2019

Попробуйте что-то вроде:

 LocalDateTime datetime = LocalDateTime .now(ZoneId.of ( "America/New_York" ));

       System.out.println(datetime.format(DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss.SSS")));
...