Daten in Java vergleichen

1. Einleitung

In diesem Tutorial konzentrieren wir uns darauf, wie Sie Daten mithilfe der Java 8-Datums- / Uhrzeit-API vergleichen. Wir werden verschiedene Methoden untersuchen, um zu überprüfen, ob zwei Daten gleich sind und wie Daten verglichen werden.

2. Daten vergleichen

Die grundlegende Möglichkeit, ein Datum in Java auszudrücken, ist LocalDate . Betrachten wir zwei LocalDate- Objektinstanzen, die den 10. August 2019 und den 1. Juli 2019 darstellen:

LocalDate firstDate = LocalDate.of(2019, 8, 10); LocalDate secondDate = LocalDate.of(2019, 7, 1);

Wir werden zwei LocalDate- Objekte mit den Methoden isAfter () , isBefore () und isEqual () sowie equals () und compareTo () vergleichen .

Wir verwenden die isAfter () -Methode, um zu überprüfen, ob die Datumsinstanz nach dem anderen angegebenen Datum liegt. Daher wird die nächste JUnit-Behauptung bestehen:

assertThat(firstDate.isAfter(secondDate), is(true));

Analog prüft die Methode isBefore () , ob die Datumsinstanz vor dem anderen angegebenen Datum liegt:

assertThat(firstDate.isBefore(secondDate), is(false));

Die Methode isEqual () prüft, ob ein Datum denselben Punkt auf der lokalen Zeitachse darstellt wie das andere angegebene Datum:

assertThat(firstDate.isEqual(firstDate), is(true)); assertThat(firstDate.isEqual(secondDate), is(false));

2.1. Vergleichen von Daten über die vergleichbare Schnittstelle

Die equals () -Methode liefert das gleiche Ergebnis wie isEqual () , jedoch nur, wenn das übergebene Argument vom gleichen Typ ist (in diesem Fall LocalDate ):

assertThat(firstDate.equals(secondDate), is(false));

Die isEqual () -Methode kann stattdessen verwendet werden, um Objekte eines anderen Typs wie JapaneseDate , ThaiBuddhistDate usw. zu vergleichen.

Wir können zwei Datum Instanzen vergleichen , indem die Verwendung von compareTo () Methode, wie sie in den definierten Vergleichbaren Schnittstelle:

assertThat(firstDate.compareTo(secondDate), is(1)); assertThat(secondDate.compareTo(firstDate), is(-1));

3. Vergleichen von Datumsinstanzen, die die Zeitkomponente enthalten

In diesem Abschnitt wird erläutert, wie Sie zwei LocalDateTime- Instanzen vergleichen . LocalDateTime- Instanzen enthalten sowohl das Datum als auch die Zeitkomponente .

Ähnlich wie bei LocalDate vergleichen wir zwei LocalDateTime- Instanzen mit den Methoden isAfter () , isBefore () und isEqual () . Außerdem können equals () und compareTo () auf ähnliche Weise wie für LocalDate beschrieben verwendet werden.

Ebenso können wir dieselben Methoden zum Vergleichen von zwei ZonedDateTime- Instanzen verwenden. Vergleichen wir 8:00 Uhr Ortszeit in New York und 14:00 Uhr Ortszeit in Berlin am selben Tag:

ZonedDateTime timeInNewYork = ZonedDateTime.of(2019, 8, 10, 8, 0, 0, 0, ZoneId.of("America/New_York")); ZonedDateTime timeInBerlin = ZonedDateTime.of(2019, 8, 10, 14, 0, 0, 0, ZoneId.of("Europe/Berlin")); assertThat(timeInNewYork.isAfter(timeInBerlin), is(false)); assertThat(timeInNewYork.isBefore(timeInBerlin), is(false)); assertThat(timeInNewYork.isEqual(timeInBerlin), is(true));

Obwohl beide ZonedDateTime- Instanzen denselben Zeitpunkt darstellen, repräsentieren sie nicht gleiche Java-Objekte. Sie haben intern unterschiedliche LocalDateTime- und ZoneId- Felder:

assertThat(timeInNewYork.equals(timeInBerlin), is(false)); assertThat(timeInNewYork.compareTo(timeInBerlin), is(-1));

4. Zusätzliche Vergleiche

Erstellen wir eine einfache Utility-Klasse für etwas komplexere Vergleiche.

Zunächst prüfen wir, ob sich Instanzen von LocalDateTime und LocalDate am selben Tag befinden:

public static boolean isSameDay(LocalDateTime timestamp, LocalDate localDateToCompare) { return timestamp.toLocalDate().isEqual(localDateToCompare); }

Zweitens prüfen wir, ob sich zwei Instanzen von LocalDateTime am selben Tag befinden:

public static boolean isSameDay(LocalDateTime timestamp, LocalDateTime timestampToCompare) { return timestamp.truncatedTo(DAYS) .isEqual(timestampToCompare.truncatedTo(DAYS)); }

Die Methode truncatedTo (TemporalUnit) schneidet ein Datum auf der angegebenen Ebene ab , in unserem Beispiel ein Tag.

Drittens können wir einen Vergleich auf der Ebene einer Stunde durchführen:

public static boolean isSameHour(LocalDateTime timestamp, LocalDateTime timestampToCompare) { return timestamp.truncatedTo(HOURS) .isEqual(timestampToCompare.truncatedTo(HOURS)); }

Auf ähnliche Weise können wir schließlich überprüfen, ob zwei ZonedDateTime- Instanzen innerhalb derselben Stunde auftreten:

public static boolean isSameHour(ZonedDateTime zonedTimestamp, ZonedDateTime zonedTimestampToCompare) { return zonedTimestamp.truncatedTo(HOURS) .isEqual(zonedTimestampToCompare.truncatedTo(HOURS)); }

Wir können sehen, dass zwei ZonedDateTime- Objekte tatsächlich innerhalb derselben Stunde ausgeführt werden, auch wenn ihre Ortszeiten unterschiedlich sind (8:30 bzw. 14:00):

ZonedDateTime zonedTimestamp = ZonedDateTime.of(2019, 8, 10, 8, 30, 0, 0, ZoneId.of("America/New_York")); ZonedDateTime zonedTimestampToCompare = ZonedDateTime.of(2019, 8, 10, 14, 0, 0, 0, ZoneId.of("Europe/Berlin")); assertThat(DateTimeComparisonUtils. isSameHour(zonedTimestamp, zonedTimestampToCompare), is(true));

5. Vergleich in der Old Java Date API

Vor Java 8 mussten wir die Klassen java.util.Date und java.util.Calendar verwenden, um Datums- / Zeitinformationen zu bearbeiten . Das Design der alten Java Date API weist viele Mängel auf, z. B. komplexe und nicht threadsichere. Die Instanz java.util.Date repräsentiert einen "Zeitpunkt" und kein reales Datum.

Eine der Lösungen war die Verwendung der Joda Time-Bibliothek. Seit der Veröffentlichung von Java 8 wird empfohlen, auf die Java 8-API für Datum und Uhrzeit zu migrieren.

Ähnlich wie bei LocalDate und LocalDateTime verfügen sowohl die Objekte java.util.Date als auch java.util.Calendar über die Methoden after () , before () , compareTo () und equals () zum Vergleichen zweier Datumsinstanzen . Die Daten werden als Zeitpunkte auf der Ebene einer Millisekunde verglichen:

Date firstDate = toDate(LocalDateTime.of(2019, 8, 10, 0, 00, 00)); Date secondDate = toDate(LocalDateTime.of(2019, 8, 15, 0, 00, 00)); assertThat(firstDate.after(secondDate), is(false)); assertThat(firstDate.before(secondDate), is(true)); assertThat(firstDate.compareTo(secondDate), is(-1)); assertThat(firstDate.equals(secondDate), is(false));

Für komplexere Vergleiche können wir DateUtils aus der Apache Commons Lang-Bibliothek verwenden. Diese Klasse enthält viele praktische Methoden für den Umgang mit Datums- und Kalenderobjekten :

public static boolean isSameDay(Date date, Date dateToCompare) { return DateUtils.isSameDay(date, dateToCompare); } public static boolean isSameHour(Date date, Date dateToCompare) { return DateUtils.truncatedEquals(date, dateToCompare, Calendar.HOUR); }

Um Datumsobjekte zu vergleichen, die von den verschiedenen APIs stammen, sollten wir zuerst eine ordnungsgemäße Konvertierung durchführen und erst dann den Vergleich anwenden. Weitere Informationen finden Sie in unserem Tutorial "Datum in LocalDate konvertieren" oder "LocalDateTime and Back".

6. Fazit

In diesem Artikel haben wir verschiedene Möglichkeiten zum Vergleichen von Datumsinstanzen in Java untersucht.

Die Java 8-Datums- / Zeitklassen verfügen über umfangreiche APIs zum Vergleichen von Datumsangaben mit oder ohne Zeit- und Zeitzonen. Wir haben auch gesehen, wie man Daten auf die Granularität eines Tages, einer Stunde, einer Minute usw. vergleicht.

Alle im Artikel erwähnten Codefragmente, einschließlich zusätzlicher Beispiele, sind auf GitHub verfügbar.