Java DateTimeFormatter não está analisando conforme o esperado [duplicado]

Sep 02 2020

Tentei DateTimeFormatter para analisar a data de entrada dd/MM/yyyy. Eu usei o código abaixo

java.time.format.DateTimeFormatter está falhando em analisar a data

  DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy").withResolverStyle(ResolverStyle.STRICT);
    
       
            try {
                LocalDate.parse(dateField, dateFormatter);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        
        return true;
    }

Entrada: 30/04/2018

Error:Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {MonthOfYear=4, YearOfEra=2018, DayOfMonth=30},ISO of type java.time.format.Parsed

Também está falhando por anos bissextos.

Respostas

1 deHaar Sep 02 2020 at 13:47

Você tem basicamente duas opções (aqui, onde uma está usando o que ResolverStylevocê está mostrando em seu exemplo de código):

  • use ResolverStyle.STRICTexplicitamente ⇒ analisa apenas o ano u
  • use um padrão ResolverStyle⇒ ano de época y ou ano u será analisado

O exemplo a seguir mostra as diferenças no código:

public static void main(String[] args) {
    String date = "30/04/2018";
    // first formatter with year-of-era but no resolver style
    DateTimeFormatter dtfY = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    // second one with year and a strict resolver style
    DateTimeFormatter dtfU = DateTimeFormatter.ofPattern("dd/MM/uuuu")
                                                .withResolverStyle(ResolverStyle.STRICT);
    // parse
    LocalDate localDateU = LocalDate.parse(date, dtfU);
    LocalDate localDateY = LocalDate.parse(date, dtfY);
    // print results
    System.out.println(localDateU);
    System.out.println(localDateY);
}

A saída é

2018-04-30
2018-04-30

portanto, ambos DateTimeFormattersão analisados ​​da mesma forma String, mas aquele sem um ResolverStyleexplicitamente anexado será usado ResolverStyle.SMARTpor padrão de acordo com os JavaDocs deDateTimeFormatter .

Claro, um padrão com ano ( u) será analisado por ResolverStyle.SMART, também,

DateTimeFormatter.ofPattern("dd/MM/uuuu");

seria uma opção também.

Uma boa explicação da diferença entre ano de época e ano pode ser encontrada neste post .

3 layonez Sep 02 2020 at 13:43

O problema é usar .withResolverStyle(ResolverStyle.STRICT)requer o uso do padrão de ano uuuu em vez de yyyy (ou seja, "ano" em vez de "ano da era")