Wie überprüfe ich, ob ein Datum in einem bestimmten Bereich liegt?

Lesezeit: 7 Minuten

Benutzer-Avatar
Mike Sickler

Ich habe eine Reihe von Bereichen mit Start- und Enddaten. Ich möchte überprüfen, ob ein Datum in diesem Bereich liegt.

Date.before() und Date.after() scheinen etwas umständlich zu verwenden zu sein. Was ich wirklich brauche, ist so etwas wie dieser Pseudocode:

boolean isWithinRange(Date testDate) {
    return testDate >= startDate && testDate <= endDate;
}

Ich bin mir nicht sicher, ob es relevant ist, aber die Daten, die ich aus der Datenbank ziehe, haben Zeitstempel.

  • Ähnliche Frage mit mehreren Antworten: Wie kann ich in Java feststellen, ob ein Datum zwischen zwei Daten liegt?

    – Basilikum Bourque

    9. Februar 2016 um 18:47 Uhr


  • FYI, die lästigen alten Datums-Zeit-Klassen wie java.util.Date und java.util.Calendar sind jetzt Vermächtnisersetzt durch die java.time Klassen. Sehen Tutorial von Oracle.

    – Basilikum Bourque

    4. September 2017 um 22:56 Uhr


boolean isWithinRange(Date testDate) {
   return !(testDate.before(startDate) || testDate.after(endDate));
}

Kommt mir nicht so umständlich vor. Beachten Sie, dass ich es so geschrieben habe, anstatt

return testDate.after(startDate) && testDate.before(endDate);

es würde also funktionieren, selbst wenn testDate genau gleich einem der Endfälle wäre.

  • mit diesem Code ist Folgendes ungültig: date is 01-01-2014 and the range is from 01-01-2014 to 31-01-2014 wie kann man es gültig machen?

    – Shahe

    31. Januar 2014 um 9:36 Uhr


  • @Shahe Das erste, was ich tun würde, ist, die Zeitabschnitte Ihrer Daten zu überprüfen. Die Chancen stehen Ihnen date ist früh morgens und startDate ist danach.

    – Paul Tomblin

    31. Januar 2014 um 13:20 Uhr

  • dieser trick mit dem negieren von or ist nach sieben jahren immer noch schön. 🙂

    – Tosz

    16. September 2016 um 11:33 Uhr

  • Es funktioniert nicht, wenn testDate das aktuelle Datum von heute ist. Wie man mit diesem Szenario in der oben vorgeschlagenen Lösung umgeht.

    – Schnell

    8. Dezember 2016 um 12:14 Uhr

  • @Schnell Date enthält Zeit (Stunden, Minuten, Sekunden und Millisekunden). Wenn Sie also testen möchten, ob etwas “heute” ist, erstellen Sie ein Datumsobjekt, das zur Zeit 0:00:00.000 “heute” ist, und eines, das zur Zeit 0:00:00.000 “morgen” ist. Ich verwende das Calendar Klasse dafür, aber ich bin mir sicher, dass es einen besseren Weg gibt, wenn Sie JodaTime oder die neueren Basis-Java-Klassen verwenden.

    – Paul Tomblin

    8. Dezember 2016 um 15:35 Uhr

Benutzer-Avatar
Basil Bourque

tl;dr

ZoneId z = ZoneId.of( "America/Montreal" );  // A date only has meaning within a specific time zone. At any given moment, the date varies around the globe by zone.
LocalDate ld = 
    givenJavaUtilDate.toInstant()  // Convert from legacy class `Date` to modern class `Instant` using new methods added to old classes.
                     .atZone( z )  // Adjust into the time zone in order to determine date.
                     .toLocalDate();  // Extract date-only value.

LocalDate today = LocalDate.now( z );  // Get today’s date for specific time zone.
LocalDate kwanzaaStart = today.withMonth( Month.DECEMBER ).withDayOfMonth( 26 );  // Kwanzaa starts on Boxing Day, day after Christmas.
LocalDate kwanzaaStop = kwanzaaStart.plusWeeks( 1 );  // Kwanzaa lasts one week.
Boolean isDateInKwanzaaThisYear = (
    ( ! today.isBefore( kwanzaaStart ) ) // Short way to say "is equal to or is after".
    &&
    today.isBefore( kwanzaaStop )  // Half-Open span of time, beginning inclusive, ending is *exclusive*.
)

Halb offen

Bei der Datums-/Uhrzeitarbeit wird üblicherweise der „halboffene“ Ansatz verwendet, um eine Zeitspanne zu definieren. Der Anfang ist inklusive während das Ende ist exklusiv. Eine Woche, die an einem Montag beginnt, läuft also bis zum folgenden Montag, schließt diesen jedoch nicht ein.

java.time

Java 8 und höher wird mit dem geliefert java.time Rahmen eingebaut. Ersetzt die alten lästigen Klassen einschließlich java.util.Date/.Calendar und SimpleDateFormat. Inspiriert von der erfolgreichen Joda-Time-Bibliothek. Definiert durch JSR 310. Erweitert durch das ThreeTen-Extra-Projekt.

Ein Instant ist ein Moment auf der Timeline in koordinierte Weltzeit mit Nanosekundenauflösung.

Instant

Konvertieren Sie Ihre java.util.Date Objekte zu Instant-Objekten.

Instant start = myJUDateStart.toInstant();
Instant stop = …

Wenn bekommen java.sql.Timestamp Objekte über JDBC aus einer Datenbank, in java.time.Instant konvertieren auf eine ähnliche Weise. EIN java.sql.Timestamp ist bereits in UTC, sodass Sie sich keine Gedanken über Zeitzonen machen müssen.

Instant start = mySqlTimestamp.toInstant() ;
Instant stop = …

Holen Sie sich den aktuellen Moment zum Vergleich.

Instant now = Instant.now();

Vergleichen Sie mit den Methoden isBefore, isAfter und equals.

Boolean containsNow = ( ! now.isBefore( start ) ) && ( now.isBefore( stop ) ) ;

LocalDate

Vielleicht möchten Sie nur mit dem Datum arbeiten, nicht mit der Uhrzeit.

Das LocalDate Die Klasse stellt einen Nur-Datum-Wert dar, ohne Uhrzeit und ohne Zeitzone.

LocalDate start = LocalDate.of( 2016 , 1 , 1 ) ;
LocalDate stop = LocalDate.of( 2016 , 1 , 23 ) ;

Um das aktuelle Datum zu erhalten, geben Sie eine Zeitzone an. Zu jedem Zeitpunkt variiert das heutige Datum je nach Zeitzone. Zum Beispiel bricht ein neuer Tag in Paris früher an als in Montréal.

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );

Wir können die verwenden isEqual, isBeforeund isAfter Methoden zu vergleichen. Bei der Arbeit mit Datum und Uhrzeit verwenden wir üblicherweise den halboffenen Ansatz, bei dem der Beginn einer Zeitspanne liegt inklusive während das Ende ist exklusiv.

Boolean containsToday = ( ! today.isBefore( start ) ) && ( today.isBefore( stop ) ) ;

Interval

Wenn Sie sich entschieden haben, die hinzuzufügen ThreeTen-Extra Bibliothek zu Ihrem Projekt, könnten Sie die verwenden Interval Klasse, um eine Zeitspanne zu definieren. Diese Klasse bietet Methoden zum Testen des Intervalls enthält, anliegt, umschließtoder überlappt andere Datumszeiten/Intervalle.

Das Interval Klasse arbeitet weiter Instant Objekte. Das Instant Klasse repräsentiert einen Moment auf der Zeitachse in koordinierte Weltzeit mit einer Auflösung von Nanosekunden (bis zu neun (9) Stellen eines Dezimalbruchs).

Wir können die anpassen LocalDate in einen bestimmten Moment, den ersten Moment des Tages, indem Sie eine Zeitzone angeben, um a zu erhalten ZonedDateTime. Von dort können wir zu UTC zurückkehren, indem wir a extrahieren Instant.

ZoneId z = ZoneId.of( "America/Montreal" );
Interval interval = 
    Interval.of( 
        start.atStartOfDay( z ).toInstant() , 
        stop.atStartOfDay( z ).toInstant() );
Instant now = Instant.now();
Boolean containsNow = interval.contains( now );

Über java.time

Das java.time Framework ist in Java 8 und höher integriert. Diese Klassen ersetzen die lästigen alten Vermächtnis Datum-Zeit-Klassen wie z java.util.Date, Calendar& SimpleDateFormat.

Das Joda-Zeit Projekt, jetzt in Wartungsmodusrät zur Migration in die java.time Klassen.

Weitere Informationen finden Sie unter Oracle-Tutorial. Und durchsuchen Sie Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR310.

Wo bekommt man die java.time Klassen?

  • Java SE 8 und SE 9 und später
  • Eingebaut.
  • Teil der Standard-Java-API mit einer gebündelten Implementierung.
  • Java 9 fügt einige kleinere Funktionen und Korrekturen hinzu.
  • Java SE 6 und SE 7
  • Viel von der java.time Funktionalität ist zurückportiert auf Java 6 & 7 in ThreeTen-Backport.
  • Android
  • Das ThreeTenABP Projekt passt ThreeTen-Backport (oben erwähnt) speziell für Android.
  • Sehen Wie benutzt man….

Das ThreeTen-Extra Projekt verlängert java.time mit Zusatzklassen. Dieses Projekt ist ein Testgelände für mögliche zukünftige Ergänzungen java.time. Sie können hier einige nützliche Klassen finden, wie z Interval, YearWeek, YearQuarterund mehr.

Das ist der richtige Weg. Kalender funktionieren auf die gleiche Weise. Das Beste, was ich Ihnen anbieten könnte (basierend auf Ihrem Beispiel), ist Folgendes:

boolean isWithinRange(Date testDate) {
    return testDate.getTime() >= startDate.getTime() &&
             testDate.getTime() <= endDate.getTime();
}

Date.getTime() gibt die Anzahl der Millisekunden seit dem 1.1.1970 00:00:00 GMT zurück und ist lang, sodass es leicht vergleichbar ist.

Benutzer-Avatar
Ben Hardy

Erwägen Sie die Verwendung Joda-Zeit. Ich liebe diese Bibliothek und wünschte, sie würde das aktuelle schreckliche Durcheinander ersetzen, das die vorhandenen Java-Klassen Date und Calendar sind. Es ist die richtige Handhabung von Daten.

EDIT: Es ist nicht mehr 2009 und Java 8 ist seit Ewigkeiten draußen. Verwenden Sie die in Java 8 integrierten java.time-Klassen, die auf Joda Time basieren, wie Basil Bourque oben erwähnt. In diesem Fall benötigen Sie die Period-Klasse, und hier ist sie Tutorial von Oracle wie man es benutzt.

Eine einfache Möglichkeit besteht darin, die Daten nach dem 1. Januar 1970 in Millisekunden umzuwandeln (verwenden Sie Date.getTime()) und diese Werte dann zu vergleichen.

Benutzer-Avatar
Epoxid

Seit Java 8

HINWEIS: Alle, bis auf einen, DateDie Konstruktoren von sind veraltet. Die meisten von den DateDie Methoden von sind veraltet. REF: Datum: Veraltete Methoden. Alle, aber Date::from(Instant)statische Methoden sind veraltet.

Erwägen Sie also seit Java 8 die Verwendung von Instant (unveränderlich, Thread-sicher, Schaltsekunden-bewusst) Typ statt Date. REF: Sofortig

  static final LocalTime MARKETS_OPEN = LocalTime.of(07, 00);
  static final LocalTime MARKETS_CLOSE = LocalTime.of(20, 00);

    // Instant utcTime = testDate.toInstant();
    var bigAppleTime = ZonedDateTime.ofInstant(utcTime, ZoneId.of("America/New_York"));

im Bereich INKLUSIVE:

    return !bigAppleTime.toLocalTime().isBefore(MARKETS_OPEN)
        && !bigAppleTime.toLocalTime().isAfter(MARKETS_CLOSE);

im Bereich EXKLUSIV:

    return bigAppleTime.toLocalTime().isAfter(MARKETS_OPEN)
        && bigAppleTime.toLocalTime().isBefore(MARKETS_CLOSE);

Benutzer-Avatar
keval dholakiya

wenn Sie inklusive Vergleich mit wollen LocalDate Dann verwenden Sie diesen Code.

LocalDate from = LocalDate.of(2021,8,1);
LocalDate to = LocalDate.of(2021,8,1);
LocalDate current = LocalDate.of(2021,8,1);

boolean isDateInRage = ( ! (current.isBefore(from.minusDays(1)) && current.isBefore(to.plusDays(1))) );

  • Etwas kompliziert und vielleicht deswegen auch nicht ganz richtig. ich habe mich verändert currentzu LocalDate.of(2021, 7, 31); und noch bekommen true, was nicht stimmen kann. Verwenden LocalDate und isBefore() ist eine gute Idee.

    – Ole VV

    8. Januar 2021 um 21:08 Uhr


1014610cookie-checkWie überprüfe ich, ob ein Datum in einem bestimmten Bereich liegt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy