Java ZonedDateTime не настраивает UTC на локальную зону

#java #java-time #zoneddatetime #localdatetime

Вопрос:

Этот фрагмент кода:

 String dateString = "20210811T021500Z";
String dateFormat = "yyyyMMdd'T'HHmmss'Z'";

System.out.println(LocalDateTime.parse(dateString, dateFormat).toString());
System.out.println(LocalDateTime.parse(dateString, dateFormat).atZone(ZoneId.of("Europe/Budapest")).toString());
System.out.println(ZonedDateTime.of(LocalDateTime.parse(dateString, dateFormat), ZoneId.of("Europe/Budapest")).toString());
 

Выводит это:

 2021-08-11T02:15
2021-08-11T02:15 02:00[Europe/Budapest]
2021-08-11T02:15 02:00[Europe/Budapest]
 

Как я могу распечатать скорректированное время? Я ожидаю, что результат будет 2021-08-11T04:15 таким .

Комментарии:

1. @DawoodibnKareem Ну, это местное время.

2. О, хорошая мысль. Хорошо, так как же ОП ожидает, что их программа волшебным образом интерпретирует его как UTC?

Ответ №1:

Вы не должны разбирать свою дату на a LocalDateTime . У A LocalDateTime нет информации о часовых поясах, но для вашего расчета здесь вам абсолютно необходимо знать, что дата ввода указана в UTC, чтобы вычислить разницу во времени Europe/Budapest .

Вместо этого проанализируйте дату на a ZonedDateTime :

 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX");
ZonedDateTime zdt = ZonedDateTime.parse(dateString, formatter);
// zdt = 2021-08-11T02:15Z
 

Обратите Z внимание , что строка даты в строке даты анализируется не буквально как 'Z' , а скорее X как смещение зоны. Если бы вы проанализировали его буквально, то в вашей строке даты не было бы информации о часовом поясе.

Затем вы можете получить желаемый результат, позвонив withZoneSameInstant :

 System.out.println(
    zdt.withZoneSameInstant(ZoneId.of("Europe/Budapest"))
); // 2021-08-11T04:15 02:00[Europe/Budapest]
 

В качестве альтернативы вы можете передать зону в форматер:

 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX")
    .withZone(ZoneId.of("Europe/Budapest"));
ZonedDateTime zdt = ZonedDateTime.parse(dateString, formatter);
System.out.println(zdt);
2021-08-11T04:15 02:00[Europe/Budapest]
 

Комментарии:

1. Это работает! Спасибо! Думаю, я понимаю разницу между LocalDateTime «и ZonedDateTime сейчас». Однако мой следующий провал был бы 'Z' буквальным, так что двух зайцев одним выстрелом.