Je dois comparer deux Date
s (par exemple date1
et date2
) et trouver unboolean sameDay
qui est vrai pour les deux Date
s partagent le même jour, et faux s'ils ne le sont pas.
Comment puis-je faire ceci? Il semble y avoir un tourbillon de confusion ici ... et je voudrais éviter de tirer dans d'autres dépendances au-delà du JDK si possible.
pour clarifier: si date1
et date2
partager la même année, le même mois et le même jour, alors sameDay
c'est vrai, sinon c'est faux. Je me rends compte que cela nécessite la connaissance d'un fuseau horaire ... ce serait bien de passer dans un fuseau horaire, mais je peux vivre avec l'heure GMT ou locale tant que je sais quel est le comportement.
encore une fois, pour clarifier:
date1 = 2008 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
=> sameDate = true
date1 = 2009 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
=> sameDate = false
date1 = 2008 Aug 03 12:00:00
date2 = 2008 Jun 03 12:00:00
=> sameDate = false
Réponses:
Notez que «même jour» n'est pas un concept aussi simple qu'il y paraît lorsque différents fuseaux horaires peuvent être impliqués. Le code ci-dessus calculera pour les deux dates le jour par rapport au fuseau horaire utilisé par l'ordinateur sur lequel il s'exécute. Si ce n'est pas ce dont vous avez besoin, vous devez transmettre le (s) fuseau (s) horaire (s) correspondant (s) aux
Calendar.getInstance()
appels, après avoir décidé ce que vous entendez exactement par "le même jour".Et oui, Joda Time
LocalDate
rendrait le tout beaucoup plus propre et plus facile (bien que les mêmes difficultés impliquant les fuseaux horaires soient présentes).la source
Que diriez-vous:
Vous pouvez également définir le fuseau horaire sur SimpleDateFormat, si nécessaire.
la source
SimpleDateFormat
méthode est en fait plus rapide que l'autre mentionnée ici en utilisantCalendar
s. En moyenne, cela prend la moitié du temps commeCalendar
méthode. (Au moins sur mon système). Gloire!J'utilise le package "apache commons lang" pour ce faire (à savoir org.apache.commons.lang.time.DateUtils )
la source
Vous pouvez éviter les dépendances externes et l'impact sur les performances de l'utilisation de Calendar en calculant le numéro du jour julien pour chacune des dates, puis en les comparant:
la source
Date
s droites n'encapsulent pas la notion de fuseaux horaires, il n'y a donc aucun moyen de résoudre ce problème de manière non arbitraire.Joda-Time
Quant à l'ajout d'une dépendance, je crains que les java.util.Date et .Calendar soient vraiment si mauvais que la première chose que je fais à tout nouveau projet est d'ajouter la bibliothèque Joda-Time. Dans Java 8, vous pouvez utiliser le nouveau package java.time, inspiré de Joda-Time.
Le cœur de Joda-Time est la
DateTime
classe. Contrairement à java.util.Date, il comprend le fuseau horaire qui lui est attribué (DateTimeZone
). Lors de la conversion de juDate, attribuez une zone.LocalDate
Une façon de vérifier si deux dates-heures atterrissent à la même date est de les convertir en
LocalDate
objets.Cette conversion dépend du fuseau horaire attribué. Pour comparer des
LocalDate
objets, ils doivent avoir été convertis avec la même zone.Voici une petite méthode utilitaire.
Mieux serait un autre argument, spécifiant le fuseau horaire plutôt que de supposer que le fuseau horaire du premier objet DateTime devrait être utilisé.
Représentation des chaînes
Une autre approche consiste à créer une représentation sous forme de chaîne de la partie date de chaque date-heure, puis à comparer les chaînes.
Encore une fois, le fuseau horaire attribué est crucial.
Durée du temps
La solution généralisée consiste à définir un intervalle de temps, puis demandez si l'intervalle contient votre cible. Cet exemple de code est dans Joda-Time 2.4. Notez que les classes liées à "minuit" sont obsolètes. Utilisez plutôt la
withTimeAtStartOfDay
méthode. Joda-Time propose trois classes pour représenter un laps de temps de différentes manières: Intervalle, Période et Durée.Utilisation de l'approche "Half-Open" où le début de la plage est inclusif et la fin exclusive.
Le fuseau horaire de la cible peut être différent du fuseau horaire de l'intervalle.
java.time
Java 8 et versions ultérieures sont fournies avec le framework java.time . Inspiré par Joda-Time, défini par JSR 310, et étendu par le projet ThreeTen-Extra. Voir le tutoriel .
Les créateurs de Joda-Time nous ont tous demandé de passer à java.time dès que possible. Dans l'intervalle, Joda-Time continue d'être un projet activement maintenu. Mais attendez-vous à ce que les travaux futurs se produisent uniquement dans java.time et ThreeTen-Extra plutôt que Joda-Time.
Pour résumer java.time en quelques mots… An
Instant
est un moment sur la timeline en UTC. Appliquez un fuseau horaire (ZoneId
) pour obtenir unZonedDateTime
objet. Pour se déplacer hors de la ligne de temps, pour obtenir l'idée vague indéfinie d'une date-heure, utiliser les classes « locales »:LocalDateTime
,LocalDate
,LocalTime
.La logique discutée dans la section Joda-Time de cette réponse s'applique à java.time.
L'ancienne classe java.util.Date a une nouvelle
toInstant
méthode de conversion en java.time.La détermination d'une date nécessite un fuseau horaire.
Nous appliquons cet objet de fuseau horaire au
Instant
pour obtenir unZonedDateTime
. De là, nous extrayons une valeur de date uniquement (aLocalDate
) car notre objectif est de comparer les dates (pas les heures, les minutes, etc.).Faites de même pour le deuxième
java.util.Date
objet dont nous avons besoin pour la comparaison. Je vais juste utiliser l'instant présent à la place.Utilisez la
isEqual
méthode spéciale pour tester la même valeur de date.la source
LocalDate localDate = LocalDate.fromDateFields(yourJavaUtilDate);
fromDateFields()
en a pas dans maLocalDate
classe .Convertissez les dates en Java 8 java.time.LocalDate comme on le voit ici .
la source
ZoneId.of("America/Phoenix")
ou à laZoneId.of("Europe/Budapest")
place du système par défaut.Java 8
Si vous utilisez Java 8 dans votre projet et comparez
java.sql.Timestamp
, vous pouvez utiliser laLocalDate
classe:Si vous utilisez
java.util.Date
, jetez un œil à la réponse d'Istvan qui est moins ambiguë.la source
date1
etdate2
êtes-vousjava.sql.Timestamp
? Selon la question qu'ils sontDate
, je comprendraisjava.util.Date
. De plus, votre code utilise le paramètre de fuseau horaire de l'ordinateur, qui à de nombreuses fins conviendra; je préférerais quand même rendre ce fait explicite dans le code.java.sql.Timestamp
. Comme vous l'avez dit, il est généralement préférable de définir explicitement le fuseau horaire.la source
POUR LES UTILISATEURS ANDROID:
Vous pouvez utiliser
DateUtils.isToday(dateMilliseconds)
pour vérifier si la date donnée est la journée en cours ou non.Référence de l'API: https://developer.android.com/reference/android/text/format/DateUtils.html#isToday(long)
la source
DateUtils.isToday(x.getTime())
(x est une instance de java.util.date) fera l'affaireen plus de la solution Binil Thomas
usage
la source
Pour les développeurs Kotlin, c'est la version avec la comparaison de l'approche des chaînes formatées:
Ce n'est pas la meilleure façon, mais c'est court et ça marche.
la source
SimpleDateFormat
classe a été supplantée il y a des années par lajava.time.DateTimeFormatter
classe moderne définie dans la JSR 310. Suggérer son utilisation en 2019 est un mauvais conseil.vous pouvez appliquer la même logique que la solution SimpleDateFormat sans compter sur SimpleDateFormat
la source