Anleitung zu DateTimeFormatter

1. Übersicht

In diesem Tutorial werden die Java 8 DateTimeFormatter- Klasse und ihre Formatierungsmuster überprüft . Wir werden auch mögliche Anwendungsfälle für diese Klasse diskutieren.

Wir können DateTimeFormatter verwenden, um Datums- und Uhrzeitangaben in einer App mit vordefinierten oder benutzerdefinierten Mustern einheitlich zu formatieren.

2. DateTimeFormatter mit vordefinierten Instanzen

DateTimeFormatter enthält mehrere vordefinierte Datums- / Zeitformate , die den ISO- und RFC-Standards entsprechen. Beispielsweise können wir die ISO_LOCAL_DATE- Instanz verwenden, um ein Datum wie '2018-03-09' zu analysieren:

DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.of(2018, 3, 9));

Um ein Datum mit einem Versatz zu analysieren, können wir ISO_OFFSET_DATE verwenden , um eine Ausgabe wie '2018-03-09-03: 00' zu erhalten:

DateTimeFormatter.ISO_OFFSET_DATE.format(LocalDate.of(2018, 3, 9).atStartOfDay(ZoneId.of("UTC-3")));

Die meisten vordefinierten Instanzen der DateTimeFormatter- Klasse konzentrieren sich auf den Standard ISO-8601. ISO-8601 ist ein internationaler Standard für die Formatierung von Datum und Uhrzeit.

Es gibt jedoch eine andere vordefinierte Instanz, die RFC-1123, Anforderung für Internet-Hosts, analysiert und von der IETF veröffentlicht wird:

DateTimeFormatter.RFC_1123_DATE_TIME.format(LocalDate.of(2018, 3, 9).atStartOfDay(ZoneId.of("UTC-3")));

Dieses Snippet generiert ' Fr, 9. März 2018 00:00:00 -0300 '.

Manchmal müssen wir das Datum, das wir erhalten, als Zeichenfolge eines bekannten Formats bearbeiten. Wir können die parse () -Methode verwenden:

LocalDate.from(DateTimeFormatter.ISO_LOCAL_DATE.parse("2018-03-09")).plusDays(3);

Das Ergebnis dieses Code-Snippets ist eine LocalDate- Darstellung für den 12. März 2018.

3. DateTimeFormatter mit FormatStyle

Manchmal möchten wir Daten auf eine für Menschen lesbare Weise drucken.

In solchen Fällen können wir mit unserem DateTimeFormatter die Werte der Aufzählung java.time.format.FormatStyle (FULL, LONG, MEDIUM, SHORT) verwenden :

LocalDate anotherSummerDay = LocalDate.of(2016, 8, 23); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(anotherSummerDay)); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).format(anotherSummerDay)); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(anotherSummerDay)); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(anotherSummerDay));

Die Ausgabe dieser verschiedenen Formatierungsstile desselben Datums lautet:

Tuesday, August 23, 2016 August 23, 2016 Aug 23, 2016 8/23/16

Wir können auch vordefinierte Formatierungsstile für Datum und Uhrzeit verwenden. Um FormatStyle mit der Zeit zu verwenden, müssen wir die ZonedDateTime- Instanz verwenden. Andernfalls wird eine DateTimeException ausgelöst:

LocalDate anotherSummerDay = LocalDate.of(2016, 8, 23); LocalTime anotherTime = LocalTime.of(13, 12, 45); ZonedDateTime zonedDateTime = ZonedDateTime.of(anotherSummerDay, anotherTime, ZoneId.of("Europe/Helsinki")); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL) .format(zonedDateTime)); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG) .format(zonedDateTime)); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) .format(zonedDateTime)); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT) .format(zonedDateTime));

Beachten Sie, dass wir diesmal die Methode ofLocalizedDateTime () von DateTimeFormatter verwendet haben.

Und die Ausgabe, die wir erhalten, ist:

Tuesday, August 23, 2016 1:12:45 PM EEST August 23, 2016 1:12:45 PM EEST Aug 23, 2016 1:12:45 PM 8/23/16 1:12 PM

Wir können auch verwenden FormatStyle ein Datum Zeit zu analysieren String Umwandlung in ZonedDateTime , zum Beispiel.

Wir können dann den analysierten Wert verwenden, um die Datums- und Zeitvariable zu manipulieren:

ZonedDateTime dateTime = ZonedDateTime.from( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL) .parse("Tuesday, August 23, 2016 1:12:45 PM EET")); System.out.println(dateTime.plusHours(9));

Die Ausgabe dieses Snippets lautet "2016-08-23T22: 12: 45 + 03: 00 [Europa / Bukarest]". Beachten Sie, dass sich die Zeit auf "22:12:45" geändert hat.

4. DateTimeFormatter mit benutzerdefinierten Formaten

Vordefinierte und integrierte Formatierer und Stile können viele Situationen abdecken . Manchmal müssen wir jedoch Datum und Uhrzeit etwas anders formatieren. Hier kommen benutzerdefinierte Formatierungsmuster ins Spiel.

4.1. DateTimeFormatter für Datum

Angenommen, wir möchten ein java.time.LocalDate- Objekt in einem regulären europäischen Format wie dem 31.12.2018 präsentieren. Dazu könnten wir die Factory-Methode DateTimeFormatter aufrufen . ofPattern ("TT.MM.JJJJ").

Dadurch wird eine geeignete DateTimeFormatter- Instanz erstellt, mit der wir unser Datum formatieren können:

String europeanDatePattern = "dd.MM.yyyy"; DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern(europeanDatePattern); System.out.println(europeanDateFormatter.format(LocalDate.of(2016, 7, 31)));

Die Ausgabe dieses Code-Snippets lautet "31.07.2016".

Es gibt viele verschiedene Musterbuchstaben, mit denen wir ein Format für Daten erstellen können, das unseren Anforderungen entspricht:

 Symbol Meaning Presentation Examples ------ ------- ------------ ------- u year year 2004; 04 y year-of-era year 2004; 04 M/L month-of-year number/text 7; 07; Jul; July; J d day-of-month number 10

Dies ist ein Auszug aus der offiziellen Java-Dokumentation zur DateTimeFormatter- Klasse.

Die Anzahl der Buchstaben im Musterformat ist signifikant .

Wenn wir ein zweistelliges Muster für den Monat verwenden, erhalten wir eine zweistellige Monatsdarstellung. Wenn die Monatszahl kleiner als 10 ist, wird sie mit einer Null aufgefüllt. Wenn wir die erwähnte Auffüllung mit Nullen nicht benötigen, können wir ein Ein-Buchstaben-Muster "M" verwenden, das den Januar als "1" anzeigt.

Wenn wir zufällig ein aus vier Buchstaben bestehendes Muster für den Monat "MMMM" verwenden, erhalten wir eine Darstellung in "vollständiger Form". In unserem Beispiel ist es "Juli". Ein 5-Buchstaben-Muster, "MMMMM", lässt den Formatierer die "schmale Form" verwenden. In unserem Fall würde "J" verwendet.

Ebenso kann ein benutzerdefiniertes Formatierungsmuster verwendet werden, um eine Zeichenfolge zu analysieren, die ein Datum enthält:

DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); System.out.println(LocalDate.from(europeanDateFormatter.parse("15.08.2014")).isLeapYear());

Dieses Code-Snippet prüft, ob das Datum „ 15.08.2014 “ ein Schaltjahr ist und nicht.

4.2. DateTimeFormatter für Zeit

Es gibt auch Musterbuchstaben, die für Zeitmuster verwendet werden können:

 Symbol Meaning Presentation Examples ------ ------- ------------ ------- H hour-of-day (0-23) number 0 m minute-of-hour number 30 s second-of-minute number 55 S fraction-of-second fraction 978 n nano-of-second number 987654321

Es ist ganz einfach, DateTimeFormatter zum Formatieren einer java.time.LocalTime- Instanz zu verwenden. Angenommen, wir möchten die durch einen Doppelpunkt getrennte Zeit (Stunden, Minuten und Sekunden) anzeigen:

String timeColonPattern = "HH:mm:ss"; DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern); LocalTime colonTime = LocalTime.of(17, 35, 50); System.out.println(timeColonFormatter.format(colonTime));

Dies erzeugt die Ausgabe „ 17:35:50 “.

Wenn wir der Ausgabe Millisekunden hinzufügen möchten, sollten wir dem Muster "SSS" hinzufügen:

String timeColonPattern = "HH:mm:ss SSS"; DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern); LocalTime colonTime = LocalTime.of(17, 35, 50).plus(329, ChronoUnit.MILLIS); System.out.println(timeColonFormatter.format(colonTime));

Was die Ausgabe „ 17:35:50 329 “ ergibt .

Beachten Sie, dass „HH“ ein Stunden-Stunden-Muster ist, das die Ausgabe von 0-23 generiert. Wenn wir AM / PM anzeigen möchten, sollten wir stundenlang Kleinbuchstaben "hh" verwenden und ein "a" -Muster hinzufügen:

String timeColonPattern = "hh:mm:ss a"; DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern); LocalTime colonTime = LocalTime.of(17, 35, 50); System.out.println(timeColonFormatter.format(colonTime));

Die generierte Ausgabe lautet „ 05:35:50 PM “.

We may want to parse time String with our custom formatter and check if it is before noon:

DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss a"); System.out.println(LocalTime.from(timeFormatter.parse("12:25:30 AM")).isBefore(LocalTime.NOON));

The output of this last snippet shows that the given time is actually before noon.

4.3. DateTimeFormatter for Time Zones

Often we want to see a time zone of some specific date-time variable. If we happen to use New York-based date-time (UTC -4), we may use “z” pattern-letter for time-zone name:

String newYorkDateTimePattern = "dd.MM.yyyy HH:mm z"; DateTimeFormatter newYorkDateFormatter = DateTimeFormatter.ofPattern(newYorkDateTimePattern); LocalDateTime summerDay = LocalDateTime.of(2016, 7, 31, 14, 15); System.out.println(newYorkDateFormatter.format(ZonedDateTime.of(summerDay, ZoneId.of("UTC-4"))));

This will generate the output “31.07.2016 14:15 UTC-04:00”.

We can parse date time strings with time zones just like we did earlier:

DateTimeFormatter zonedFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm z"); System.out.println(ZonedDateTime.from(zonedFormatter.parse("31.07.2016 14:15 GMT+02:00")).getOffset().getTotalSeconds());

The output of this code is “7200” seconds, or 2 hours, as we'd expect.

Wir müssen sicherstellen, dass wir der parse () -Methode eine korrekte Datums- und Uhrzeitzeichenfolge zur Verfügung stellen . Wenn wir "31.07.2016 14:15" ohne Zeitzone an den zonedFormatter aus dem letzten Code-Snippet übergeben, erhalten wir eine DateTimeParseException .

5. Schlussfolgerung

In diesem Tutorial haben wir erläutert, wie die DateTimeFormatter- Klasse zum Formatieren von Datum und Uhrzeit verwendet wird. Wir haben reale Beispielmuster verwendet, die häufig bei der Arbeit mit Datums- und Uhrzeitinstanzen auftreten.

Weitere Informationen zur Java 8 Date / Time API finden Sie in früheren Tutorials. Wie immer ist der im Tutorial verwendete Quellcode über GitHub verfügbar.