Ich hätte gerne eine compareTo-Methode, die den Zeitanteil eines java.util.Date ignoriert. Ich denke, es gibt eine Reihe von Möglichkeiten, dies zu lösen. Was ist der einfachste Weg?
Update: Während Joda Time zu dieser Zeit eine gute Empfehlung war, verwenden Sie java.time
stattdessen nach Möglichkeit die Bibliothek von Java 8+.
Ich bevorzuge die Verwendung von Joda Time , was dies unglaublich einfach macht:
DateTime first = ...;
DateTime second = ...;
LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();
return firstDate.compareTo(secondDate);
EDIT: Wie in den Kommentaren erwähnt, ist DateTimeComparator.getDateOnlyInstance()
es noch einfacher , wenn Sie verwenden :)
// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);
("Use Joda Time" ist die Grundlage für fast alle SO-Fragen, die nach java.util.Date
oder gestellt werden java.util.Calendar
. Es ist eine durchaus überlegene API. Wenn Sie mit Datums- / Uhrzeitangaben etwas Bedeutendes tun , sollten Sie es wirklich verwenden, wenn Sie können.)
Wenn Sie absolut gezwungen sind , die integrierte API zu verwenden, sollten Sie eine Instanz Calendar
mit dem entsprechenden Datum und der entsprechenden Zeitzone erstellen . Sie können dann jedes Feld in jedem Kalender außerhalb von Stunde, Minute, Sekunde und Millisekunde auf 0 setzen und die resultierenden Zeiten vergleichen. Auf jeden Fall eklig im Vergleich zur Joda-Lösung :)
Der Zeitzonenteil ist wichtig: java.util.Date
basiert immer auf UTC. In den meisten Fällen, in denen ich an einem Datum interessiert war, war dies ein Datum in einer bestimmten Zeitzone . Das allein zwingt Sie dazu, Calendar
oder Joda Time zu verwenden (es sei denn, Sie möchten die Zeitzone selbst berücksichtigen, was ich nicht empfehle.)
Kurzreferenz für Android-Entwickler
//Add joda library dependency to your build.gradle file
dependencies {
...
implementation 'joda-time:joda-time:2.9.9'
}
Beispielcode (Beispiel)
DateTimeComparator dateTimeComparator = DateTimeComparator.getDateOnlyInstance();
Date myDateOne = ...;
Date myDateTwo = ...;
int retVal = dateTimeComparator.compare(myDateOne, myDateTwo);
if(retVal == 0)
//both dates are equal
else if(retVal < 0)
//myDateOne is before myDateTwo
else if(retVal > 0)
//myDateOne is after myDateTwo
Apache commons-lang ist fast allgegenwärtig. Was ist damit?
quelle
Wenn Sie das java.util.Date wirklich verwenden möchten, würden Sie Folgendes tun:
oder stattdessen einen Kalender verwenden (bevorzugt, da getYear () und dergleichen veraltet sind)
quelle
Ich würde es vorziehen, die Joda- Bibliothek
java.util.Date
direkt zu verwenden, da Joda zwischen Datum und Uhrzeit unterscheidet (siehe YearMonthDay- und DateTime- Klassen).Wenn Sie jedoch verwenden möchten,
java.util.Date
würde ich vorschlagen, eine Dienstprogrammmethode zu schreiben. z.Bquelle
Irgendwelche Meinungen zu dieser Alternative?
quelle
==
Operator gibt nicht unbedingttrue
für äquivalente Strings (Verwendungequals()
) zurück. Die anderen von Ihnen genannten Vergleichsoperatoren können Sie sicherlich auch nicht verwenden.sdf.format(date1).compareTo(sdf.format(date2));
.Wenn Sie nur den Monat, den Tag und das Jahr zweier Daten vergleichen möchten, funktioniert der folgende Code für mich:
Danke Rob.
quelle
Ich bevorzuge auch Joda Time , aber hier ist eine Alternative:
BEARBEITEN
Ich habe das UTC-Ding unten aufgeführt, falls Sie Daten für eine andere Zeitzone als UTC vergleichen müssen. Wenn Sie jedoch ein solches Bedürfnis haben, dann rate ich Ihnen wirklich, sich für Joda zu entscheiden.
quelle
Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
< oneDay
.tl; dr
Vermeiden Sie ältere Datums- und Zeitklassen
Vermeiden Sie die lästigen alten Legacy-Datums- / Uhrzeitklassen wie
Date
&Calendar
, die jetzt durch die Klassen java.time ersetzt werden.Mit java.time
A
java.util.Date
repräsentiert einen Moment auf der Timeline in UTC. Das Äquivalent in java.time istInstant
. Sie können mit neuen Methoden konvertieren, die der Legacy-Klasse hinzugefügt wurden.Sie möchten nach Datum vergleichen. Eine Zeitzone ist entscheidend für die Bestimmung eines Datums. Für jeden Moment variiert das Datum weltweit je nach Zone. Zum Beispiel ist ein paar Minuten nach Mitternacht in Paris Frankreich ein neuer Tag, während es in Montréal Québec noch „gestern“ ist .
Geben Sie einen richtigen Zeitzonennamen im Format
continent/region
, wie zum BeispielAmerica/Montreal
,Africa/Casablanca
oderPacific/Auckland
. Verwenden Sie niemals die Abkürzung für 3-4 Buchstaben, wie z. B.EST
oderIST
da es sich nicht um echte Zeitzonen handelt, die nicht standardisiert und nicht einmal eindeutig (!) Sind.Wenden Sie das
ZoneId
anInstant
, um eine zu erhaltenZonedDateTime
.Die
LocalDate
Klasse repräsentiert einen Nur-Datum-Wert ohne Tageszeit und ohne Zeitzone. Wir können aLocalDate
aus a extrahierenZonedDateTime
und so den Tageszeitanteil effektiv eliminieren.Vergleichen Sie nun, Methoden wie
isEqual
,isBefore
undisAfter
.Sehen Sie diesen Code live auf IdeOne.com .
Über java.time
Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie
java.util.Date
,Calendar
, &SimpleDateFormat
.Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .
Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .
Woher bekomme ich die java.time-Klassen?
Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden
Interval
,YearWeek
,YearQuarter
, und mehr .quelle
Bereits erwähnte Apache Commons-Utils :
gibt Ihnen ein Datumsobjekt, das nur Datum ohne Uhrzeit enthält, und Sie können es mit vergleichen
Date.compareTo
quelle
Ich fürchte, es gibt keine Methode zum Vergleichen von zwei Daten, die als "einfach" oder "einfach" bezeichnet werden könnten.
Wenn Sie zwei Zeitinstanzen mit einer reduzierten Genauigkeit vergleichen (z. B. nur Datumsvergleiche), müssen Sie immer berücksichtigen, wie sich die Zeitzone auf den Vergleich auswirkt.
Wenn Sie
date1
ein Ereignis angeben, das in der Zeitzone +2 aufgetretendate2
ist, und beispielsweise ein Ereignis angeben, das in EST aufgetreten ist, müssen Sie darauf achten, die Auswirkungen des Vergleichs richtig zu verstehen.Möchten Sie herausfinden, ob die beiden Ereignisse am selben Kalenderdatum in ihren jeweiligen Zeitzonen aufgetreten sind? Oder müssen Sie wissen, ob die beiden Daten in einer bestimmten Zeitzone (z. B. UTC oder Ihre lokale TZ) auf dasselbe Kalenderdatum fallen?
Sobald Sie herausgefunden haben, was Sie tatsächlich vergleichen möchten, müssen Sie nur noch das Dreifache von Jahr, Monat und Datum in einer geeigneten Zeitzone festlegen und den Vergleich durchführen.
Durch die Joda-Zeit sieht die eigentliche Vergleichsoperation möglicherweise viel sauberer aus, aber die Semantik des Vergleichs ist immer noch etwas, das Sie selbst herausfinden müssen.
quelle
Wenn Sie Java 8 verwenden, sollten Sie die
java.time.*
Klassen zum Vergleichen von Daten verwenden - dies wird den verschiedenenjava.util.*
Klassen vorgezogenz.B; https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
quelle
Wenn Sie nur zwei Daten ohne Zeit vergleichen möchten, kann der folgende Code hilfreich sein:
quelle
Hier ist eine Lösung aus diesem Blog: http://brigitzblog.blogspot.com/2011/10/java-compare-dates.html
Sie können also sehen, ob der Zeitunterschied in Millisekunden weniger als die Länge eines Tages beträgt.
quelle
`
`
quelle
Ich weiß nicht, ob es neu ist oder nicht, aber ich zeige es dir, wie ich es getan habe
quelle
Überprüfen Sie einfach DAY_OF_YEAR in Kombination mit der YEAR-Eigenschaft
BEARBEITEN:
Jetzt können wir die Leistung der Kotlin-Erweiterungsfunktionen nutzen
quelle
In Java 8 können Sie LocalDate verwenden, das dem von Joda Time sehr ähnlich ist.
quelle
Auf diese Weise können Sie Daten ohne Berücksichtigung der Uhrzeit vergleichen.
quelle
Mit getDateInstance von SimpleDateFormat können wir nur zwei Datumsobjekte ohne Zeit vergleichen. Führen Sie den folgenden Code aus.
quelle
Verwenden von http://mvnrepository.com/artifact/commons-lang/commons-lang
quelle
DateUtils.isSameDay(date1, date2)
.Eine weitere einfache Vergleichsmethode basierend auf den Antworten hier und meiner Mentor-Anleitung
EDIT : Laut @Jonathan Drapeau schlägt der obige Code in einigen Fällen fehl (ich würde diese Fälle bitte sehen) und er schlug Folgendes vor, so wie ich es verstehe:
Bitte beachten Sie, dass die Date-Klasse veraltet ist, da sie nicht internationalisiert werden konnte. Stattdessen wird die Calendar-Klasse verwendet!
quelle
getXxx
Methoden vonDate
.Beachten Sie zunächst, dass dieser Vorgang von der Zeitzone abhängt. Wählen Sie also, ob Sie dies in UTC, in der Zeitzone des Computers, in Ihrer eigenen bevorzugten Zeitzone oder wo tun möchten. Wenn Sie noch nicht überzeugt sind, dass es darauf ankommt, sehen Sie sich mein Beispiel am Ende dieser Antwort an.
Da Ihre Frage dazu nicht ganz klar ist, gehe ich davon aus, dass Sie eine Klasse mit einem Instanzfeld haben, das einen Zeitpunkt darstellt und implementiert
Comparable
, und dass die natürliche Reihenfolge Ihrer Objekte nach dem Datum, aber nicht nach der Uhrzeit erfolgen soll von diesem Feld. Beispielsweise:Java 8
java.time
KlassenIch habe mir die Freiheit genommen, den Typ Ihres Instanzfelds von
Date
inInstant
die entsprechende Klasse in Java 8 zu ändern . Ich verspreche, zur folgenden Behandlung zurückzukehrenDate
. Ich habe auch eine Zeitzonenkonstante hinzugefügt. Sie können es aufZoneOffset.UTC
oderZoneId.of("Europe/Stockholm")
oder das setzen, was Sie für angemessen halten (es auf einZoneOffset
Werk setzen, weilZoneOffset
es eine Unterklasse von istZoneId
).Ich habe mich entschieden, die Lösung mit den Java 8-Klassen zu zeigen. Sie haben nach dem einfachsten Weg gefragt, oder? :-) Hier ist die
compareTo
Methode, nach der Sie gefragt haben:Wenn Sie nie die Zeit Teil benötigen
when
, ist es natürlich leichter zu erklären ,when
einLocalDate
und alle Conversions überspringen. Dann müssen wir uns auch nicht mehr um die Zeitzone kümmern.Nehmen wir nun an, Sie können Ihr
when
Feld aus irgendeinem Grund nicht deklarierenInstant
oder möchten es altmodisch haltenDate
. Wenn Sie Java 8 weiterhin verwenden können, konvertieren Sie es einfach inInstant
und gehen Sie wie folgt vor:Ähnliches gilt für
o.when
.Kein Java 8?
Wenn Sie Java 8 nicht verwenden können, gibt es zwei Möglichkeiten:
Calendar
oderSimpleDateFormat
.Die altmodischen Wege
Die Antwort von Adamski zeigt Ihnen, wie Sie den Zeitteil
Date
mithilfe derCalendar
Klasse entfernen können. Ich schlage vor, Sie verwendengetInstance(TimeZone)
, um dieCalendar
Instanz für die gewünschte Zeitzone zu erhalten . Alternativ können Sie die Idee aus der zweiten Hälfte von Jorns Antwort verwenden .Verwenden
SimpleDateFormat
ist wirklich eine indirekte Art zu verwenden,Calendar
da aSimpleDateFormat
einCalendar
Objekt enthält . Möglicherweise ist dies jedoch weniger problematisch als dieCalendar
direkte Verwendung :Dies wurde von Robs Antwort inspiriert .
Zeitzonenabhängigkeit
Warum müssen wir eine bestimmte Zeitzone auswählen? Angenommen, wir möchten zwei Mal vergleichen, dass in UTC der 24. März 0:00 (Mitternacht) und 12:00 (Mittag) sind. Wenn Sie dies in MEZ tun (z. B. Europa / Paris), sind sie am 24. März um 1 Uhr morgens und um 13 Uhr abends, dh am selben Tag. In New York (Eastern Daylight Time) sind sie am 23. März um 20:00 Uhr und am 24. März um 8:00 Uhr, dh nicht am selben Tag. Es macht also einen Unterschied, welche Zeitzone Sie auswählen. Wenn Sie sich nur auf die Standardeinstellungen des Computers verlassen, werden Sie möglicherweise überrascht sein, wenn jemand versucht, Ihren Code auf einem Computer an einem anderen Ort in dieser globalisierten Welt auszuführen.
Verknüpfung
Link zu ThreeTen Backport, dem Backport der Java 8-Datums- und Zeitklassen zu Java 6 und 7: http://www.threeten.org/threetenbp/ .
quelle
Mein Vorschlag:
quelle
Mit Apache Commons können Sie Folgendes tun:
quelle
Dies ist der einfachste Weg, um dieses Problem zu lösen.
quelle
Ich habe dies durch einen Vergleich nach Zeitstempel gelöst:
Ich vermeide es, Joda Time zu verwenden, da Android einen riesigen Speicherplatz benötigt. Die Größe ist wichtig. ;)
quelle
Eine andere Lösung mit Java 8 und Instant ist die Verwendung der Methode truncatedTo
Beispiel:
quelle
quelle
Das hat bei mir funktioniert:
quelle
Wie wäre es mit
DateUtil.daysBetween()
. Es ist Java und es gibt eine Zahl zurück (Differenz in Tagen).quelle