Comment comparer deux dates sans la portion de temps?

203

Je voudrais avoir une méthode compareTo qui ignore la partie temporelle d'un java.util.Date. Je suppose qu'il y a plusieurs façons de résoudre ce problème. Quelle est la manière la plus simple?

Arne Evertsson
la source

Réponses:

212

Mise à jour: alors que Joda Time était une bonne recommandation à l'époque, utilisez java.timeplutôt la bibliothèque de Java 8+ lorsque cela est possible.


Ma préférence est d'utiliser Joda Time, ce qui rend cela incroyablement facile:

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

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

return firstDate.compareTo(secondDate);

EDIT: Comme indiqué dans les commentaires, si vous utilisez DateTimeComparator.getDateOnlyInstance()c'est encore plus simple :)

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

("Utiliser Joda Time" est la base de presque toutes les questions SO qui posent des questions sur java.util.Dateou java.util.Calendar. C'est une API complètement supérieure. Si vous faites quelque chose d' important avec les dates / heures, vous devriez vraiment l'utiliser si vous le pouvez.)

Si vous êtes absolument obligé d'utiliser l'API intégrée, vous devez créer une instance de Calendaravec la date appropriée et en utilisant le fuseau horaire approprié. Vous pouvez ensuite définir chaque champ de chaque calendrier sur heure, minute, seconde et milliseconde sur 0 et comparer les temps résultants. Certainement icky par rapport à la solution Joda cependant :)

La partie fuseau horaire est importante: elle java.util.Dateest toujours basée sur UTC. Dans la plupart des cas où je suis intéressé par une date, c'est une date dans un fuseau horaire spécifique . Cela vous obligera à utiliser CalendarJoda Time (à moins que vous ne teniez compte du fuseau horaire vous-même, ce que je ne recommande pas.)

Référence rapide pour les développeurs Android

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

Exemple de code (exemple)

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
la source
28
Même si Jon dit "Utiliser le temps Joda" est la base de presque toutes les questions SO qui posent sur java.util.Date ou java.util.Calendar Je pense toujours qu'il est préférable de donner une réponse concrète basée sur la question de l'utilisateur, à au moins pour montrer à quel point il peut être difficile de faire de la manière java. Et après avoir suggéré d'utiliser Joda ...
JuanZe
13
@JuanZe: Cela nécessite de savoir exactement comment faire quelque chose correctement dans une API douloureuse, ce qui est par définition douloureux. Je préfère passer ce temps à faire quelque chose de plus productif :)
Jon Skeet
1
@ MetroidFan2002: LocalDate est une meilleure option que DateMidnight, car il est plus expressif - et tous les jours n'ont pas minuit ...
Jon Skeet
2
@dertoni: Bien sûr - au Brésil, lorsque les horloges avancent en raison de l'heure d'été, cela se produit en début de journée ... donc une horloge indique 23:59:58, 23:59:59, 01:00 : 00, 01:00:01 etc.
Jon Skeet
8
Ne serait-il pas préférable d'utiliser DateTimeComparator.getDateOnlyInstance ()
Emil
126

Apache commons-lang est presque omniprésent. Et alors?

if (DateUtils.isSameDay(date1, date2)) {
    // it's same
} else if (date1.before(date2)) {
   // it's before
} else {
   // it's after
}
André
la source
La version 2.6 comprend une fonction truncatedCompareTo commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/...
utilisateur linux shonky
2
Malheureusement, ne tolère pas les dates nulles
Pavel Niedoba
Les gars, nous avons aujourd'hui Java 8 stackoverflow.com/a/35411693/259237
André
Je ne recommande pas d'utiliser avant de cette façon, car si le premier ou le deuxième objet Date a été diffusé à partir de Timestamp et a des secondes, et l'autre est un objet Date normal, vous aurez des problèmes car, la date du magasin d'estampilles dans une autre partie le d'objet, les millisecondes donnent des différences même lorsque les deux dates sont égales.
Zini
Malheureusement, Apache n'est pas sur plus de 1,3 milliard d'appareils Android, et c'est une énorme bibliothèque sur laquelle s'appuyer pour un seul cas d'utilisation. J'aurai besoin d'autre chose: /
milosmns
58

Si vous voulez vraiment utiliser le java.util.Date, vous feriez quelque chose comme ceci:

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

ou, en utilisant un calendrier à la place (préféré, car getYear () et autres sont obsolètes)

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
la source
1
Dans la deuxième méthode, vous avez oublié de mettre à jour certaines de vos références, de d1, d2 à c1, c2.
stivlo
1
Après avoir corrigé ce détail, votre code fonctionne bien: je l'ai testé intensivement à l'unité. J'ai ajouté l'étape pour créer un calendrier à partir des dates et utilisé votre code dans mon projet github nouvellement créé org.obliquid.helpers , merci.
stivlo
Solution douce et agréable sans utiliser de bibliothèque externe.
4gus71n
1
Toutes ces méthodes sont obsolètes. Cela peut-il avoir un impact quelconque?
Pranav Mahajan
36

Ma préférence serait d'utiliser directement la bibliothèque de Jodajava.util.Date , car Joda fait une distinction entre la date et l'heure (voir les classes YearMonthDay et DateTime ).

Cependant, si vous souhaitez l'utiliser, java.util.Dateje vous suggère d'écrire une méthode utilitaire; par exemple

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
la source
1
Joda-Time YearMonthDay est déconseillé au profit de LocalDate. De plus, le code sur le calendrier aura des problèmes si le fuseau horaire n'a pas minuit 00:00 en raison de l'heure d'été.
JodaStephen
1
Cela ne fonctionne pas 100% du temps. A eu un cas d'utilisation où je l'ai fait et le calendar.getTime () retournerait toujours l'heure avec les heures définies comme date de paramètre. Il est préférable d'effacer les champs et de définir uniquement l'année, le mois et le jour.
Jonathan Drapeau
31

Des opinions sur cette alternative?

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
Robert Brown
la source
1
Je ne pense pas que cela fonctionnerait, même si la conversion en Strings était une bonne idée. L' ==opérateur ne retourne pas nécessairement truepour des chaînes équivalentes (utilisation equals()). Vous ne pouvez certainement pas non plus utiliser les autres opérateurs de comparaison que vous avez mentionnés.
harto
1
Ahh oui - mon rubis ruine mon Java! Pourrait convertir les chaînes en ints pour <,> etc.
Robert Brown
Utiliser Joda est la voie sonore, mais c'est élégant!
Arne Evertsson
Cela ne fonctionnera pas pour tout le monde, mais c'est très simple et léger; une bonne alternative lorsque d'autres bibliothèques ne sont pas disponibles.
Jacob Marble
Pour obtenir l'ordre des dates, vous pouvez également utiliser sdf.format(date1).compareTo(sdf.format(date2));.
Ole VV
18

Si vous souhaitez comparer uniquement le mois, le jour et l'année de deux dates, le code suivant fonctionne pour moi:

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

Merci Rob.

Dellanio
la source
13

Moi aussi, je préfère Joda Time , mais voici une alternative:

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

ÉDITER

Je mets le truc UTC ci-dessous au cas où vous auriez besoin de comparer les dates pour un fuseau horaire spécifique autre que UTC. Si vous avez un tel besoin, alors je vous conseille vraiment d'aller chercher 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
Daniel C. Sobral
la source
J'ai dit que je préfèrerais utiliser Joda Time, mais c'est un bon point. Je n'ai recours à de telles tactiques que lorsque je ne suis pas vraiment intéressé par la TZ.
Daniel C.Sobral
La division peut être évitée:Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
Vadzim
@Vadzim Make it < oneDay.
Daniel C.Sobral
2
@Vadzim, qui vérifie uniquement si les dates sont espacées de moins d'un jour. Cela ne signifie pas nécessairement qu'ils sont le même jour.
arahant
@arahant, oui. cela peut être suffisant lorsque la deuxième date est toujours alignée à minuit.
Vadzim
12

tl; dr

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

Évitez les anciennes classes de date et d'heure

Évitez les anciennes classes de date et heure héritées, comme Date& Calendar, désormais supplantées par les classes java.time.

Utilisation de java.time

A java.util.Datereprésente un moment sur la timeline en UTC. L'équivalent dans java.time est Instant. Vous pouvez convertir en utilisant de nouvelles méthodes ajoutées à la classe héritée.

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

Vous souhaitez comparer par date. Un fuseau horaire est crucial pour déterminer une date. Pour un moment donné, la date varie dans le monde par zone. Par exemple, quelques minutes après minuit à Paris, la France est un nouveau jour alors qu'hier encore à Montréal Québec .

Spécifiez un nom de fuseau horaire correct au format continent/region, tel que America/Montreal,Africa/Casablanca ou Pacific/Auckland. N'utilisez jamais l'abréviation de 3 à 4 lettres telle que ESTou ISTcar ce ne sont pas de véritables fuseaux horaires, ni standardisés, ni même uniques (!).

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

Appliquez le ZoneIdà Instantpour obtenir un ZonedDateTime.

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

le LocalDate classe représente une valeur de date uniquement sans heure et sans fuseau horaire. Nous pouvons extraire un LocalDatede a ZonedDateTime, éliminant efficacement la partie de l'heure.

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

Comparez maintenant, en utilisant des méthodes telles que isEqual , isBeforeet isAfter.

Boolean sameDate = localDate1.isEqual( localDate2 );

Découvrez ce code en direct sur 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 [Amérique / Montréal] | zdt2: 2017-03-24T18: 13: 10.972-04: 00 [Amérique / Montréal]

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

sameDate: false


À propos de java.time

Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date, Calendar, &SimpleDateFormat .

Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers java.time classes .

Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .

Où obtenir les classes java.time?

Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour de futurs ajouts possibles à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval, YearWeek, YearQuarteret plus .

Basil Bourque
la source
7

Apache commons-utils déjà mentionné :

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

vous donne un objet Date contenant uniquement la date, sans heure, et vous pouvez le comparer avec Date.compareTo

Marin danubien
la source
6

J'ai bien peur qu'il n'y ait pas de méthode pour comparer deux dates qui pourraient être appelées "faciles" ou "simples".

Lorsque vous comparez deux instances de temps avec n'importe quelle sorte de précision réduite (par exemple en comparant simplement des dates), vous devez toujours prendre en compte la façon dont le fuseau horaire affecte la comparaison.

Si date1spécifie un événement qui s'est produit dans le fuseau horaire +2 et date2spécifie un événement qui s'est produit dans EST, par exemple, vous devez prendre soin de bien comprendre les implications de la comparaison.

Votre objectif est-il de déterminer si les deux événements se sont produits à la même date dans leurs propres fuseaux horaires respectifs? Ou avez-vous besoin de savoir si les deux dates tombent dans la même date de calendrier dans un fuseau horaire spécifique (UTC ou votre TZ locale, par exemple).

Une fois que vous avez compris ce que vous essayez de comparer, il suffit de placer le triple de l'année et du mois dans un fuseau horaire approprié et de faire la comparaison.

Le temps Joda peut rendre l'opération de comparaison réelle beaucoup plus propre, mais la sémantique de la comparaison est toujours quelque chose que vous devez comprendre vous-même.

Roland Tepp
la source
5

Si vous souhaitez simplement comparer seulement deux dates sans heure, le code suivant peut vous aider:

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
la source
C'est la même chose que la réponse de Rob . Je pense que la solution de Jorn est meilleure car elle n'implique pas un aller-retour aux cordes et devrait accomplir la même chose.
Rup
4

Voici une solution de ce 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.");

c'est-à-dire que vous pouvez voir si le décalage horaire en millisecondes est inférieur à la durée d'un jour.

Wilbert
la source
4
Cet échantillon vérifiera si les deux dates sont à moins de 24 heures l'une de l'autre mais pas nécessairement si elles sont toutes les deux à la même date, c'est-à-dire qu'il est possible de s'étendre sur minuit. Il serait préférable de diviser les deux ensembles de millis à la place par MILLIS_IN_DAY et de comparer le résultat, mais cela ne sera exact que pour UTC et non pour les heures locales.
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
la source
3

Je ne sais pas si c'est nouveau, ou je pense, mais je vous montre ce que j'ai fait

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
la source
3

Vérifiez simplement DAY_OF_YEAR en combinaison avec la propriété YEAR

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

ÉDITER:

Maintenant, nous pouvons utiliser la puissance des fonctions d'extension de 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
    }
}
Simon K. Gerges
la source
C'est faux car les dates avec des années différentes peuvent avoir le même jour de l'année, par exemple 2015-01-01 et 2016-01-01.
nelson eldoro
@nelsoneldoro merci pour votre commentaire, j'ai oublié d'ajouter un chèque pour l'année, maintenant ça devrait aller.
Simon K. Gerges
2

Dans Java 8, vous pouvez utiliser LocalDate qui est très similaire à celui de Joda Time.

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

Cela vous aidera à comparer les dates sans tenir compte de l'heure.

Fathima km
la source
1

En utilisant getDateInstance de SimpleDateFormat, nous ne pouvons comparer que deux objets de date sans heure. Exécutez le code ci-dessous.

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
la source
1

Utilisation de 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
la source
3
Ou tout simplement DateUtils.isSameDay(date1, date2).
OliBlogger
1

Une autre méthode de comparaison simple basée sur les réponses ici et les conseils de mon mentor

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 : Selon @Jonathan Drapeau, le code ci-dessus échoue dans certains cas (j'aimerais voir ces cas, s'il vous plaît) et il a suggéré ce qui suit si je comprends bien:

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

Veuillez noter que la classe Date est obsolète car elle ne se prêtait pas à l'internationalisation. La classe Calendar est utilisée à la place!

Abdelrahman Aly
la source
Cela ne fonctionne pas 100% du temps. A eu un cas d'utilisation où je l'ai fait et le calendar.getTime () retournerait toujours l'heure avec les heures définies comme date de paramètre. Il est préférable d'effacer les champs et de définir uniquement l'année, le mois et le jour.
Jonathan Drapeau
@JonathanDrapeau, il me semble que vous avez peut-être rencontré la conséquence de ne pas avoir choisi de fuseau horaire explicite. Certainement mieux rendre le fuseau horaire explicite que d'utiliser les getXxxméthodes obsolètes de Date.
Ole VV
1

Tout d'abord, sachez que cette opération dépend du fuseau horaire. Choisissez donc si vous voulez le faire en UTC, dans le fuseau horaire de l'ordinateur, dans votre propre fuseau horaire préféré ou où. Si vous n'êtes pas encore convaincu que cela compte, consultez mon exemple au bas de cette réponse.

Étant donné que votre question n'est pas très claire à ce sujet, je suppose que vous avez une classe avec un champ d'instance représentant un point dans le temps et l'implémentation Comparable, et que vous souhaitez que l'ordre naturel de vos objets soit par date, mais pas l'heure , de ce domaine. Par exemple:

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

J'ai pris la liberté de changer le type de votre champ d'instance de Dateà Instant, la classe correspondante en Java 8. Je promets de revenir au traitement de Dateci - dessous. J'ai également ajouté une constante de fuseau horaire. Vous pouvez le définir sur ZoneOffset.UTCou ZoneId.of("Europe/Stockholm")ou sur ce que vous jugez approprié (le définir sur un ZoneOffsetworks parce qu'il ZoneOffsets'agit d'une sous-classe de ZoneId).

J'ai choisi de montrer la solution en utilisant les classes Java 8. Vous avez demandé le moyen le plus simple, non? :-) Voici la compareTométhode que vous avez demandée:

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

Si vous n'avez jamais besoin du temps when, il est bien sûr plus facile de déclarer whenun LocalDateet d'ignorer toutes les conversions. Ensuite, nous n'avons plus à nous soucier du fuseau horaire.

Supposons maintenant que, pour une raison quelconque, vous ne puissiez pas déclarer votre whenchamp Instantou que vous souhaitiez le conserver à l'ancienne Date. Si vous pouvez toujours utiliser Java 8, convertissez-le simplement Instant, puis procédez comme avant:

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

De même pour o.when .

Pas de Java 8?

Si vous ne pouvez pas utiliser java 8, il existe deux options:

  1. Résolvez-le en utilisant l'une des anciennes classes, soit CalendarouSimpleDateFormat .
  2. Utilisez le backport des classes de date et d'heure Java 8 vers Java 6 et 7, puis faites comme ci-dessus. J'inclus un lien en bas. N'utilisez pas JodaTime. JodaTime était probablement une bonne suggestion lorsque les réponses le recommandant ont été écrites; mais JodaTime est maintenant en mode maintenance, donc le backport ThreeTen est une option meilleure et plus évolutive.

Les voies à l'ancienne

La réponse d'Adamski vous montre comment retirer la partie du temps d'une Dateutilisation de la Calendarclasse. Je vous suggère d'utiliser getInstance(TimeZone)pour obtenir l' Calendarinstance pour le fuseau horaire que vous souhaitez. Comme alternative, vous pouvez utiliser l'idée de la seconde moitié de la réponse de Jorn .

L'utilisation SimpleDateFormatest vraiment une manière indirecte d'utiliser Calendarcar a SimpleDateFormatcontient un Calendarobjet. Cependant, vous pouvez trouver cela moins gênant que l'utilisation Calendardirecte:

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

Cela a été inspiré par la réponse de Rob .

Dépendance du fuseau horaire

Pourquoi devons-nous choisir un fuseau horaire spécifique? Disons que nous voulons comparer deux fois le temps en UTC le 24 mars à 0h00 (minuit) et à 12h00 (midi). Si vous le faites en CET (disons Europe / Paris), ils sont 1 h et 13 h le 24 mars, c'est-à-dire à la même date. À New York (heure avancée de l'Est), ils sont 20h00 le 23 mars et 8h00 le 24 mars, c'est-à-dire pas à la même date. Cela fait donc une différence quel fuseau horaire vous choisissez. Si vous vous fiez uniquement à la valeur par défaut de l'ordinateur, vous risquez d'être surpris lorsque quelqu'un essaie d'exécuter votre code sur un ordinateur à un autre endroit dans ce monde globalisé.

Lien

Lien vers ThreeTen Backport, le backport des classes de date et d'heure Java 8 vers Java 6 et 7: http://www.threeten.org/threetenbp/ .

Ole VV
la source
0

Ma proposition:

    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
la source
0

En utilisant Apache commons, vous pouvez faire:

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

DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)
unifier
la source
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   

c'est le moyen le plus simple de résoudre ce problème.

rana_sadam
la source
0

J'ai résolu cela en comparant par horodatage:

    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
    }

J'évite d'utiliser Joda Time car sur Android utilise un immense espace. Questions de taille. ;)

Oscar Josue Alvrez
la source
0

Une autre solution utilisant Java 8 et Instant, utilise la méthode truncatedTo

Renvoie une copie de cet instant tronqué à l'unité spécifiée.

Exemple:

@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
la source
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
la source
Merci! Il y a déjà une poignée d'autres réponses avec la même approche - bien que je vois maintenant que vous comparez directement les objets Calendar alors qu'ils comparent largement les getTime () s.
Rup
-2

C'est ce qui a fonctionné pour moi:

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
la source
2
Votre comparaison "normale" ne compilerait même pas en Java. Si tel était le cas, il comparerait les références des objets, mais cela n'est pas autorisé.
stivlo
J'ai édité pour ajouter Markdown, mais Stivlo a raison. Je ne sais pas comment ce code "a fonctionné pour vous".
Pops
C'est probablement js.
Andrey Luiz
-2

Que diriez-vous DateUtil.daysBetween(). C'est Java et il renvoie un nombre (différence en jours).

Jules
la source