Impossibile analizzare il timestamp Problema java.time.format.DateTimeParseException: impossibile analizzare il testo "9/25/2020, 12:46:00 PM" all'indice 0 [duplicato]
Sto tentando di acquisire l'ora prima e dopo aver controllato un valore di timestamp su una pagina Web e quindi confermare che il mio timestamp rientri tra quei tempi. Tuttavia, sto lottando per convertire il mio timestamp String in un formato comparabile in modo pulito.
Instant b4 = Instant.now();
//My code submites a file that then triggers the timestamp. I retrieve it as a string
//exa string"9/25/2020, 11:03:18 AM"
DateTimeFormatter dtf = DateTimeFormatter
.ofPattern("MM/dd/yyyy, HH:mm:ss a")
.withZone(ZoneId.systemDefault());
Instant instantTimestamp = Instant.from(dtf.parse(timeStamp));
Instant after = Instant.now();
if (instantTimestamp.isAfter(b4) && instantTimestamp.isBefore(after)) {
testPass = true;
}
Assert.assertTrue(testPass);
Errore: java.time.format.DateTimeParseException: impossibile analizzare il testo "9/25/2020, 12:46:00 PM" all'indice 0
Risposte
C'è una mancata corrispondenza nel formato per il mese e il suo valore nella stringa. Il formato è MMche specifica due cifre ma il valore 9è una singola cifra. È possibile utilizzare singole lettere per mese, giorno, anno, ora, minuti, secondi ecc. Per contenere tutto il numero di cifre consentito. Inoltre, ti suggerisco di analizzarlo in modo che non faccia distinzione tra maiuscole e minuscole in modo che le lettere maiuscole e minuscole (ad esempio AMe am) possano essere adattate.
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Given date-time string
String dateTimeString = "9/25/2020, 12:46:00 PM";
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("M/d/u, H:m:s a")
.toFormatter(Locale.ENGLISH);
// Convert the given date-time string to LocalDateTime
LocalDateTime ldt = LocalDateTime.parse(dateTimeString, dtf);
System.out.println(ldt);
//Convert to LocalDateTime Instant if required
Instant instant=ldt.toInstant(ZoneOffset.UTC);
System.out.println(instant);
}
}
Produzione:
2020-09-25T12:46
2020-09-25T12:46:00Z
L'errore è dovuto alla stringa di formato utilizzata. "MM" richiede che la parte relativa al mese della stringa di input sia composta esattamente da due cifre, ma "9" è solo una cifra. In altre parole, funziona per "25/09/2020, 11:03:18", ma non per "25/09/2020, 11:03:18".
Quello che serve qui è "M", che non richiede che il valore sia preceduto da "0":
DateTimeFormatter dtf = DateTimeFormatter
.ofPattern("M/dd/yyyy, HH:mm:ss a")
.withZone(ZoneId.systemDefault());
Se la data deve essere anche una singola cifra e non 0 riempita per i giorni 0-9, il "M/d/yyyy, HH:mm:ss a"modello dovrebbe essere utilizzato invece.
Questo è descritto dai DateTimeFormatterJavadoc:
Tutte le lettere dalla "A" alla "Z" e dalla "a" alla "z" sono riservate come lettere modello. Vengono definite le seguenti lettere del modello:
Symbol Meaning Presentation Examples ------ ------- ------------ ------- [...] M/L month-of-year number/text 7; 07; Jul; July; J [...]Testo: [...]
Numero: se il conteggio delle lettere è uno, il valore viene emesso utilizzando il numero minimo di cifre e senza riempimento. In caso contrario, il conteggio delle cifre viene utilizzato come larghezza del campo di output, con il valore riempito con zero se necessario. [...]
Numero / Testo: se il numero di lettere del motivo è 3 o superiore, utilizzare le regole di testo sopra. Altrimenti usa le regole del numero sopra.
Poiché "M" usa la presentazione "numero / testo" e il conteggio delle sue lettere il tuo formato ("MM") è 2, allora richiede esattamente due cifre per il mese. Il passaggio a una singola "M" fa sì che utilizzi il numero minimo di cifre (una cifra per i mesi 1-9 e due cifre per i mesi 10-12).