LocalDateTime в зоне не отображает час дня зоны

У меня есть дата и время в UTC в формате LocalDateTime lastUpdated. Я хотел бы отображать время и дату для данной зоны, но независимо от зоны я получаю одно и то же время суток. Для следующего кода:

System.out.println(lastUpdated);
System.out.println(lastUpdated.atZone(ZoneId.of("Europe/Paris")));
System.out.println(lastUpdated.atZone(ZoneId.of("America/Los_Angeles")));

Я получаю:

2018-05-26T21:33:46
2018-05-26T21:33:46+02:00[Europe/Paris]
2018-05-26T21:33:46-07:00[America/Los_Angeles]

но то, что я хотел бы получить, это:

2018-05-26T21:33:46
2018-05-26T**23**:33:46+02:00[Europe/Paris]
2018-05-26T**14**:33:46-07:00[America/Los_Angeles]

Информация о зоне для меня необязательна. Мне просто нужно правильное время в зоне. Есть ли способ достичь этого?


person merzbow    schedule 27.05.2018    source источник
comment
Вы пробовали вместо этого использовать ZonedDateTime?   -  person Yassin Hajaj    schedule 27.05.2018
comment
А ваши исследовательские усилия? Почти дубликат Changing LocalDateTime на основе разница во времени в текущем часовом поясе по сравнению с восточным часовым поясом   -  person Ole V.V.    schedule 28.05.2018


Ответы (2)


У меня сложилось впечатление, что вы путаете и приравниваете «отсутствие информации о часовом поясе» к «часовому поясу UTC… Потому что, когда я не говорю, какой часовой пояс, это UTC… Верно?»

Неправильный. Когда вы не говорите, какой часовой пояс, у вас нет конкретной информации о часовом поясе.

Итак, ваш 2018-05-26T21:33:46 - это не дата и время, UTC, это понятие даты и времени в эту дату, не зная, что существует концепция часовых поясов. Это то, что вы получаете, когда идете и спрашиваете кого-нибудь, какое сегодня число и который час. Нет, они не подумают, что вы тоже можете захотеть учитывать, что он находится в том часовом поясе, в котором вы сейчас находитесь. Парень просто вообще не подумает, что существует такая вещь, как часовые пояса, и все же он будет быть в состоянии сказать, который день и время это.

Итак, чтобы преобразовать дату и время, UTC, в дату и время в других часовых поясах, вы делаете это:

ZonedDateTime time = lastUpdated.atZone(ZoneId.of("UTC"));
System.out.println(time);
System.out.println(time.withZoneSameInstant​(ZoneId.of("Europe/Paris")));
System.out.println(time.withZoneSameInstant​(ZoneId.of("America/Los_Angeles")));
person kumesana    schedule 27.05.2018
comment
Лучше. Не запомнил withZoneSameInstant. - person M. le Rutte; 27.05.2018
comment
Правильный ответ. Выражение «UTC LocalDateTime» является противоречием в терминах. - person Basil Bourque; 27.05.2018
comment
Я понимаю. Спасибо за подробное объяснение. Я неправильно понял концепцию. Теперь супер ясно :) - person merzbow; 27.05.2018
comment
Я мог бы даже использовать OffsetDateTime time = lastUpdated.atOffset(ZoneOffset.UTC);, а затем time.atZoneSameInstant​(…). - person Ole V.V.; 28.05.2018
comment
@ОлеВ.В. это лучше работает на семантическом уровне. Но мы входим в домен, когда я начинаю думать, что тот или иной метод не имеет большого значения. - person kumesana; 28.05.2018

Вы используете LocalDateTime, который указывает дату и время без часового пояса, как вы бы использовали, когда обсуждаете даты и время с людьми в вашем часовом поясе. atZone возвращает ZonedDateTime этой даты в то время, как если бы вы говорили об этом в этом часовом поясе.

Таким образом, чтобы получить разное время, вам нужно преобразовать ZonedDateTime в Instant, то есть момент времени, определенный для всей планеты. Это Instant может быть снова преобразовано в ZonedDateTime.

LocalDateTime lastUpdated = LocalDateTime.now();
ZonedDateTime zonedDateTime = lastUpdated.atZone(ZoneId.of("Europe/Paris"));
System.out.println(zonedDateTime);
ZonedDateTime other = ZonedDateTime.ofInstant(zonedDateTime.toInstant(), ZoneId.of("America/Los_Angeles"));
System.out.println(other);

Выход:

2018-05-27T21:53:53.754+02:00[Europe/Paris]
2018-05-27T12:53:53.754-07:00[America/Los_Angeles]
person M. le Rutte    schedule 27.05.2018
comment
Спасибо за объяснение :) Было очень полезно понять идею. - person merzbow; 27.05.2018