Impossible d'obtenir LocalDateTime à partir de TemporalAccessor lors de l'analyse de LocalDateTime (Java 8)

151

J'essaie simplement de convertir une chaîne de date en un objet DateTime dans Java 8. En exécutant les lignes suivantes:

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

J'obtiens 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 à ce qui a été suggéré ici , mais je suis servi avec une exception. J'utilise JDK-8u25.

rétographie
la source

Réponses:

177

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

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate dt = LocalDate.parse("20140218", formatter);
rétographie
la source
42
Pour ce que ça vaut: j'ai eu ce même problème même lors de l'utilisation LocalDateet non LocalDateTime. Le problème était que j'avais créé mon DateTimeFormatterutilisation .withResolverStyle(ResolverStyle.STRICT);, donc j'ai dû utiliser le modèle de date uuuuMMddau lieu de yyyyMMdd(c'est-à-dire "année" au lieu de "année de l'ère")!
ZeroOne
72

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

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay();
Øyvind Mo
la source
2
Correction: réglé à n'importe quelle heure au début de la journée .
Trejkaz le
20
LocalDateTime.fromsemble inutile, comme atStartOfDay()revient déjà LocalDateTime.
Dariusz
1
scala: val time = LocalDate.parse ("20171220", DateTimeFormatter.ofPattern ("yyyyMMdd")). atStartOfDay.format (DateTimeFormatter.ofPattern ("yyyy-MM-dd HH: mm: ss"))
Woody Sun
48

Pour ce qui vaut si quelqu'un devait relire ce sujet (comme moi), la bonne réponse serait dans la DateTimeFormatterdéfinition, 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(); 

Il faut définir les champs optionnels s'ils apparaissent. Et le reste du code devrait être exactement le même.

Iulian David
la source
1
C'est une vraie solution universelle par exemple pour une telle méthode: Long getFileTimestamp (fichier de chaîne, modèle de modèle, DateTimeFormatter dtf, groupe int); Ici, vous avez différents modèles et DateTimeFormetter, avec et sans heure spécifiée.
toootooo
Cela peut-il être un champ statique? Je n'ai pas trouvé dans le Javadoc qu'une instance créée de cette façon est thread-safe
Kamil Roman
N'oubliez pas d'ajouter parseDefaultingAPRÈS que vous avez appelé appendPattern. Sinon, ça va céder DateTimeParseException.
wittyameta
31

Ceci est un message d'erreur vraiment peu clair et inutile. Après de nombreux essais et erreurs, j'ai trouvé que LocalDateTimecela donnerait l'erreur ci-dessus si vous n'essayez pas d'analyser une heure. En utilisant à la LocalDateplace, cela fonctionne sans erreur.

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

Tom B
la source
25

Élargissement de la réponse de la rétographie ..: J'ai eu ce même problème même en utilisant LocalDateet non LocalDateTime. Le problème était que j'avais créé mon DateTimeFormatterutilisation .withResolverStyle(ResolverStyle.STRICT);, donc j'ai dû utiliser le modèle de date uuuuMMddau lieu de yyyyMMdd(c'est-à-dire "année" au lieu de "année de l'ère")!

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

(Cette solution était à l'origine un commentaire à la réponse de la rétrospective, mais j'ai été encouragé à la publier comme une réponse autonome car elle fonctionne apparemment très bien pour de nombreuses personnes.)

Zéro un
la source
1
La réponse à la question de savoir pourquoi "u" au lieu de "y" a été répondu dans ce lien uuuu-versus-yyyy-in-datetimeformatter-formatting-pattern-codes-in-java @Peru
prashanth
23

Pour tous ceux qui ont atterri ici avec cette erreur, comme moi:

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

Il provenait d'une 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 0, au lieu d'un modèle de 24 heures.

Changer le modèle d'heure en 24 heures en utilisant un H majuscule le corrige:

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

Si la chaîne de date n'inclut aucune valeur pour les heures, les minutes, etc., vous ne pouvez pas la convertir directement en LocalDateTime. Vous ne pouvez le convertir qu'en a LocalDate, car la chaîne ne représente que les composants année, mois et date , ce serait la bonne chose à faire.

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

Quoi qu'il en soit, vous pouvez le convertir 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
premier
la source
Assurez-vous également que le format est correct. Ce correctif n'a fonctionné pour moi que parce que j'ai défini le format comme yyyy-mm-ddil aurait dû l'être yyyy-MM-dd.
patstuart
0

Essaye celui-là:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-dd-yyyy"); 
LocalDate fromLocalDate = LocalDate.parse(fromdstrong textate, dateTimeFormatter);

Vous pouvez ajouter le format de votre choix. Ça marche pour moi!

Vinay Kasarla
la source
0

Cela fonctionne bien

public class DateDemo {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm");
        String date = "16-08-2018 12:10";
        LocalDate localDate = LocalDate.parse(date, formatter);
        System.out.println("VALUE="+localDate);

        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
        LocalDateTime parse = LocalDateTime.parse(date, formatter1);
        System.out.println("VALUE1="+parse);
    }
}

production:

VALUE=2018-08-16
VALUE1=2018-08-16T12:10
Jeff Cook
la source