Sammenligning af datoer i Java

1. Introduktion

I denne vejledning fokuserer vi på, hvordan man sammenligner datoer ved hjælp af Java 8 Date / Time API. Vi dykker ned i forskellige metoder for at kontrollere, om to datoer er ens, og hvordan man sammenligner datoer.

2. Sammenligning af datoer

Den grundlæggende måde at udtrykke en dato på Java er på LocalDate. Lad os overveje to LocalDate objektforekomster, der repræsenterer den 10. august 2019 og den 1. juli 2019:

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

Vi sammenligner to LocalDate genstande ved at bruge isAfter (), isBefore ()og isEqual () metoder, såvel som lige med() og sammenligne med().

Vi bruger isAfter () metode til at kontrollere, om datoinstansen er efter den anden specificerede dato. Derfor vil den næste JUnit-påstand bestå:

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

Analogt metoden isBefore () kontrollerer, om datoinstansen er før den anden specificerede dato:

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

Metoden isEqual () kontrollerer, om en dato repræsenterer det samme punkt på den lokale tidslinje som den anden specificerede dato:

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

2.1. Sammenligning af datoer ved hjælp af Sammenlignelig Interface

Det lige med() metode giver det samme resultat som isEqual (), men kun hvis argumentet, der er sendt, er af samme type (i dette tilfælde LocalDate):

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

Det isEqual () Metoden kan bruges i stedet for at sammenligne med objekter af en anden type, f.eks Japansk dato, ThaiBuddhistDate, etc.

Vi kan sammenligne to datoinstanser ved hjælp af sammenligne med() metode, som defineret af Sammenlignelig grænseflade:

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

3. Sammenligning af datoinstanser, der indeholder tidskomponenten

Dette afsnit forklarer, hvordan man sammenligner to LocalDateTime tilfælde. LocalDateTime forekomster indeholder både dato og tidskomponent.

På samme måde som LocalDate, vi sammenligner to LocalDateTime tilfælde med metoderne isAfter (), isBefore () og isEqual (). Derudover lige med() og sammenligne med() kan anvendes på en lignende måde som beskrevet for LocalDate.

På samme måde kan vi bruge de samme metoder til at sammenligne to ZonedDateTime tilfælde. Lad os sammenligne 8:00 lokal tid i New York og 14:00 lokal tid i Berlin samme dag:

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 ("Europa / Berlin")); assertThat (timeInNewYork.isAfter (timeInBerlin), er (false)); assertThat (timeInNewYork.isBefore (timeInBerlin), er (false)); assertThat (timeInNewYork.isEqual (timeInBerlin), er (true));

Selvom begge dele ZonedDateTime forekomster repræsenterer det samme øjeblik i tiden, de repræsenterer ikke lige Java-objekter. De har forskellige LocalDateTime og ZoneId felter internt:

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

4. Yderligere sammenligninger

Lad os oprette en simpel hjælpeklasse til lidt mere komplekse sammenligninger.

For det første kontrollerer vi, om forekomster af LocalDateTime og LocalDate er samme dag:

offentlig statisk boolsk isSameDay (LocalDateTime tidsstempel, LocalDate localDateToCompare) {return timestamp.toLocalDate (). isEqual (localDateToCompare); }

For det andet kontrollerer vi, om to forekomster af LocalDateTime er samme dag:

offentlig statisk boolsk isSameDay (LocalDateTime-tidsstempel, LocalDateTime-tidsstempelToCompare) {return timestamp.truncatedTo (DAYS) .isEqual (timestampToCompare.truncatedTo (DAYS)); }

Det trunkeret til (TemporalUnit) metode afkortes en dato på det givne niveau, som i vores eksempel er en dag.

For det tredje kan vi implementere en sammenligning på niveau med en time:

offentlig statisk boolsk isSameHour (LocalDateTime tidsstempel, LocalDateTime tidsstempelToCompare) {return timestamp.truncatedTo (HOURS) .isEqual (timestampToCompare.truncatedTo (HOURS)); }

Endelig kan vi på samme måde kontrollere, om to ZonedDateTime forekomster sker inden for den samme time:

offentlig statisk boolesk isSameHour (ZonedDateTime zonedTimestamp, ZonedDateTime zonedTimestampToCompare) {return zonedTimestamp.truncatedTo (HOURS) .isEqual (zonedTimestampToCompare.truncatedTo (HOURS)); }

Vi kan se de to ZonedDateTime objekter sker faktisk inden for den samme time, selvom deres lokale tid er forskellig (henholdsvis 8:30 og 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 ("Europa / Berlin")); assertThat (DateTimeComparisonUtils. isSameHour (zonedTimestamp, zonedTimestampToCompare), er (true));

5. Sammenligning i den gamle Java Date API

Før Java 8 måtte vi bruge java.util.Date og java.util.Kalender klasser til manipulation af dato / tid information. Designet af den gamle Java Date API har mange mangler, såsom at være kompleks og ikke trådsikker. Det java.util.Date instans repræsenterer et "øjeblikkeligt tidspunkt" og ikke en reel dato.

En af løsningerne var at bruge Joda Time-biblioteket. Siden frigivelsen af ​​Java 8 anbefales det at migrere til Java 8 Date / Time API.

På samme måde som LocalDate og LocalDateTime, begge java.util.Date og java.util.Kalender genstande har efter(), Før(), sammenligne med() og lige med() metoder til sammenligning af to datoinstanser. Datoerne sammenlignes som de øjeblikke, på et millisekund niveau:

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

For mere komplekse sammenligninger kan vi bruge DateUtils fra Apache Commons Lang-biblioteket. Denne klasse indeholder mange praktiske metoder til at håndtere Dato og Kalender genstande:

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

For at sammenligne datoobjekter, der stammer fra de forskellige API'er, skal vi først foretage en ordentlig konvertering og først derefter anvende sammenligningen. Vi kan finde flere detaljer i vores Konverter dato til LocalDate eller LocalDateTime og Back tutorial.

6. Konklusion

I denne artikel har vi undersøgt forskellige måder at sammenligne datoinstanser i Java.

Java 8 dato / tidsklasser har rige API'er til sammenligning af datoer med eller uden tids- og tidszoner. Vi har også set, hvordan man sammenligner datoer på granulariteten af ​​en dag, time, minut osv.

Alle de kodestykker, der er nævnt i artiklen, inklusive yderligere eksempler, er tilgængelige på GitHub.