Formatear LocalDateTime con Zona horaria en Java8


Tengo este simple código:

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

Entonces obtendré la siguiente excepción:

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)

¿Cómo resolver este problema?

Author: Matthias Braun, 2014-08-29

2 answers

LocalDateTime es una fecha-hora sin una zona horaria. Especificó el símbolo de formato de desplazamiento de zona horaria en el formato, sin embargo, LocalDateTime no tiene dicha información. Por eso ocurrió el error.

Si desea información de zona horaria, debe usar ZonedDateTime.

DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
ZonedDateTime.now().format(FORMATTER);
=> "20140829 14:12:22.122000 +09"
 121
Author: ntalbs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-20 14:51:46

El prefijo "Local" en JSR-310 (también conocido como java.time-package en Java-8) no indica que haya una información de zona horaria en estado interno de esa clase (aquí: LocalDateTime). A pesar del nombre a menudo engañoso tales clases como LocalDateTime o LocalTime no tienen información de zona horaria o desplazamiento.

Ha intentado formatear tal tipo temporal (que no contiene ningún desplazamiento) con información de desplazamiento (indicada por el símbolo de patrón Z). Así que el formateador intenta acceder a un no disponible información y tiene que lanzar la excepción que observó.

Solución:

Utilice un tipo que tenga dicha información de desplazamiento o zona horaria. En JSR-310 esto es OffsetDateTime (que contiene un desplazamiento pero no una zona horaria que incluye reglas DST) o ZonedDateTime. Puede ver todos los campos soportados de este tipo buscando en el método isSupported(TemporalField).. El campo OffsetSeconds está soportado en OffsetDateTime y ZonedDateTime, pero no en LocalDateTime.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
String s = ZonedDateTime.now().format(formatter);
 34
Author: Meno Hochschild,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-29 05:08:09