Impossible d’obtenir LocalDateTime à partir de TemporalAccessor lors de l’parsing de LocalDateTime (Java 8)

J’essaie simplement de convertir une chaîne de date en object DateTime en Java 8. En exécutant les lignes suivantes:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); LocalDateTime dt = LocalDateTime.parse("20140218", formatter); 

Je reçois l’erreur suivante:

 Exception in thread "main" java.time.format.DateTimeParseException: Text '20140218' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2014-02-18 of type java.time.format.Parsed at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853) at java.time.LocalDateTime.parse(LocalDateTime.java:492) 

La syntaxe est identique à celle proposée ici , mais je suis servi avec une exception. J’utilise JDK-8u25 .

Il s’avère que Java n’accepte pas une valeur de date nue comme DateTime. Utiliser LocalDate au lieu de LocalDateTime résout le problème:

 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); LocalDate dt = LocalDate.parse("20140218", formatter); 

Si vous avez vraiment besoin de transformer une date en object LocalDateTime, vous pouvez utiliser LocalDate.atStartOfDay (). Cela vous donnera un object LocalDateTime à la date spécifiée, les champs heure, minute et seconde étant définis sur 0:

 final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay(); 

Ceci est un message d’erreur vraiment peu clair et inutile. Après beaucoup d’essais et d’erreurs, j’ai trouvé que LocalDateTime donnera l’erreur ci-dessus si vous n’essayez pas d’parsingr une heure. En utilisant LocalDate place, cela fonctionne sans erreur.

Ceci est mal documenté et l’exception associée est très inutile.

Pour ce qui est utile si quelqu’un lit à nouveau ce sujet (comme moi), la réponse correcte sera dans la définition de DateTimeFormatter , par exemple:

 private static DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder().appendPattern("dd/MM/yyyy[ [HH][:mm][:ss][.SSS]]") .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) .toFormatter(); 

On devrait définir les champs optionnels s’ils apparaîtront. Et le rest du code devrait être exactement le même.

Expansion sur la réponse de la rétrographie ..: J’ai eu le même problème en utilisant LocalDate et non LocalDateTime . Le problème était que j’avais créé mon DateTimeFormatter utilisant .withResolverStyle(ResolverStyle.STRICT); , j’ai donc dû utiliser le modèle de date uuuuMMdd au lieu de yyyyMMdd (c’est-à-dire “année” au lieu de “année de l’ère”)!

 DateTimeFormatter formatter = new DateTimeFormatterBuilder() .parseSsortingct() .appendPattern("uuuuMMdd") .toFormatter() .withResolverStyle(ResolverStyle.STRICT); LocalDate dt = LocalDate.parse("20140218", formatter); 

(Cette solution était à l’origine un commentaire de la réponse de retrography, mais j’ai été encouragée à la publier en tant que réponse autonome car elle fonctionne apparemment très bien pour de nombreuses personnes.)

Pour ceux qui ont atterri ici avec cette erreur, comme je l’ai fait:

Unable to obtain LocalDateTime from TemporalAccessor: {HourOfAmPm=0, MinuteOfHour=0}

Il vient de la ligne suivante:

 LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy h:mm")); 

Il s’est avéré que c’était parce que j’utilisais un modèle de 12 heures sur une heure, au lieu d’un modèle de 24 heures.

Changer le modèle heure à 24 heures en utilisant une majuscule H le corrige:

 LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy H:mm")); 

Si la chaîne de date n’inclut aucune valeur pour les heures, les minutes et etc., vous ne pouvez pas convertir directement cette valeur en LocalDateTime . Vous ne pouvez le convertir qu’en LocalDate , car la chaîne ne représente que les composants de l’ année, du mois et de la date .

 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd"); LocalDate ld = LocalDate.parse("20180306", dtf); // 2018-03-06 

De toute façon, vous pouvez convertir cela en LocalDateTime .

 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd"); LocalDate ld = LocalDate.parse("20180306", dtf); LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00