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?
Mise à jour: alors que Joda Time était une bonne recommandation à l'époque, utilisez java.time
plutô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.Date
ou 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 Calendar
avec 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.Date
est 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 Calendar
Joda 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
Apache commons-lang est presque omniprésent. Et alors?
la source
Si vous voulez vraiment utiliser le java.util.Date, vous feriez quelque chose comme ceci:
ou, en utilisant un calendrier à la place (préféré, car getYear () et autres sont obsolètes)
la source
Ma préférence serait d'utiliser directement la bibliothèque de Joda
java.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.Date
je vous suggère d'écrire une méthode utilitaire; par exemplela source
Des opinions sur cette alternative?
la source
==
opérateur ne retourne pas nécessairementtrue
pour des chaînes équivalentes (utilisationequals()
). Vous ne pouvez certainement pas non plus utiliser les autres opérateurs de comparaison que vous avez mentionnés.sdf.format(date1).compareTo(sdf.format(date2));
.Si vous souhaitez comparer uniquement le mois, le jour et l'année de deux dates, le code suivant fonctionne pour moi:
Merci Rob.
la source
Moi aussi, je préfère Joda Time , mais voici une alternative:
É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.
la source
Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
< oneDay
.tl; dr
É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.Date
représente un moment sur la timeline en UTC. L'équivalent dans java.time estInstant
. Vous pouvez convertir en utilisant de nouvelles méthodes ajoutées à la classe héritée.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 queAmerica/Montreal
,Africa/Casablanca
ouPacific/Auckland
. N'utilisez jamais l'abréviation de 3 à 4 lettres telle queEST
ouIST
car ce ne sont pas de véritables fuseaux horaires, ni standardisés, ni même uniques (!).Appliquez le
ZoneId
àInstant
pour obtenir unZonedDateTime
.le
LocalDate
classe représente une valeur de date uniquement sans heure et sans fuseau horaire. Nous pouvons extraire unLocalDate
de aZonedDateTime
, éliminant efficacement la partie de l'heure.Comparez maintenant, en utilisant des méthodes telles que
isEqual
,isBefore
etisAfter
.Découvrez ce code en direct sur IdeOne.com .
À 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
,YearQuarter
et plus .la source
Apache commons-utils déjà mentionné :
vous donne un objet Date contenant uniquement la date, sans heure, et vous pouvez le comparer avec
Date.compareTo
la source
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
date1
spécifie un événement qui s'est produit dans le fuseau horaire +2 etdate2
spé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.
la source
Si vous utilisez Java 8, vous devez utiliser les
java.time.*
classes pour comparer les dates - il est préférable aux diversjava.util.*
classespar exemple; https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
la source
Si vous souhaitez simplement comparer seulement deux dates sans heure, le code suivant peut vous aider:
la source
Voici une solution de ce blog: http://brigitzblog.blogspot.com/2011/10/java-compare-dates.html
c'est-à-dire que vous pouvez voir si le décalage horaire en millisecondes est inférieur à la durée d'un jour.
la source
"
"
la source
Je ne sais pas si c'est nouveau, ou je pense, mais je vous montre ce que j'ai fait
la source
Vérifiez simplement DAY_OF_YEAR en combinaison avec la propriété YEAR
ÉDITER:
Maintenant, nous pouvons utiliser la puissance des fonctions d'extension de Kotlin
la source
Dans Java 8, vous pouvez utiliser LocalDate qui est très similaire à celui de Joda Time.
la source
Cela vous aidera à comparer les dates sans tenir compte de l'heure.
la source
En utilisant getDateInstance de SimpleDateFormat, nous ne pouvons comparer que deux objets de date sans heure. Exécutez le code ci-dessous.
la source
Utilisation de http://mvnrepository.com/artifact/commons-lang/commons-lang
la source
DateUtils.isSameDay(date1, date2)
.Une autre méthode de comparaison simple basée sur les réponses ici et les conseils de mon mentor
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:
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!
la source
getXxx
méthodes obsolètes deDate
.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:java.time
Cours Java 8J'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 deDate
ci - dessous. J'ai également ajouté une constante de fuseau horaire. Vous pouvez le définir surZoneOffset.UTC
ouZoneId.of("Europe/Stockholm")
ou sur ce que vous jugez approprié (le définir sur unZoneOffset
works parce qu'ilZoneOffset
s'agit d'une sous-classe deZoneId
).J'ai choisi de montrer la solution en utilisant les classes Java 8. Vous avez demandé le moyen le plus simple, non? :-) Voici la
compareTo
méthode que vous avez demandée:Si vous n'avez jamais besoin du temps
when
, il est bien sûr plus facile de déclarerwhen
unLocalDate
et 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
when
champInstant
ou que vous souhaitiez le conserver à l'ancienneDate
. Si vous pouvez toujours utiliser Java 8, convertissez-le simplementInstant
, puis procédez comme avant:De même pour
o.when
.Pas de Java 8?
Si vous ne pouvez pas utiliser java 8, il existe deux options:
Calendar
ouSimpleDateFormat
.Les voies à l'ancienne
La réponse d'Adamski vous montre comment retirer la partie du temps d'une
Date
utilisation de laCalendar
classe. Je vous suggère d'utilisergetInstance(TimeZone)
pour obtenir l'Calendar
instance 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
SimpleDateFormat
est vraiment une manière indirecte d'utiliserCalendar
car aSimpleDateFormat
contient unCalendar
objet. Cependant, vous pouvez trouver cela moins gênant que l'utilisationCalendar
directe: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/ .
la source
Ma proposition:
la source
En utilisant Apache commons, vous pouvez faire:
la source
c'est le moyen le plus simple de résoudre ce problème.
la source
J'ai résolu cela en comparant par horodatage:
J'évite d'utiliser Joda Time car sur Android utilise un immense espace. Questions de taille. ;)
la source
Une autre solution utilisant Java 8 et Instant, utilise la méthode truncatedTo
Exemple:
la source
la source
C'est ce qui a fonctionné pour moi:
la source
Que diriez-vous
DateUtil.daysBetween()
. C'est Java et il renvoie un nombre (différence en jours).la source