Datumsformatproblem mit DateTimeFormatter [Duplikat]

Oct 05 2020

Ich habe ein Datum im folgenden Format: 1/1/2020 3:4:7 AMIch versuche es mit zu formatieren DateTimeFormatter.

Ich habe den folgenden Code mit einem Formatierer, um ihn zu analysieren, aber er funktioniert nicht.

LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));

Ich bekomme folgende Ausnahme:

java.time.format.DateTimeParseException: Text '1/1/2020 3:4:7 AM' could not be parsed at index 0

Kann mir jemand helfen?

Antworten

7 rzwitserloot Oct 05 2020 at 21:07

Zwei getrennte Probleme:

Falsche Zählungen

Sie verwenden zB MMeine explizite: Immer die volle Anzahl von Ziffern, nullgefüllt. Ihre Zeichenfolge ist nicht so, es ist nur die Zahl. Also mach das M/d/uuuu h:m:s a.

EDIT: Geändert yyyyzu uuuu, danke, @deHaar. Begründung: JJJJ oder UUUU spielen selten eine Rolle, aber beachten Sie, dass dies bedeutet, dass 4 Stellen erforderlich sind . Die Differenz Tritte in für die Jahre vor 0: uuuunegativ wird , yyyynicht und erwartet Sie zum Beispiel verwenden , GGso dass Sie erhalten 44 BCstatt -44. Auf diese Weise uuuuist es nur korrekter, obwohl normalerweise der Unterschied nicht auftauchen wird.

Fehlendes Gebietsschema

Das zweite Problem ist, dass Sie diese Version von so gut wie nie verwenden sollten ofPattern- sie hat einen Fehler, den Sie mit Unit-Tests nicht abfangen können, was diesen Fehler zu einem tausendmal "schwereren" und damit zu einem echten Problem macht .

Sie müssen das Gebietsschema angeben. Ohne diese Option wird 'AM' nur analysiert, wenn das Standardgebietsschema Ihrer Plattform Englisch ist.

Etwas zusammensetzen

LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM",
  DateTimeFormatter.ofPattern("M/d/uuuu h:m:s a", Locale.ENGLISH));

funktioniert super.

3 GiorgiTsiklauri Oct 05 2020 at 21:09

In Ihrem Snippet:

LocalDateTime
    .parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
  • 1 - stimmt nicht überein MM
  • 1 - stimmt nicht überein dd
  • 3 - stimmt nicht überein hh
  • 4 - stimmt nicht überein mm
  • 7 - stimmt nicht überein ss

dh die Längen der Formatierungsmusterteile (z. B. MM) und ihrer jeweiligen Teile aus dem Zeichenfolgentext (z. B. 1) stimmen nicht überein.

Sie können sie auf verschiedene Arten abgleichen, z. B. können Sie entweder den Zeichenfolgentext so ändern , dass er dem Formatierungsmuster entspricht, oder umgekehrt.

Sie können dies stattdessen versuchen:

LocalDateTime
    .parse("01/01/2020 03:04:07 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));

Schauen Sie sich außerdem die Musterbuchstaben und -symbole an .

3 LiveandLetLive Oct 05 2020 at 21:05
  1. Verwenden Sie einzelne Buchstaben für Datums- und Zeitkomponenten (Monat, Tag, Jahr, Stunde, Minute und Sekunde).

  2. Sie können den Formatierer auch dazu bringen, das Muster ohne Berücksichtigung der Groß- und Kleinschreibung zu behandeln (z. B. am, AM, Am), wie unten gezeigt:

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

Ausgabe:

2020-01-01T03:04:07
2 0009laH Oct 05 2020 at 21:08

Gemäß der Dokumentation von DateTimeFormatter :

Anzahl: Wenn die Anzahl der Buchstaben eins ist , wird der Wert mit der minimalen Anzahl von Ziffern und ohne Auffüllen ausgegeben . Andernfalls wird die Anzahl der Ziffern als Breite des Ausgabefelds verwendet, wobei der Wert bei Bedarf mit Nullen aufgefüllt wird.

Wenn Sie die Argumentation umkehren, können Sie stattdessen versuchen, diesen Formatierer zu verwenden:

DateTimeFormatter.ofPattern("M/d/yyyy h:m:s a")