Nie można uzyskać LocalDateTime z TemporalAccessor podczas analizowania LocalDateTime (Java 8)

150

Po prostu próbuję przekonwertować ciąg daty na obiekt DateTime w Javie 8. Po uruchomieniu następujących wierszy:

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

Otrzymuję następujący błąd:

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)

Składnia jest identyczna z tą, która została tu zasugerowana , ale obsługiwany jestem z wyjątkiem. Używam JDK-8u25.

retrografia
źródło

Odpowiedzi:

177

Okazuje się, że Java nie akceptuje samej wartości Date jako DateTime. Użycie LocalDate zamiast LocalDateTime rozwiązuje problem:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate dt = LocalDate.parse("20140218", formatter);
retrografia
źródło
42
Cóż to jest warte: miałem ten sam problem nawet podczas używania LocalDatei nie LocalDateTime. Problem polegał na tym, że stworzyłem DateTimeFormatterużycie .withResolverStyle(ResolverStyle.STRICT);, więc musiałem użyć wzorca daty uuuuMMddzamiast yyyyMMdd(tj. „Rok” zamiast „roku ery”)!
ZeroOne
71

Jeśli naprawdę potrzebujesz przekształcić datę w obiekt LocalDateTime, możesz użyć metody LocalDate.atStartOfDay (). W ten sposób otrzymasz obiekt LocalDateTime o określonej dacie, z polami godziny, minuty i sekundy ustawionymi na 0:

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay();
Øyvind Mo
źródło
2
Korekta: ustaw dowolną godzinę na początku tego dnia .
Trejkaz,
20
LocalDateTime.fromwydaje się niepotrzebne, ponieważ atStartOfDay()już wraca LocalDateTime.
Dariusz
1
scala: val time = LocalDate.parse ("20171220", DateTimeFormatter.ofPattern ("rrrrMMdd")). atStartOfDay.format (DateTimeFormatter.ofPattern ("rrrr-MM-dd HH: mm: ss"))
Woody Sun
48

Bo cóż by było, gdyby ktoś jeszcze raz przeczytał ten temat (tak jak ja) poprawna odpowiedź byłaby w DateTimeFormatterdefinicji, np:

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

Należy ustawić opcjonalne pola, jeśli się pojawią. A reszta kodu powinna być dokładnie taka sama.

Iulian David
źródło
1
To prawdziwie uniwersalne rozwiązanie np. Dla takiej metody: Long getFileTimestamp (plik String, wzorzec wzorca, DateTimeFormatter dtf, grupa int); Tutaj masz różne wzorce i określono DateTimeFormetter bez określonego czasu.
toootooo
Czy może to być pole statyczne? Nie znalazłem w Javadoc, że utworzona w ten sposób instancja jest bezpieczna dla wątków
Kamil Roman
Pamiętaj, aby dodać po parseDefaultingwywołaniu appendPattern. W przeciwnym razie to da DateTimeParseException.
wittyameta
31

To jest naprawdę niejasny i nieprzydatny komunikat o błędzie. Po wielu próbach i błędach stwierdziłem, że LocalDateTimewystąpi powyższy błąd, jeśli nie spróbujesz przeanalizować czasu. Używając LocalDatezamiast tego, działa bez błędów.

Jest to słabo udokumentowane, a powiązany wyjątek jest bardzo nieprzydatny.

Tom B.
źródło
25

Poszerzenie odpowiedzi na temat retrografii …: Miałem ten sam problem, nawet gdy go używałem, LocalDatea nie LocalDateTime. Problem polegał na tym, że stworzyłem DateTimeFormatterużycie .withResolverStyle(ResolverStyle.STRICT);, więc musiałem użyć wzorca daty uuuuMMddzamiast yyyyMMdd(tj. „Rok” zamiast „roku ery”)!

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

(To rozwiązanie było początkowo komentarzem do odpowiedzi retrograficznej, ale zachęcono mnie do opublikowania go jako samodzielnej odpowiedzi, ponieważ najwyraźniej działa naprawdę dobrze dla wielu ludzi.)

Zero jeden
źródło
1
Odpowiedź na pytanie, dlaczego „u” zamiast „y” znajduje się w tym linku uuuu-versus-yyyy-in-datetimeformatter-formatting-pattern- cods -in-java @Peru
prashanth
23

Dla każdego, kto wylądował tutaj z tym błędem, tak jak ja:

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

Pochodzi z następującej linii:

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

Okazało się, że to dlatego, że użyłem wzoru 12-godzinnego na godzinę 0, zamiast wzoru 24-godzinnego.

Zmiana wzoru godzinowego na 24-godzinny za pomocą dużego H rozwiązuje ten problem:

LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy H:mm"));
mawburn
źródło
12

Jeśli ciąg daty nie zawiera żadnej wartości dla godzin, minut itp., Nie można bezpośrednio przekonwertować tego na plik LocalDateTime. Możesz go przekonwertować tylko na a LocalDate, ponieważ łańcuch reprezentuje tylko składniki roku, miesiąca i daty , które byłoby poprawne.

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

W każdym razie możesz przekonwertować to na 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
główny
źródło
Upewnij się również, że format jest prawidłowy. Ta poprawka nie zadziałała, dopóki nie ustawiłem formatu na taki yyyy-mm-dd, jaki powinien yyyy-MM-dd.
patstuart
0

Spróbuj tego:

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

Możesz dodać dowolny format. To działa dla mnie!

Vinay Kasarla
źródło
0

To działa dobrze

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

wynik:

VALUE=2018-08-16
VALUE1=2018-08-16T12:10
Jeff Cook
źródło