web-dev-qa-db-fra.com

Formater LocalDateTime avec le fuseau horaire en Java8

J'ai le code simple suivant:

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

Ensuite, j'aurai l'exception suivante:

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)

Comment résoudre ce problème?

79
carfield

LocalDateTime est une date-heure sans fuseau horaire. Vous avez spécifié le symbole de format de décalage de fuseau horaire dans le format. Cependant, LocalDateTime ne dispose pas de telles informations. C'est pourquoi l'erreur s'est produite.

Si vous souhaitez des informations sur le fuseau horaire, vous devez utiliser ZonedDateTime .

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

Le préfixe "Local" dans JSR-310 (ou Java.time-package dans Java-8) n'indique pas qu'il existe une information de fuseau horaire dans l'état interne de cette classe (ici: LocalDateTime). Malgré le nom souvent trompeur, des classes telles que LocalDateTime ou LocalTime n'ont AUCUN renseignement sur le fuseau horaire ou offset.

Vous avez essayé de formater un tel type temporel (qui ne contient aucun décalage) avec des informations de décalage (indiquées par le symbole de motif Z). Le formateur essaie donc d'accéder à une information non disponible et doit lever l'exception que vous avez observée.

Solution: 

Utilisez un type qui contient une telle information de décalage ou de fuseau horaire. Dans JSR-310, il s’agit de OffsetDateTime (qui contient un décalage mais pas un fuseau horaire incluant les règles DST) ou ZonedDateTime. Vous pouvez surveiller tous les champs supportés de ce type en consultant la méthode isSupported (TemporalField). . Le champ OffsetSeconds est pris en charge dans OffsetDateTime et ZonedDateTime, mais pas dans LocalDateTime.

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