Wie vergleiche ich zwei Daten ohne Zeitanteil?

202

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?

Arne Evertsson
quelle

Antworten:

212

Update: Während Joda Time zu dieser Zeit eine gute Empfehlung war, verwenden Sie java.timestattdessen 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.Dateoder 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 Calendarmit 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.Datebasiert 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, Calendaroder 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
Jon Skeet
quelle
28
Obwohl Jon sagt, dass "Use Joda Time" die Grundlage für fast alle SO-Fragen ist, die zu java.util.Date oder java.util.Calendar gestellt werden, denke ich immer, dass es am besten ist, zunächst eine konkrete Antwort auf der Grundlage der Frage des Benutzers zu geben Zumindest um zu zeigen, wie schwer es sein kann, Java zu machen. Und danach vorschlagen, Joda zu verwenden ...
JuanZe
13
@JuanZe: Dazu muss man genau herausfinden, wie man in einer schmerzhaften API etwas richtig macht, was per Definition schmerzhaft ist. Ich würde diese Zeit lieber damit verbringen, etwas Produktiveres zu tun :)
Jon Skeet
1
@ MetroidFan2002: LocalDate ist eine bessere Option als DateMidnight, da es ausdrucksvoller ist - und nicht alle Tage Mitternacht haben ...
Jon Skeet
2
@dertoni: Sicher - in Brasilien, wenn die Uhren aufgrund der Sommerzeit vorwärts gehen, geschieht dies zu Beginn des Tages ... also würde eine Uhr 23:59:58, 23:59:59, 01:00 anzeigen : 00, 01:00:01 usw.
Jon Skeet
8
Wäre es nicht besser, DateTimeComparator.getDateOnlyInstance ()
Emil
125

Apache commons-lang ist fast allgegenwärtig. Was ist damit?

if (DateUtils.isSameDay(date1, date2)) {
    // it's same
} else if (date1.before(date2)) {
   // it's before
} else {
   // it's after
}
André
quelle
Version 2.6 enthielt eine abgeschnittene CompareTo-
Shonky Linux-Benutzer
2
Toleriert
leider
Leute
André
Ich empfehle die Verwendung von vor diesem Weg nicht, da, wenn das erste oder das zweite Datumsobjekt nicht aus dem Zeitstempel gesendet wurde und Meilensekunden haben und das andere ein normales Datumsobjekt ist, Probleme auftreten können, da das Datum aus dem Datenstempel in einem anderen Teil gespeichert wird Die Millisekunden des Objekts ergeben Unterschiede, selbst wenn beide Daten gleich sind.
Zini
Leider ist Apache nicht auf mehr als 1,3 Milliarden Android-Geräten verfügbar, und es ist eine riesige Bibliothek, auf die man sich nur für einen Anwendungsfall verlassen kann. Ich brauche noch etwas: /
Milosmns
58

Wenn Sie das java.util.Date wirklich verwenden möchten, würden Sie Folgendes tun:

public class TimeIgnoringComparator implements Comparator<Date> {
  public int compare(Date d1, Date d2) {
    if (d1.getYear() != d2.getYear()) 
        return d1.getYear() - d2.getYear();
    if (d1.getMonth() != d2.getMonth()) 
        return d1.getMonth() - d2.getMonth();
    return d1.getDate() - d2.getDate();
  }
}

oder stattdessen einen Kalender verwenden (bevorzugt, da getYear () und dergleichen veraltet sind)

public class TimeIgnoringComparator implements Comparator<Calendar> {
  public int compare(Calendar c1, Calendar c2) {
    if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) 
        return c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);
    if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) 
        return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
    return c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH);
  }
}
Jorn
quelle
1
Bei der zweiten Methode haben Sie vergessen, einige Ihrer Referenzen von d1, d2 auf c1, c2 zu aktualisieren.
Stivlo
1
Nachdem Sie dieses Detail korrigiert haben, funktioniert Ihr Code gut: Ich habe ihn ausgiebig getestet. Ich habe den Schritt zum Erstellen eines Kalenders aus den Daten hinzugefügt und Ihren Code in meinem neu erstellten Github-Projekt org.obliquid.helpers verwendet . Danke.
Stivlo
Süße, schöne Lösung ohne Verwendung einer externen Bibliothek.
4gus71n
1
Alle diese Methoden sind veraltet. Kann dies irgendwelche Auswirkungen haben?
Pranav Mahajan
36

Ich würde es vorziehen, die Joda- Bibliothek java.util.Datedirekt zu verwenden, da Joda zwischen Datum und Uhrzeit unterscheidet (siehe YearMonthDay- und DateTime- Klassen).

Wenn Sie jedoch verwenden möchten, java.util.Datewürde ich vorschlagen, eine Dienstprogrammmethode zu schreiben. z.B

public static Date setTimeToMidnight(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( date );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}
Adamski
quelle
1
Joda-Time YearMonthDay ist zugunsten von LocalDate veraltet. Außerdem hat der Code im Kalender Probleme, wenn die Zeitzone aufgrund der Sommerzeit nicht um Mitternacht 00:00 Uhr ist.
JodaStephen
1
Dies funktioniert nicht 100% der Zeit. Hatte einen Anwendungsfall, in dem ich das getan habe, und die Datei calendar.getTime () gab immer noch die Uhrzeit mit den als Parameterdatum festgelegten Stunden zurück. Löschen Sie am besten die Felder und stellen Sie nur die Felder für Jahr, Monat und Tag ein.
Jonathan Drapeau
31

Irgendwelche Meinungen zu dieser Alternative?

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
Robert Brown
quelle
1
Ich denke nicht, dass das funktionieren würde, selbst wenn die Konvertierung in Strings eine gute Idee wäre. Der ==Operator gibt nicht unbedingt truefür äquivalente Strings (Verwendung equals()) zurück. Die anderen von Ihnen genannten Vergleichsoperatoren können Sie sicherlich auch nicht verwenden.
Harto
1
Ahh ja - mein Rubin ruiniert mein Java! Könnte die Zeichenfolgen jedoch für <,> usw. in Ints konvertieren.
Robert Brown
Joda zu benutzen ist der richtige Weg, aber das ist elegant!
Arne Evertsson
Dies funktioniert nicht für alle, ist aber sehr einfach und leicht. Eine gute Alternative, wenn andere Bibliotheken nicht verfügbar sind.
Jacob Marble
Um die Reihenfolge der Daten zu erhalten, können Sie auch verwenden sdf.format(date1).compareTo(sdf.format(date2));.
Ole VV
18

Wenn Sie nur den Monat, den Tag und das Jahr zweier Daten vergleichen möchten, funktioniert der folgende Code für mich:

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));

Danke Rob.

Dellanio
quelle
13

Ich bevorzuge auch Joda Time , aber hier ist eine Alternative:

long oneDay = 24 * 60 * 60 * 1000
long d1 = first.getTime() / oneDay
long d2 = second.getTime() / oneDay
d1 == d2

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.

long oneDay = 24 * 60 * 60 * 1000
long hoursFromUTC = -4 * 60 * 60 * 1000 // EST with Daylight Time Savings
long d1 = (first.getTime() + hoursFromUTC) / oneDay
long d2 = (second.getTime() + hoursFromUTC) / oneDay
d1 == d2
Daniel C. Sobral
quelle
Ich sagte, ich würde lieber Joda Time verwenden, aber das ist ein guter Punkt. Ich greife nur dann auf so niedrige Taktiken zurück, wenn ich nicht wirklich an der TZ interessiert bin.
Daniel C. Sobral
Teilung kann vermieden werden:Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
Vadzim
@ Vadzim Mach es < oneDay.
Daniel C. Sobral
2
@Vadzim, der nur prüft, ob die Daten weniger als 1 Tag voneinander entfernt sind. Das bedeutet nicht unbedingt, dass sie am selben Tag sind.
Arahant
@arahant, ja. Dies kann ausreichend sein, wenn das zweite Datum immer auf Mitternacht ausgerichtet ist.
Vadzim
12

tl; dr

myJavaUtilDate1.toInstant()
               .atZone( ZoneId.of( "America/Montreal" ) )
               .toLocalDate()
               .isEqual (
                   myJavaUtilDate2.toInstant()
                                  .atZone( ZoneId.of( "America/Montreal" ) )
                                  .toLocalDate()
               )

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.Daterepräsentiert einen Moment auf der Timeline in UTC. Das Äquivalent in java.time ist Instant. Sie können mit neuen Methoden konvertieren, die der Legacy-Klasse hinzugefügt wurden.

Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();

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 Beispiel America/Montreal, Africa/Casablancaoder Pacific/Auckland. Verwenden Sie niemals die Abkürzung für 3-4 Buchstaben, wie z. B. ESToder ISTda es sich nicht um echte Zeitzonen handelt, die nicht standardisiert und nicht einmal eindeutig (!) Sind.

ZoneId z = ZoneId.of( "America/Montreal" );

Wenden Sie das ZoneIdan Instant, um eine zu erhalten ZonedDateTime.

ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );

Die LocalDateKlasse repräsentiert einen Nur-Datum-Wert ohne Tageszeit und ohne Zeitzone. Wir können a LocalDateaus a extrahieren ZonedDateTimeund so den Tageszeitanteil effektiv eliminieren.

LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();

Vergleichen Sie nun, Methoden wie isEqual, isBeforeund isAfter.

Boolean sameDate = localDate1.isEqual( localDate2 );

Sehen Sie diesen Code live auf IdeOne.com .

instant1: 2017-03-25T04: 13: 10.971Z | instant2: 2017-03-24T22: 13: 10.972Z

zdt1: 2017-03-25T00: 13: 10.971-04: 00 [Amerika / Montreal] | zdt2: 2017-03-24T18: 13: 10.972-04: 00 [Amerika / Montreal]

localDate1: 2017-03-25 | localDate2: 2017-03-24

sameDate: false


Ü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 .

Basil Bourque
quelle
7

Bereits erwähnte Apache Commons-Utils :

org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DAY_OF_MONTH)

gibt Ihnen ein Datumsobjekt, das nur Datum ohne Uhrzeit enthält, und Sie können es mit vergleichen Date.compareTo

Donau-Seemann
quelle
6

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 date1ein Ereignis angeben, das in der Zeitzone +2 aufgetreten date2ist, 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.

Roland Tepp
quelle
6

Wenn Sie Java 8 verwenden, sollten Sie die java.time.*Klassen zum Vergleichen von Daten verwenden - dies wird den verschiedenen java.util.*Klassen vorgezogen

z.B; https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html

LocalDate date1 = LocalDate.of(2016, 2, 14);
LocalDate date2 = LocalDate.of(2015, 5, 23);
date1.isAfter(date2);
Lorcan O'Neill
quelle
5

Wenn Sie nur zwei Daten ohne Zeit vergleichen möchten, kann der folgende Code hilfreich sein:

final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date dLastUpdateDate = dateFormat.parse(20111116);
Date dCurrentDate = dateFormat.parse(dateFormat.format(new Date()));
if (dCurrentDate.after(dLastUpdateDate))
{
   add your logic
}
Pritesh Shah
quelle
Das ist das gleiche wie Robs Antwort . Ich denke, Jorns Lösung ist besser, da sie keinen Roundtrip zu Strings beinhaltet und dasselbe erreichen sollte.
Rup
4

Hier ist eine Lösung aus diesem Blog: http://brigitzblog.blogspot.com/2011/10/java-compare-dates.html

long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("Time in days: " + diffDays  + " days.");

Sie können also sehen, ob der Zeitunterschied in Millisekunden weniger als die Länge eines Tages beträgt.

Wilbert
quelle
4
Diese Stichprobe prüft, ob die beiden Daten innerhalb von 24 Stunden voneinander entfernt sind, aber nicht unbedingt, ob sie beide am selben Datum liegen, dh es ist möglich, eine Mitternacht zu überspannen. Besser wäre es, stattdessen beide Millisätze durch MILLIS_IN_DAY zu teilen und das Ergebnis zu vergleichen, aber das gilt nur für UTC, nicht für Ortszeiten.
Rup
4

`

SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy")

   Date date1=sdf.parse("03/25/2015");



  Date currentDate= sdf.parse(sdf.format(new Date()));

   return date1.compareTo(currentDate);

`

Zakir
quelle
3

Ich weiß nicht, ob es neu ist oder nicht, aber ich zeige es dir, wie ich es getan habe

SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yyyy");
Date td_date = new Date();
String first_date = dtf.format(td_date);    //First seted in String 
String second_date = "30/11/2020";          //Second date you can set hear in String

String result = (first_date.equals(second_date)) ? "Yes, Its Equals":"No, It is not Equals";
System.out.println(result);
13hola
quelle
3

Überprüfen Sie einfach DAY_OF_YEAR in Kombination mit der YEAR-Eigenschaft

boolean isSameDay = 
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)

BEARBEITEN:

Jetzt können wir die Leistung der Kotlin-Erweiterungsfunktionen nutzen

fun Calendar.isSameDay(second: Calendar): Boolean {

    return this[Calendar.YEAR] == second[Calendar.YEAR] && this[Calendar.DAY_OF_YEAR] == second[Calendar.DAY_OF_YEAR]
}

fun Calendar.compareDatesOnly(other: Calendar): Int {

    return when {
        isSameDay(other) -> 0
        before(other) -> -1
        else -> 1
    }
}
Simon K. Gerges
quelle
Es ist falsch, weil Daten mit unterschiedlichen Jahren denselben Tag des Jahres haben können, z. B. 2015-01-01 und 2016-01-01.
Nelson Eldoro
@ Nelsoneldoro danke für deinen Kommentar, habe vergessen, einen Scheck für das Jahr hinzuzufügen, jetzt sollte es in Ordnung sein.
Simon K. Gerges
2

In Java 8 können Sie LocalDate verwenden, das dem von Joda Time sehr ähnlich ist.

habsq
quelle
2
public Date saveDateWithoutTime(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( date );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.HOUR, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}

Auf diese Weise können Sie Daten ohne Berücksichtigung der Uhrzeit vergleichen.

Fathima km
quelle
1

Mit getDateInstance von SimpleDateFormat können wir nur zwei Datumsobjekte ohne Zeit vergleichen. Führen Sie den folgenden Code aus.

public static void main(String[] args) {        
        Date date1  = new Date();
        Date date2  = new Date();
        DateFormat dfg = SimpleDateFormat.getDateInstance(DateFormat.DATE_FIELD);
        String dateDtr1 = dfg.format(date1);
        String dateDtr2 = dfg.format(date2);
        System.out.println(dateDtr1+" : "+dateDtr2);
        System.out.println(dateDtr1.equals(dateDtr2));  

    }
Senthil Eswaramoorthy
quelle
1

Verwenden von http://mvnrepository.com/artifact/commons-lang/commons-lang

Date date1 = new Date();

Date date2 = new Date();

if (DateUtils.truncatedCompareTo(date1, date2, Calendar.DAY_OF_MONTH) == 0)
    // TRUE
else
    // FALSE
Federico Traiman
quelle
3
Oder einfach DateUtils.isSameDay(date1, date2).
OliBlogger
1

Eine weitere einfache Vergleichsmethode basierend auf den Antworten hier und meiner Mentor-Anleitung

public static int compare(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.setTime(d1);
    c1.set(Calendar.MILLISECOND, 0);
    c1.set(Calendar.SECOND, 0);
    c1.set(Calendar.MINUTE, 0);
    c1.set(Calendar.HOUR_OF_DAY, 0);
    c2.setTime(d2);
    c2.set(Calendar.MILLISECOND, 0);
    c2.set(Calendar.SECOND, 0);
    c2.set(Calendar.MINUTE, 0);
    c2.set(Calendar.HOUR_OF_DAY, 0);
    return c1.getTime().compareTo(c2.getTime());
  }

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:

public static int compare2(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.clear();
    c2.clear();
    c1.set(Calendar.YEAR, d1.getYear());
    c1.set(Calendar.MONTH, d1.getMonth());
    c1.set(Calendar.DAY_OF_MONTH, d1.getDay());
    c2.set(Calendar.YEAR, d2.getYear());
    c2.set(Calendar.MONTH, d2.getMonth());
    c2.set(Calendar.DAY_OF_MONTH, d2.getDay());
    return c1.getTime().compareTo(c2.getTime());
}

Bitte beachten Sie, dass die Date-Klasse veraltet ist, da sie nicht internationalisiert werden konnte. Stattdessen wird die Calendar-Klasse verwendet!

Abdelrahman Aly
quelle
Dies funktioniert nicht 100% der Zeit. Hatte einen Anwendungsfall, in dem ich das getan habe, und die Datei calendar.getTime () gab immer noch die Uhrzeit mit den als Parameterdatum festgelegten Stunden zurück. Löschen Sie am besten die Felder und stellen Sie nur die Felder für Jahr, Monat und Tag ein.
Jonathan Drapeau
@ JonathanDrapeau, es hört sich für mich so an, als ob Sie möglicherweise darauf gestoßen sind, keine explizite Zeitzone auszuwählen. Machen Sie die Zeitzone auf jeden Fall besser explizit, als die veralteten getXxxMethoden von Date.
Ole VV
1

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:

public class ArnesClass implements Comparable<ArnesClass> {

    private static final ZoneId arnesTimeZone = ZoneId.systemDefault();

    private Instant when;

    @Override
    public int compareTo(ArnesClass o) {
        // question is what to put here
    }

}

Java 8 java.timeKlassen

Ich habe mir die Freiheit genommen, den Typ Ihres Instanzfelds von Datein Instantdie entsprechende Klasse in Java 8 zu ändern . Ich verspreche, zur folgenden Behandlung zurückzukehren Date. Ich habe auch eine Zeitzonenkonstante hinzugefügt. Sie können es auf ZoneOffset.UTCoder ZoneId.of("Europe/Stockholm")oder das setzen, was Sie für angemessen halten (es auf ein ZoneOffsetWerk setzen, weil ZoneOffsetes eine Unterklasse von ist ZoneId).

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 compareToMethode, nach der Sie gefragt haben:

public int compareTo(ArnesClass o) {
    LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
    LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
    return dateWithoutTime.compareTo(otherDateWithoutTime);
}

Wenn Sie nie die Zeit Teil benötigen when, ist es natürlich leichter zu erklären , whenein LocalDateund alle Conversions überspringen. Dann müssen wir uns auch nicht mehr um die Zeitzone kümmern.

Nehmen wir nun an, Sie können Ihr whenFeld aus irgendeinem Grund nicht deklarieren Instantoder möchten es altmodisch halten Date. Wenn Sie Java 8 weiterhin verwenden können, konvertieren Sie es einfach in Instantund gehen Sie wie folgt vor:

    LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();

Ähnliches gilt für o.when.

Kein Java 8?

Wenn Sie Java 8 nicht verwenden können, gibt es zwei Möglichkeiten:

  1. Löse es mit einer der alten Klassen, entweder Calendaroder SimpleDateFormat.
  2. Verwenden Sie den Backport der Java 8-Datums- und Zeitklassen für Java 6 und 7 und gehen Sie dann wie oben beschrieben vor. Ich füge unten einen Link hinzu. Verwenden Sie JodaTime nicht. JodaTime war wahrscheinlich ein guter Vorschlag, als die Antworten, die es empfahlen, geschrieben wurden; Da sich JodaTime jetzt im Wartungsmodus befindet, ist der ThreeTen-Backport eine bessere und zukunftssicherere Option.

Die altmodischen Wege

Die Antwort von Adamski zeigt Ihnen, wie Sie den Zeitteil Datemithilfe der CalendarKlasse entfernen können. Ich schlage vor, Sie verwenden getInstance(TimeZone), um die CalendarInstanz für die gewünschte Zeitzone zu erhalten . Alternativ können Sie die Idee aus der zweiten Hälfte von Jorns Antwort verwenden .

Verwenden SimpleDateFormatist wirklich eine indirekte Art zu verwenden, Calendarda a SimpleDateFormatein CalendarObjekt enthält . Möglicherweise ist dies jedoch weniger problematisch als die Calendardirekte Verwendung :

private static final TimeZone arnesTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
private static final DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
static {
    formatter.setTimeZone(arnesTimeZone);
}

private Date when;

@Override
public int compareTo(ArnesClass o) {
    return formatter.format(when).compareTo(formatter.format(o.when));
}

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/ .

Ole VV
quelle
0

Mein Vorschlag:

    Calendar cal = Calendar.getInstance();
    cal.set(1999,10,01);   // nov 1st, 1999
    cal.set(Calendar.AM_PM,Calendar.AM);
    cal.set(Calendar.HOUR,0);
    cal.set(Calendar.MINUTE,0);
    cal.set(Calendar.SECOND,0);
    cal.set(Calendar.MILLISECOND,0);

    // date column in the Thought table is of type sql date
    Thought thought = thoughtDao.getThought(date, language);

    Assert.assertEquals(cal.getTime(), thought.getDate());
Jean-Pierre Schnyder
quelle
0

Mit Apache Commons können Sie Folgendes tun:

import org.apache.commons.lang3.time.DateUtils

DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)
vereinheitlichen
quelle
0
public static Date getZeroTimeDate(Date fecha) {
    Date res = fecha;
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( fecha );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    res = calendar.getTime();

    return res;
}

Date currentDate = getZeroTimeDate(new Date());// get current date   

Dies ist der einfachste Weg, um dieses Problem zu lösen.

rana_sadam
quelle
0

Ich habe dies durch einen Vergleich nach Zeitstempel gelöst:

    Calendar last = Calendar.getInstance();

    last.setTimeInMillis(firstTimeInMillis);

    Calendar current = Calendar.getInstance();

    if (last.get(Calendar.DAY_OF_MONTH) != current.get(Calendar.DAY_OF_MONTH)) {
        //not the same day
    }

Ich vermeide es, Joda Time zu verwenden, da Android einen riesigen Speicherplatz benötigt. Die Größe ist wichtig. ;)

Oscar Josue Alvrez
quelle
0

Eine andere Lösung mit Java 8 und Instant ist die Verwendung der Methode truncatedTo

Gibt eine Kopie dieses Instant zurück, die auf die angegebene Einheit gekürzt wurde.

Beispiel:

@Test
public void dateTruncate() throws InterruptedException {
    Instant now = Instant.now();
    Thread.sleep(1000*5);
    Instant later = Instant.now();
    assertThat(now, not(equalTo(later)));
    assertThat(now.truncatedTo(ChronoUnit.DAYS), equalTo(later.truncatedTo(ChronoUnit.DAYS)));
}
rince
quelle
0
// Create one day 00:00:00 calendar
int oneDayTimeStamp = 1523017440;
Calendar oneDayCal = Calendar.getInstance();
oneDayCal.setTimeInMillis(oneDayTimeStamp * 1000L);
oneDayCal.set(Calendar.HOUR_OF_DAY, 0);
oneDayCal.set(Calendar.MINUTE, 0);
oneDayCal.set(Calendar.SECOND, 0);
oneDayCal.set(Calendar.MILLISECOND, 0);

// Create current day 00:00:00 calendar
Calendar currentCal = Calendar.getInstance();
currentCal.set(Calendar.HOUR_OF_DAY, 0);
currentCal.set(Calendar.MINUTE, 0);
currentCal.set(Calendar.SECOND, 0);
currentCal.set(Calendar.MILLISECOND, 0);

if (oneDayCal.compareTo(currentCal) == 0) {
    // Same day (excluding time)
}
Yaslam
quelle
Vielen Dank! Es gibt jedoch bereits eine Handvoll anderer Antworten mit demselben Ansatz - obwohl ich jetzt sehe, dass Sie die Kalenderobjekte direkt vergleichen, während sie die getTime () s weitgehend vergleichen.
Rup
-2

Das hat bei mir funktioniert:

var Date1 = new Date(dateObject1.toDateString()); //this sets time to 00:00:00
var Date2 = new Date(dateObject2.toDateString()); 
//do a normal compare
if(Date1 > Date2){ //do something }
Technomama
quelle
2
Ihr "normaler" Vergleich würde nicht einmal in Java kompiliert. Wenn dies der Fall wäre, würden die Objektreferenzen verglichen, dies ist jedoch nicht zulässig.
Stivlo
Ich habe bearbeitet, um Markdown hinzuzufügen, aber stivlo ist richtig. Ich habe keine Ahnung, wie dieser Code "für Sie funktioniert hat".
Pops
Dies ist wahrscheinlich js.
Andrey Luiz
-2

Wie wäre es mit DateUtil.daysBetween(). Es ist Java und es gibt eine Zahl zurück (Differenz in Tagen).

Jules
quelle