Impossibile ottenere LocalDateTime da TemporalAccessor durante l'analisi di LocalDateTime (Java 8)


151

Sto semplicemente cercando di convertire una stringa di data in un oggetto DateTime in Java 8. Dopo aver eseguito le seguenti righe:

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

Ottengo il seguente errore:

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 sintassi è identica a ciò che è stato suggerito qui , eppure mi viene servita un'eccezione. Sto usando JDK-8u25.

Risposte:


177

Si scopre che Java non accetta un valore Date nudo come DateTime. L'uso di LocalDate anziché LocalDateTime risolve il problema:

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

42
Per quello che vale: ho avuto lo stesso problema anche durante l'utilizzo LocalDatee non LocalDateTime. Il problema era che avevo creato il mio DateTimeFormatterutilizzo .withResolverStyle(ResolverStyle.STRICT);, quindi dovevo usare il modello di data uuuuMMddinvece di yyyyMMdd(cioè "anno" anziché "anno-era-epoca")!
ZeroOne,

72

Se è davvero necessario trasformare una data in un oggetto LocalDateTime, è possibile utilizzare LocalDate.atStartOfDay (). Questo ti darà un oggetto LocalDateTime alla data specificata, con i campi ora, minuti e secondi impostati su 0:

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

2
Correzione: impostare a qualsiasi ora sarebbe all'inizio di quel giorno .
Trejkaz,

20
LocalDateTime.fromsembra inutile, come atStartOfDay()già ritorna 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

Per quanto vale se qualcuno dovesse rileggere questo argomento (come me) la risposta corretta sarebbe in DateTimeFormatterdefinizione, ad esempio:

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

Uno dovrebbe impostare i campi opzionali se appariranno. E il resto del codice dovrebbe essere esattamente lo stesso.


1
Questa è la vera soluzione universale per esempio per tale metodo: Long getFileTimestamp (file String, Pattern pattern, DateTimeFormatter dtf, int group); Qui hai diversi schemi e DateTimeFormetter, senza tempo specificato.
toootooo,

Può essere un campo statico? Non ho trovato nel Javadoc che un'istanza creata in quel modo sia thread-safe
Kamil Roman

Ricorda di aggiungere il parseDefaultingDOPO che hai chiamato appendPattern. Altrimenti darà DateTimeParseException.
wittyameta,

31

Questo è un messaggio di errore davvero poco chiaro e inutile. Dopo molte prove ed errori ho scoperto che LocalDateTimedarà l'errore sopra se non si tenta di analizzare un tempo. Usando LocalDateinvece, funziona senza errori.

Ciò è scarsamente documentato e la relativa eccezione non è molto utile.


25

Espandendo la risposta della retrografia ..: ho avuto lo stesso problema anche durante l'utilizzo LocalDatee non LocalDateTime. Il problema era che avevo creato il mio DateTimeFormatterutilizzo .withResolverStyle(ResolverStyle.STRICT);, quindi dovevo usare il modello di data uuuuMMddinvece di yyyyMMdd(cioè "anno" anziché "anno-era-epoca")!

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

(Questa soluzione era originariamente un commento alla risposta della retrografia, ma sono stato incoraggiato a pubblicarlo come risposta autonoma perché apparentemente funziona davvero bene per molte persone.)


1
La risposta al perché "u" al posto di "y" è stata risolta in questo link uuuu-versus-aaaa-in-DateTimeFormatter-formattazione-modello-codici-in-java @Peru
Prashanth

23

Per chiunque sia arrivato qui con questo errore, come ho fatto io:

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

Veniva da una delle seguenti righe:

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

Si è scoperto che era perché stavo usando un modello 12 ore su 0 ore, anziché un modello 24 ore.

Cambiando l'ora a 24 ore usando una maiuscola H si risolve:

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

12

Se la stringa della data non include alcun valore per ore, minuti e così via, non è possibile convertirla direttamente in a LocalDateTime. Puoi solo convertirlo in a LocalDate, perché la stringa rappresenta solo i componenti di anno, mese e data che sarebbe la cosa giusta da fare.

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

Ad ogni modo puoi convertirlo in 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

Assicurati anche che il formato sia corretto. Questa correzione non ha funzionato per me fino a quando ho impostato il formato su yyyy-mm-ddquando avrebbe dovuto essere yyyy-MM-dd.
patstuart,

0

Prova questo:

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

Puoi aggiungere qualsiasi formato desideri. Per me va bene!


0

Funziona benissimo

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

produzione:

VALUE=2018-08-16
VALUE1=2018-08-16T12:10
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.