Não foi possível obter o LocalDateTime do TemporalAccessor ao analisar o LocalDateTime (Java 8)

151

Estou simplesmente tentando converter uma string de data em um objeto DateTime em Java 8. Ao executar as seguintes linhas:

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

Estou tendo o erro a seguir:

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)

A sintaxe é idêntica ao que foi sugerido aqui , mas sou atendido com uma exceção. Eu estou usando JDK-8u25.

retrografia
fonte

Respostas:

177

Acontece que o Java não aceita um valor de Data simples como DateTime. Usar LocalDate em vez de LocalDateTime resolve o problema:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate dt = LocalDate.parse("20140218", formatter);
retrografia
fonte
42
Pelo que vale a pena: eu tive esse mesmo problema mesmo quando LocalDateestava usando e não LocalDateTime. O problema foi que eu criei meu DateTimeFormatteruso .withResolverStyle(ResolverStyle.STRICT);, então tive que usar o padrão de data em uuuuMMddvez de yyyyMMdd(por exemplo, "ano" em vez de "ano da era")!
ZeroOne
72

Se você realmente precisar transformar uma data em um objeto LocalDateTime, poderá usar o LocalDate.atStartOfDay (). Isso fornecerá um objeto LocalDateTime na data especificada, com os campos de hora, minuto e segundo definidos como 0:

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay();
Øyvind Mo
fonte
2
Correção: defina para qualquer hora que fosse no início desse dia .
Trejkaz
20
LocalDateTime.fromparece desnecessário, como atStartOfDay()já retorna LocalDateTime.
Dariusz
1
scala: val time = LocalDate.parse ("20171220", DateTimeFormatter.ofPattern ("aaaaMMdd")). atStartOfDay.format (DateTimeFormatter.ofPattern ("aaaa-MM-dd HH: mm: ss"))
Woody Sun
48

Pelo que vale a pena se alguém ler novamente este tópico (como eu), a resposta correta estaria em DateTimeFormatterdefinição, por exemplo:

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

Deve-se definir os campos opcionais se eles aparecerem. E o restante do código deve ser exatamente o mesmo.

Iulian David
fonte
1
Esta é a verdadeira solução universal, por exemplo, para esse método: Long getFileTimestamp (arquivo String, padrão, DateTimeFormatter dtf, int group); Aqui você tem diferentes padrões e DateTimeFormetter, com e sem tempo especificado.
toootooo
Pode ser um campo estático? Eu não encontrei na Javadoc que uma instância criada dessa forma é thread-safe
Kamil Roman
Lembre-se de adicionar o parseDefaultingAPÓS que você ligou appendPattern. Caso contrário, vai dar DateTimeParseException.
Wittyameta
31

Esta é uma mensagem de erro realmente pouco clara e inútil. Depois de muitas tentativas e erros, descobri que LocalDateTimefornecerá o erro acima se você não tentar analisar um tempo. Ao usar LocalDate, ele funciona sem erros.

Isso está mal documentado e a exceção relacionada é muito inútil.

Tom B
fonte
25

Expandindo a resposta da retrografia ..: Eu tive esse mesmo problema mesmo quando LocalDateestava usando e não LocalDateTime. O problema foi que eu criei meu DateTimeFormatteruso .withResolverStyle(ResolverStyle.STRICT);, então tive que usar o padrão de data em uuuuMMddvez de yyyyMMdd(por exemplo, "ano" em vez de "ano da era")!

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

(Esta solução foi originalmente um comentário à resposta da retrografia, mas fui encorajado a publicá-la como uma resposta autônoma, porque aparentemente funciona muito bem para muitas pessoas.)

Zero um
fonte
1
A resposta para isso "u" em vez de "y" foi respondida nesta ligação uuuu-versus-aaaa-in-DateTimeFormatter-padrão códigos de formatação em java @Peru
prashanth
23

Para quem chegou aqui com esse erro, como eu fiz:

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

Veio de uma linha a seguir:

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

Acabou que era porque eu estava usando um padrão de 12 horas em uma hora 0, em vez de um padrão de 24 horas.

Alterar a hora para o padrão de 24 horas usando H maiúsculo corrige:

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

Se a data String não incluir nenhum valor por horas, minutos e etc., você não poderá convertê-lo diretamente em a LocalDateTime. Você só pode convertê-lo em a LocalDate, porque a string representa apenas os componentes de ano, mês e data que seria a coisa correta a fazer.

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

De qualquer forma, você pode converter isso em 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
fonte
Verifique também se o formato está correto. Essa correção não funcionou para mim até porque eu configurei o formato para yyyy-mm-ddquando deveria ter sido yyyy-MM-dd.
patstuart
0

Tente este:

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

Você pode adicionar qualquer formato que desejar. Isso funciona para mim!

Vinay Kasarla
fonte
0

Isso funciona bem

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

resultado:

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