Problema de formato de data com DateTimeFormatter [duplicado]
Tenho uma data no seguinte formato: 1/1/2020 3:4:7 AMEstou tentando formatar usando DateTimeFormatter.
Eu tenho o seguinte código com um formatador para analisá-lo, mas não funciona.
LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
Eu recebo a seguinte exceção:
java.time.format.DateTimeParseException: Text '1/1/2020 3:4:7 AM' could not be parsed at index 0
Alguém pode me ajudar?
Respostas
Dois problemas separados:
Contagens erradas
Você está usando, por exemplo, MMque é um explícito: Sempre a quantidade total de dígitos, preenchido com zeros. Sua string não é assim, é apenas o número. Então, faça isso M/d/uuuu h:m:s a.
EDIT: Alterado yyyypara uuuu, obrigado, @deHaar. Raciocínio: yyyy ou uuuu raramente importa, mas observe que isso significa que são necessários 4 dígitos . A diferença entra em ação anos antes de 0: uuuufica negativo, yyyynão faz e espera que você use, por exemplo, GGpara obter em 44 BCvez de -44. Dessa forma, uuuué apenas mais correto, embora normalmente a diferença não vá aparecer.
Localidade ausente
O segundo problema é que você quase nunca deve usar essa versão do ofPattern- ela tem um bug, que você não consegue detectar com testes de unidade, o que o torna um bug que é milhares de vezes "pesado" e, portanto, um problema real .
Você precisa especificar o local. Sem ele, 'AM' não analisará, a menos que o local padrão da plataforma seja o inglês.
Juntar as peças
LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM",
DateTimeFormatter.ofPattern("M/d/uuuu h:m:s a", Locale.ENGLISH));
funciona bem.
Em seu snippet:
LocalDateTime
.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
1- não correspondeMM1- não correspondedd3- não correspondehh4- não correspondemm7- não correspondess
ou seja, os comprimentos das partes do padrão do formatador (por exemplo MM) e suas respectivas partes do texto da string (por exemplo 1) não correspondem.
Você pode combiná-los de algumas maneiras, por exemplo, você pode alterar o texto da string para corresponder ao padrão do formatador ou de outra forma.
Você pode tentar isso:
LocalDateTime
.parse("01/01/2020 03:04:07 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
Além disso, dê uma olhada nas letras e símbolos de padrão .
Use letras únicas para componentes de data e hora (mês, dia, ano, hora, minuto e segundo).
Você também pode fazer o formatador lidar com o padrão sem diferenciar maiúsculas de minúsculas (por exemplo, am, AM, Am), conforme mostrado abaixo:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.util.Locale; public class Main { public static void main(String[] args) { // Formatter to handle the pattern in case insensitive way (e.g. am, AM, Am) DateTimeFormatter formatter = new DateTimeFormatterBuilder() .parseCaseInsensitive() .appendPattern("M/d/u h:m:s a") .toFormatter(Locale.ENGLISH); LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", formatter); System.out.println(date); } }
Resultado:
2020-01-01T03:04:07
De acordo com a documentação do DateTimeFormatter :
Número: se a contagem de letras for um , o valor será emitido usando o número mínimo de dígitos e sem preenchimento. Caso contrário, a contagem de dígitos é usada como a largura do campo de saída, com o valor preenchido com zeros conforme necessário.
Ao inverter o raciocínio, você pode tentar usar este formatador:
DateTimeFormatter.ofPattern("M/d/yyyy h:m:s a")