LocalDateTime kann beim Parsen von LocalDateTime (Java 8) nicht von TemporalAccessor abgerufen werden.

150

Ich versuche einfach, eine Datumszeichenfolge in ein DateTime-Objekt in Java 8 zu konvertieren. Beim Ausführen der folgenden Zeilen:

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

Ich erhalte folgende Fehlermeldung:

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)

Die Syntax ist identisch mit dem, was hier vorgeschlagen wurde , aber ich werde mit einer Ausnahme bedient. Ich benutze JDK-8u25.

Retrographie
quelle

Antworten:

177

Es stellt sich heraus, dass Java keinen bloßen Datumswert als DateTime akzeptiert. Die Verwendung von LocalDate anstelle von LocalDateTime löst das Problem:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate dt = LocalDate.parse("20140218", formatter);
Retrographie
quelle
42
Für das, was es wert ist: Ich hatte das gleiche Problem, auch wenn ich es benutzte LocalDateund nicht LocalDateTime. Das Problem war, dass ich meine DateTimeFormatterVerwendung erstellt hatte .withResolverStyle(ResolverStyle.STRICT);, also musste ich Datumsmuster uuuuMMddanstelle von yyyyMMdd(dh "Jahr" anstelle von "Jahr der Ära") verwenden!
ZeroOne
71

Wenn Sie ein Datum wirklich in ein LocalDateTime-Objekt umwandeln müssen, können Sie LocalDate.atStartOfDay () verwenden. Dadurch erhalten Sie zum angegebenen Datum ein LocalDateTime-Objekt, dessen Felder Stunde, Minute und Sekunde auf 0 gesetzt sind:

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay();
Øyvind Mo.
quelle
2
Korrektur: Stellen Sie die Zeit ein, die zu Beginn dieses Tages liegen soll .
Trejkaz
20
LocalDateTime.fromscheint unnötig, da atStartOfDay()schon zurück 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

Für was ist es wert, wenn jemand dieses Thema noch einmal lesen sollte (wie ich), wäre die richtige Antwort in DateTimeFormatter Definition, zB:

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(); 

Man sollte die optionalen Felder festlegen, wenn sie angezeigt werden. Und der Rest des Codes sollte genau der gleiche sein.

Iulian David
quelle
1
Dies ist eine echte universelle Lösung, zum Beispiel für eine solche Methode: Long getFileTimestamp (String-Datei, Mustermuster, DateTimeFormatter dtf, int group); Hier haben Sie verschiedene Muster und DateTimeFormetter, ohne und ohne Zeitangabe.
Toootooo
Kann es ein statisches Feld sein? Ich habe im Javadoc nicht festgestellt, dass eine auf diese Weise erstellte Instanz threadsicher ist
Kamil Roman
Denken Sie daran, das parseDefaultingNACH dem Aufruf hinzuzufügen appendPattern. Sonst wird es geben DateTimeParseException.
wittyameta
31

Dies ist eine wirklich unklare und nicht hilfreiche Fehlermeldung. Nach langem Ausprobieren habe ich festgestellt, LocalDateTimedass der obige Fehler angezeigt wird, wenn Sie nicht versuchen, eine Zeit zu analysieren. Wenn Sie LocalDatestattdessen verwenden, funktioniert dies ohne Fehler.

Dies ist schlecht dokumentiert und die damit verbundene Ausnahme ist sehr wenig hilfreich.

Tom B.
quelle
25

Erweiterung der Antwort der Retrographie ..: Ich hatte das gleiche Problem, auch wenn ich es benutzte LocalDateund nicht LocalDateTime. Das Problem war, dass ich meine DateTimeFormatterVerwendung erstellt hatte .withResolverStyle(ResolverStyle.STRICT);, also musste ich Datumsmuster uuuuMMddanstelle von yyyyMMdd(dh "Jahr" anstelle von "Jahr der Ära") verwenden!

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

(Diese Lösung war ursprünglich ein Kommentar zur Antwort der Retrographie, aber ich wurde ermutigt, sie als eigenständige Antwort zu veröffentlichen, da sie anscheinend für viele Menschen sehr gut funktioniert.)

Null eins
quelle
1
Die Antwort darauf, warum "u" anstelle von "y" in diesem Link beantwortet wurde uuuu-versus-yyyy-in-datetimeformatter-Formatierungsmuster-Codes-in-Java @Peru
prashanth
23

Für alle, die mit diesem Fehler hier gelandet sind, wie ich:

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

Es kam aus einer der folgenden Zeilen:

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

Es stellte sich heraus, dass ich ein 12-Stunden-Muster für eine 0-Stunde anstelle eines 24-Stunden-Musters verwendete.

Durch Ändern des Stunden- auf 24-Stunden-Musters mithilfe eines Großbuchstaben H wird Folgendes behoben:

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

Wenn die Datumszeichenfolge keinen Wert für Stunden, Minuten usw. enthält, können Sie diesen nicht direkt in a konvertieren LocalDateTime. Sie können es auf ein nur konvertieren LocalDate, da die Zeichenfolge nur repräsentieren die Jahr, Monat und Datum Komponenten wäre es die richtige Sache zu tun.

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

Auf jeden Fall können Sie dies in konvertieren 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
Prime
quelle
Stellen Sie außerdem sicher, dass das Format korrekt ist. Dieses Update hat bei mir erst funktioniert, weil ich das Format so eingestellt habe, wie yyyy-mm-ddes hätte sein sollen yyyy-MM-dd.
Patstuart
0

Probier diese:

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

Sie können jedes gewünschte Format hinzufügen. Das ist für mich in Ordnung!

Vinay Kasarla
quelle
0

Das funktioniert gut

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);
    }
}

Ausgabe:

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