Come confrontare due date senza la parte temporale?


203

Vorrei avere un metodo compareTo che ignori la parte temporale di un java.util.Date. Immagino che ci siano molti modi per risolverlo. Qual è il modo più semplice?

Risposte:


212

Aggiornamento: mentre Joda Time era una buona raccomandazione al momento, utilizzare la java.timelibreria da Java 8+ invece, ove possibile.


La mia preferenza è usare Joda Time, il che rende questo incredibilmente facile:

DateTime first = ...;
DateTime second = ...;

LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();

return firstDate.compareTo(secondDate);

EDIT: come notato nei commenti, se lo usi DateTimeComparator.getDateOnlyInstance()è ancora più semplice :)

// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);

("Usa Joda Time" è la base di quasi tutte le domande SO che pongono java.util.Dateo java.util.Calendar. È un'API di qualità superiore. Se stai facendo qualcosa di significativo con date / orari, dovresti davvero usarlo se possibile.)

Se sei assolutamente costretto a utilizzare l'API integrata, devi creare un'istanza Calendarcon la data appropriata e utilizzando il fuso orario appropriato. È quindi possibile impostare ciascun campo in ciascun calendario su ore, minuti, secondi e millisecondi su 0 e confrontare i tempi risultanti. Sicuramente icky rispetto alla soluzione Joda però :)

La parte del fuso orario è importante: java.util.Datesi basa sempre su UTC. Nella maggior parte dei casi in cui sono stato interessato a una data, quella è stata una data in un fuso orario specifico . Che da solo ti costringerà a utilizzare Calendaro Joda Time (a meno che tu non voglia tenere conto del fuso orario, che non consiglio.)

Riferimento rapido per gli sviluppatori Android

//Add joda library dependency to your build.gradle file
dependencies {
     ...
     implementation 'joda-time:joda-time:2.9.9'
}

Codice di esempio (esempio)

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

28
Anche se Jon dice "Usa Joda Time" è la base di quasi tutte le domande SO che pongono su java.util.Date o java.util.Calendar Penso sempre che in primo luogo sia meglio dare una risposta concreta basata sulla domanda dell'utente, a almeno per mostrare quanto può essere difficile fare il modo java. E dopo quello che suggerisce di usare Joda ...
JuanZe,

13
@JuanZe: questo richiede di capire esattamente come fare correttamente qualcosa in un'API dolorosa, che è per definizione dolorosa. Preferirei passare quel tempo a fare qualcosa di più produttivo :)
Jon Skeet,

1
@ MetroidFan2002: LocalDate è un'opzione migliore di DateMidnight, poiché è più espressiva - e non tutti i giorni hanno una mezzanotte ...
Jon Skeet,

2
@dertoni: Certo - in Brasile, quando gli orologi vanno avanti a causa dell'ora legale, ciò accade all'inizio della giornata ... quindi l'orologio indica 23:59:58, 23:59:59, 01:00 : 00, 01:00:01 ecc.
Jon Skeet,

8
Emil

125

Apache commons-lang è quasi onnipresente. E allora?

if (DateUtils.isSameDay(date1, date2)) {
    // it's same
} else if (date1.before(date2)) {
   // it's before
} else {
   // it's after
}

La versione 2.6 includeva una funzione troncataCompareTo commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/…
shonky linux user

2
Purtroppo non tollera le date nulle
Pavel Niedoba,

Ragazzi, oggi abbiamo Java 8 stackoverflow.com/a/35411693/259237
André

Non è consigliabile l'utilizzo prima di questo modo perché se il primo o il secondo oggetto Date è stato trasmesso da Timestamp e ha miglia di secondo, e l'altro è un normale oggetto Date, avrai problemi perché, la data dal datestamp archivia in una parte diversa il dell'oggetto i millisecondi danno differenze anche quando entrambe le date sono uguali.
Zini

Sfortunatamente, Apache non è su più di 1,3 miliardi di dispositivi Android ed è un'enorme libreria da cui dipendere per un solo caso d'uso. Avrò bisogno di qualcos'altro: /
milosmns il

58

Se vuoi davvero usare java.util.Date, dovresti fare qualcosa del genere:

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

oppure, usando invece un Calendario (preferito, poiché getYear () e simili sono obsoleti)

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

1
Nel secondo metodo hai dimenticato di aggiornare alcuni dei tuoi riferimenti, da d1, d2 a c1, c2.
stivlo,

1
Dopo aver corretto quel dettaglio il tuo codice funziona bene: l'ho ampiamente testato dall'unità. Ho aggiunto il passaggio per creare un Calendario dalle date e ho usato il tuo codice nel mio progetto github appena creato org.obliquid.helpers , grazie.
stivlo,

Dolce, bella soluzione senza usare alcuna libreria esterna.
4gus71n,

1
Tutti questi metodi sono obsoleti. Questo può avere qualche tipo di impatto?
Pranav Mahajan,

36

La mia preferenza sarebbe quella di utilizzare la libreria Jodajava.util.Date direttamente, poiché Joda fa una distinzione tra data e ora (vedi le classi YearMonthDay e DateTime ).

Tuttavia, se si desidera utilizzare java.util.Date, suggerirei di scrivere un metodo di utilità; per esempio

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

1
Joda-Time YearMonthDay è deprecato a favore di LocalDate. Inoltre, il codice sul calendario avrà problemi se il fuso orario non ha mezzanotte 00:00 a causa dell'ora legale.
JodaStephen,

1
Questo non funziona il 100% delle volte. Ho avuto un caso d'uso in cui l'ho fatto e il calendar.getTime () avrebbe comunque restituito l'ora con le ore impostate come data del parametro. Meglio cancellare i campi e impostare solo l'anno, il mese e il giorno.
Jonathan Drapeau,

31

Qualche opinione su questa alternativa?

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

1
Non penso che funzionerebbe, anche se la conversione in stringhe fosse una buona idea. L' ==operatore non ritorna necessariamente trueper stringhe equivalenti (uso equals()). Certamente non puoi nemmeno usare gli altri operatori di confronto che hai citato.
Harto,

1
Ah sì - il mio rubino sta rovinando il mio Java! Potrebbe convertire le stringhe in inte anche se per <,> ecc.
Robert Brown,

Usare Joda è il modo giusto, ma questo è elegante!
Arne Evertsson,

Questo non funzionerà per tutti, ma è molto semplice e leggero; una buona alternativa quando non sono disponibili altre librerie.
Jacob Marble,

Per ottenere l'ordine delle date, puoi anche usare sdf.format(date1).compareTo(sdf.format(date2));.
Ole VV,

18

Se vuoi confrontare solo il mese, il giorno e l'anno di due date, il seguente codice funziona per me:

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

Grazie Rob.


13

Anch'io preferisco Joda Time , ma ecco un'alternativa:

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

MODIFICARE

Ho messo la cosa UTC qui sotto nel caso in cui sia necessario confrontare le date per un fuso orario specifico diverso da UTC. Se hai un tale bisogno, però, ti consiglio davvero di scegliere Joda.

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

Ho detto che avrei preferito usare Joda Time, ma questo è un buon punto. Ricorro a tattiche così basse solo quando non sono veramente interessato alla TZ.
Daniel C. Sobral,

La divisione può essere evitata:Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
Vadzim,

@Vadzim Make it < oneDay.
Daniel C. Sobral,

2
@Vadzim, che controlla solo se le date sono distanti meno di 1 giorno. Non significa necessariamente che siano nello stesso giorno.
Arahant,

@arahant, sì. questo può essere sufficiente quando la seconda data è sempre allineata a mezzanotte.
Vadzim,

12

tl; dr

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

Evita le classi di data e ora legacy

Evita le fastidiose vecchie classi di data e ora come Date& Calendar, ora soppiantate dalle classi java.time.

Utilizzando java.time

A java.util.Daterappresenta un momento nella sequenza temporale in UTC. L'equivalente in java.time è Instant. È possibile convertire utilizzando nuovi metodi aggiunti alla classe legacy.

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

Vuoi confrontare per data. Un fuso orario è fondamentale per determinare una data. Per ogni dato momento, la data varia intorno al globo per zona. Ad esempio, pochi minuti dopo la mezzanotte a Parigi, la Francia è un nuovo giorno mentre è ancora “ieri” a Montréal Québec .

Specificare un nome proprio fuso orario nel formato continent/region, come ad esempio America/Montreal, Africa/CasablancaoPacific/Auckland . Non usare mai il 3-4 lettera sigla come ad esempio ESTo ISTcome sono non fusi orari veri e propri, non standardizzati, e nemmeno unico (!).

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

Applicare ZoneIda Instantper ottenere a ZonedDateTime.

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

Il LocalDate classe rappresenta un valore solo per la data senza ora del giorno e senza fuso orario. Siamo in grado di estrarre un LocalDateda un ZonedDateTime, eliminando efficacemente la porzione dell'ora del giorno.

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

Ora confronta, usando metodi come isEqual , isBeforee isAfter.

Boolean sameDate = localDate1.isEqual( localDate2 );

Vedi questo codice eseguito dal vivo su 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 [America / Montreal] | zdt2: 2017-03-24T18: 13: 10.972-04: 00 [America / Montreal]

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

sameDate: false


Informazioni su java.time

Il framework java.time è integrato in Java 8 e versioni successive. Queste classi soppiantare la vecchia fastidiosi legacy classi data-time come java.util.Date, Calendar, eSimpleDateFormat .

Il progetto Joda-Time , ora in modalità manutenzione , consiglia la migrazione a java.time classi .

Per saperne di più, consulta il tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .

Dove ottenere le classi java.time?

Il progetto ThreeTen-Extra estende java.time con classi aggiuntive. Questo progetto è un banco di prova per possibili aggiunte future a java.time. Si possono trovare alcune classi utili, come per esempio Interval, YearWeek, YearQuartere altro .


7

Già menzionato apache commons-utils :

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

ti dà un oggetto Date contenente solo la data, senza ora, e puoi confrontarlo con Date.compareTo


6

Temo che non esista un metodo per confrontare due date che potrebbero essere definite "facili" o "semplici".

Quando si confrontano due istanze temporali con qualsiasi tipo di precisione ridotta (ad esempio solo il confronto delle date), è necessario tenere sempre conto di come il fuso orario influisce sul confronto.

Se date1si specifica un evento che si è verificato nel fuso orario +2 e date2si specifica un evento che si è verificato in EST, ad esempio, è necessario fare attenzione a comprendere correttamente le implicazioni del confronto.

Il tuo scopo è capire se i due eventi si sono verificati nella stessa data di calendario nei rispettivi fusi orari? Oppure devi sapere se le due date cadono nella stessa data di calendario in un fuso orario specifico (UTC o la TZ locale, per esempio).

Una volta capito che cosa stai effettivamente cercando di confrontare, è solo una questione di ottenere la tripla anno-mese-data in un fuso orario appropriato ed eseguire il confronto.

Il tempo di Joda potrebbe rendere l'operazione di confronto reale molto più pulita, ma la semantica del confronto è ancora qualcosa che devi capire da solo.



5

Se vuoi solo confrontare solo due date senza tempo, il seguente codice potrebbe aiutarti:

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
}

È la stessa della risposta di Rob . Penso che la soluzione di Jorn sia migliore poiché non prevede un round trip per le stringhe e dovrebbe realizzare la stessa cosa.
Rup,

4

Ecco una soluzione da questo 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.");

cioè puoi vedere se la differenza di tempo in millisecondi è inferiore alla lunghezza di un giorno.


4
Quel campione controllerà se le due date sono entro 24 ore l'una dall'altra, ma non necessariamente se sono entrambe nella stessa data, cioè è possibile passare una mezzanotte. Meglio sarebbe invece dividere entrambi i set di millis per MILLIS_IN_DAY e confrontare il risultato, ma sarà esatto solo per l'ora UTC non locale.
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);

`


3

Non so che è nuovo pensare altrimenti, ma ti faccio vedere come ho fatto

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

3

Controlla semplicemente DAY_OF_YEAR in combinazione con la proprietà YEAR

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

MODIFICARE:

Ora possiamo usare la potenza delle funzioni di estensione di Kotlin

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

È sbagliato perché le date con anni diversi possono avere lo stesso giorno dell'anno, ad esempio 2015-01-01 e 2016-01-01.
Nelson Eldoro,

@nelsoneldoro grazie per il tuo commento, ho dimenticato di aggiungere un assegno per l'anno, ora dovrebbe essere ok.
Simon K. Gerges,

2

In Java 8 è possibile utilizzare LocalDate che è molto simile a quello di Joda Time.


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

Questo ti aiuterà a confrontare le date senza considerare l'ora.


1

Usando getDateInstance di SimpleDateFormat, possiamo confrontare solo due oggetti data senza ora. Eseguire il codice seguente.

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

    }


1

Un altro metodo di confronto semplice basato sulle risposte qui e sulla mia guida del mentore

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 : Secondo @Jonathan Drapeau, il codice sopra fallisce alcuni casi (mi piacerebbe vedere quei casi, per favore) e ha suggerito quanto segue a quanto ho capito:

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

Si noti che la classe Date è obsoleta perché non era suscettibile di internazionalizzazione. Al suo posto viene utilizzata la classe Calendar!


Questo non funziona il 100% delle volte. Ho avuto un caso d'uso in cui l'ho fatto e il calendar.getTime () avrebbe comunque restituito l'ora con le ore impostate come data del parametro. Meglio cancellare i campi e impostare solo l'anno, il mese e il giorno.
Jonathan Drapeau,

@JonathanDrapeau, mi sembra che potresti esserti imbattuto in una conseguenza della mancata selezione di un fuso orario esplicito. Certamente rendere esplicito il fuso orario piuttosto che utilizzare i getXxxmetodi obsoleti di Date.
Ole VV,

1

Innanzitutto, tenere presente che questa operazione dipende dal fuso orario. Quindi scegli se vuoi farlo in UTC, nel fuso orario del computer, nel tuo fuso orario preferito o dove. Se non sei ancora convinto che sia importante, vedi il mio esempio in fondo a questa risposta.

Dal momento che la tua domanda non è abbastanza chiara a riguardo, presumo che tu abbia una classe con un campo di istanza che rappresenta un punto nel tempo e un'implementazione Comparablee desideri che l'ordine naturale dei tuoi oggetti sia entro la data, ma non l'ora , di quel campo. Per esempio:

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.timeClassi Java 8

Ho preso la libertà di cambiare il tipo del campo della tua istanza da Datea Instant, la classe corrispondente in Java 8. Prometto di tornare al trattamento di Dateseguito. Ho anche aggiunto una costante di fuso orario. Puoi impostarlo su ZoneOffset.UTCo su ZoneId.of("Europe/Stockholm")ciò che ritieni appropriato (impostandolo su un'opera ZoneOffsetperché ZoneOffsetè una sottoclasse di ZoneId).

Ho scelto di mostrare la soluzione usando le classi Java 8. Hai chiesto il modo più semplice, giusto? :-) Ecco il compareTometodo che hai richiesto:

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

Se non hai mai bisogno del tempo when, è ovviamente più facile dichiarare whena LocalDatee saltare tutte le conversioni. Quindi non dobbiamo più preoccuparci nemmeno del fuso orario.

Supponiamo ora che per qualche motivo non puoi dichiarare il tuo whencampo Instanto vuoi mantenerlo vecchio stile Date. Se puoi ancora usare Java 8, convertilo in Instant, quindi fai come prima:

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

Allo stesso modo per o.when.

No Java 8?

Se non puoi usare java 8, ci sono due opzioni:

  1. Risolvilo usando una delle vecchie classi, o Calendaro SimpleDateFormat.
  2. Utilizzare il backport delle classi di data e ora di Java 8 su Java 6 e 7, quindi fare come sopra. Includo un link in fondo. Non usare JodaTime. JodaTime è stato probabilmente un buon suggerimento quando sono state scritte le risposte che lo raccomandano; ma JodaTime è ora in modalità manutenzione, quindi il backport ThreeTen è un'opzione migliore e più a prova di futuro.

I vecchi modi

La risposta di Adamski ti mostra come eliminare il tempo parziale Dateusando una Calendarclasse. Ti suggerisco di utilizzare getInstance(TimeZone)per ottenere l' Calendaristanza per il fuso orario desiderato. In alternativa puoi usare l'idea della seconda metà della risposta di Jorn .

L'uso SimpleDateFormatè davvero un modo indiretto di usare Calendarpoiché a SimpleDateFormatcontiene un Calendaroggetto. Tuttavia, potresti trovarlo meno problematico rispetto all'utilizzo Calendardiretto:

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

Questo è stato ispirato dalla risposta di Rob .

Dipendenza dal fuso orario

Perché dobbiamo scegliere un fuso orario specifico? Diciamo che vogliamo confrontare due volte che in UTC sono il 24 marzo 0:00 (mezzanotte) e 12:00 (mezzogiorno). Se lo fai in CET (diciamo, Europa / Parigi), sono le 1:00 e le 13:00 del 24 marzo, ovvero la stessa data. A New York (Eastern Daylight Time), sono le 20:00 del 23 marzo e le 8:00 del 24 marzo, ovvero non la stessa data. Quindi fa la differenza quale fuso orario scegli. Se fai affidamento solo sul valore predefinito del computer, potresti essere sorpreso quando qualcuno tenta di eseguire il codice su un computer in un altro posto in questo mondo globalizzato.

collegamento

Link a ThreeTen Backport, il backport delle classi di data e ora di Java 8 a Java 6 e 7: http://www.threeten.org/threetenbp/ .


0

La mia proposta:

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

0

Usando i comuni di Apache puoi fare:

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

DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)

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   

questo è il modo più semplice per risolvere questo problema.


0

Ho risolto questo confronto confrontando per timestamp:

    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
    }

Evito di usare Joda Time perché su Android utilizza uno spazio enorme. Le misure contano. ;)


0

Un'altra soluzione che utilizza Java 8 e Instant, sta usando il metodo truncatedTo

Restituisce una copia di questo Instant troncato all'unità specificata.

Esempio:

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

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

Grazie! Ci sono già alcune altre risposte con lo stesso approccio, anche se ora vedo che stai confrontando direttamente gli oggetti Calendar mentre in gran parte confrontano i getTime ().
Rup,

-2

Questo è ciò che ha funzionato per me:

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 }

2
Il tuo confronto "normale" non verrebbe nemmeno compilato in Java. In tal caso, confronterebbe i riferimenti agli oggetti, ma ciò non è consentito.
stivlo,

Ho modificato per aggiungere Markdown, ma stivlo ha ragione. Non ho idea di come quel codice "ha funzionato per te".
apre il

Questo è probabilmente js.
Andrey Luiz,

-2

Che ne dici di DateUtil.daysBetween(). È Java e restituisce un numero (differenza in giorni).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.