it-swarm.com.ru

Форматирование LocalDateTime с часовым поясом в Java8

У меня есть этот простой код:

DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
LocalDateTime.now().format(FORMATTER)

Тогда я получу следующее исключение:

Java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
at Java.time.LocalDate.get0(LocalDate.Java:680)
at Java.time.LocalDate.getLong(LocalDate.Java:659)
at Java.time.LocalDateTime.getLong(LocalDateTime.Java:720)
at Java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.Java:298)
at Java.time.format.DateTimeFormatterBuilder$OffsetIdPrinterParser.format(DateTimeFormatterBuilder.Java:3315)
at Java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.Java:2182)
at Java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.Java:1745)
at Java.time.format.DateTimeFormatter.format(DateTimeFormatter.Java:1719)
at Java.time.LocalDateTime.format(LocalDateTime.Java:1746)

Как решить эту проблему?

79
carfield

LocalDateTime это дата-время без часового пояса. Вы указали символ формата смещения часового пояса в формате, однако LocalDateTime такой информации не имеет. Вот почему произошла ошибка.

Если вам нужна информация о часовом поясе, вы должны использовать ZonedDateTime .

DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
ZonedDateTime.now().format(FORMATTER);
=> "20140829 14:12:22.122000 +09"
140
ntalbs

Префикс «Local» в JSR-310 (он же Java.time-package в Java-8) не указывает на наличие информации о часовом поясе во внутреннем состоянии этого класса (здесь: LocalDateTime). Несмотря на часто вводящее в заблуждение название, такие классы, как LocalDateTime или LocalTime, не имеют информации о часовом поясе или смещении.

Вы попытались отформатировать такой временной тип (который не содержит смещения) с информацией о смещении (обозначенной символом шаблона Z). Таким образом, средство форматирования пытается получить доступ к недоступной информации и должно выдать исключение, которое вы наблюдали.

Решение: 

Используйте тип с таким смещением или информацией о часовом поясе. В JSR-310 это либо OffsetDateTime (который содержит смещение, но не часовой пояс, включая DST-правила), либо ZonedDateTime. Вы можете просмотреть все поддерживаемые поля такого типа, посмотрев на метод isSupported (TemporalField). . Поле OffsetSeconds поддерживается в OffsetDateTime и ZonedDateTime, но не в LocalDateTime.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
String s = ZonedDateTime.now().format(formatter);
36
Meno Hochschild