Problema di formato data con DateTimeFormatter [duplicato]
Ho una data nel seguente formato: 1/1/2020 3:4:7 AMSto cercando di formattarla usando DateTimeFormatter.
Ho il seguente codice con un formattatore per analizzarlo, ma non funziona.
LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
Ottengo la seguente eccezione:
java.time.format.DateTimeParseException: Text '1/1/2020 3:4:7 AM' could not be parsed at index 0
Qualcuno può aiutarmi?
Risposte
Due problemi separati:
Conteggi sbagliati
Stai usando, ad esempio, MMche è un esplicito: sempre l'intero numero di cifre, con riempimento zero. La tua stringa non è così, è solo il numero. Quindi, fallo M/d/uuuu h:m:s a.
EDIT: cambiato yyyyin uuuu, grazie, @deHaar. Ragionamento: yyyy o uuuu raramente sono importanti, ma tieni presente che questo significa che sono richieste 4 cifre . La differenza inizia per anni prima dello 0: uuuudiventa negativa, yyyynon si aspetta che tu usi, ad esempio, in GGmodo da ottenere 44 BCinvece di -44. In questo modo, uuuuè solo più corretto, anche se di solito la differenza non verrà fuori.
Località mancante
Il secondo problema è che non dovresti praticamente mai usare questa versione di ofPattern: ha un bug, che non puoi catturare con i test unitari, il che lo rende un bug migliaia di volte più `` pesante '' e quindi un vero problema .
Devi specificare la localizzazione. Senza di esso, "AM" non analizzerà a meno che la lingua predefinita della piattaforma non sia l'inglese.
Mettendolo insieme
LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM",
DateTimeFormatter.ofPattern("M/d/uuuu h:m:s a", Locale.ENGLISH));
funziona alla grande.
Nel tuo snippet:
LocalDateTime
.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
1- non corrispondeMM1- non corrispondedd3- non corrispondehh4- non corrispondemm7- non corrispondess
cioè le lunghezze delle parti del pattern del formattatore (ad esempio MM) e le rispettive parti dal testo della stringa (ad esempio 1) non corrispondono.
Puoi abbinarli in diversi modi, ad esempio puoi cambiare il testo della stringa in modo che corrisponda al modello del formattatore o in altro modo.
Puoi provare questo invece:
LocalDateTime
.parse("01/01/2020 03:04:07 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
Inoltre, dai un'occhiata alle lettere e ai simboli del modello .
Utilizzare lettere singole per i componenti di data e ora (mese, giorno, anno, ora, minuti e secondi).
Puoi anche fare in modo che il formattatore gestisca il modello in modo insensibile al maiuscolo / minuscolo (ad esempio am, AM, Am) come mostrato di seguito:
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); } }
Produzione:
2020-01-01T03:04:07
Secondo la documentazione di DateTimeFormatter :
Numero: se il conteggio delle lettere è uno , il valore viene emesso utilizzando il numero minimo di cifre e senza riempimento. Altrimenti, il conteggio delle cifre viene utilizzato come larghezza del campo di output, con il valore riempito con zero se necessario.
Invertendo il ragionamento, puoi provare a utilizzare questo formattatore invece:
DateTimeFormatter.ofPattern("M/d/yyyy h:m:s a")