Joda-Time
Pour ce qui est de l'ajout d'une dépendance, j'ai bien peur que les java.util.Date & .Calendar soient tellement mauvais que la première chose que je fais à tout nouveau projet est d'ajouter la bibliothèque Joda-Time. En Java 8, vous pouvez utiliser le nouveau paquet java.time, inspiré de Joda-Time.
Le noyau de Joda-Time est le DateTime
classe. Contrairement à java.util.Date, elle comprend le fuseau horaire qui lui est attribué ( DateTimeZone
). Lors de la conversion de j.u.date, attribuez une zone.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeQuébec = new DateTime( date , zone );
LocalDate
Une façon de vérifier si deux dates-horaires tombent sur la même date est de convertir en LocalDate
objets.
Cette conversion dépend du fuseau horaire attribué. Pour comparer LocalDate
les objets, ils doivent avoir été convertis avec la même zone.
Voici une petite méthode utilitaire.
static public Boolean sameDate ( DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1 );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( dt1.getZone() ) );
Boolean match = ld1.equals( ld2 );
return match;
}
Il serait préférable d'utiliser un autre argument, spécifiant le fuseau horaire plutôt que de supposer que le premier fuseau horaire de l'objet DateTime doit être utilisé.
static public Boolean sameDate ( DateTimeZone zone , DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1.withZone( zone ) );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( zone ) );
return ld1.equals( ld2 );
}
Représentation des chaînes de caractères
Une autre approche consiste à créer une représentation en chaîne de la partie date de chaque date-heure, puis à comparer les chaînes.
Là encore, le fuseau horaire attribué est crucial.
DateTimeFormatter formatter = ISODateTimeFormat.date(); // Static method.
String s1 = formatter.print( dateTime1 );
String s2 = formatter.print( dateTime2.withZone( dt1.getZone() ) );
Boolean match = s1.equals( s2 );
return match;
Durée de vie
La solution généralisée consiste à définir un intervalle de temps, puis à demander si cet intervalle contient votre cible. Cet exemple de code est en Joda-Time 2.4. Notez que les classes liées à "midnight" sont dépréciées. Utilisez plutôt les classes withTimeAtStartOfDay
méthode. Joda-Time propose trois classes pour représenter un intervalle de temps de différentes manières : Intervalle, Période, et Durée.
Utilisation de l'approche "semi-ouverte" où le début de la portée est inclusif et la fin exclusive.
Le fuseau horaire de la cible peut être différent de celui de l'intervalle.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime target = new DateTime( 2012, 3, 4, 5, 6, 7, timeZone );
DateTime start = DateTime.now( timeZone ).withTimeAtStartOfDay();
DateTime stop = start.plusDays( 1 ).withTimeAtStartOfDay();
Interval interval = new Interval( start, stop );
boolean containsTarget = interval.contains( target );
java.time
Java 8 et les versions ultérieures sont livrés avec le java.time cadre. Inspiré par Joda-Time, défini par la JSR 310, et étendu par le projet ThreeTen-Extra. Voir Tutoriel .
Les créateurs de Joda-Time nous ont demandé de passer à java.time dès que possible. En attendant, Joda-Time reste un projet activement maintenu. Mais attendez-vous à ce que les travaux futurs se déroulent uniquement dans java.time et ThreeTen-Extra plutôt que dans Joda-Time.
Pour résumer java.time en quelques mots An Instant
est un moment sur la ligne de temps en UTC. Appliquez un fuseau horaire ( ZoneId
) pour obtenir un ZonedDateTime
objet. Pour sortir de la ligne du temps, pour avoir la vague idée indéfinie d'une date-heure, utilisez les classes "locales" : LocalDateTime
, LocalDate
, LocalTime
.
La logique abordée dans la section Joda-Time de cette réponse s'applique à java.time.
L'ancienne classe java.util.Date dispose d'une nouvelle classe toInstant
pour la conversion en java.time.
Instant instant = yourJavaUtilDate.toInstant(); // Convert into java.time type.
La détermination d'une date nécessite un fuseau horaire.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
Nous appliquons cet objet fuseau horaire à l'objet Instant
pour obtenir un ZonedDateTime
. Nous en extrayons une valeur de date uniquement (a LocalDate
) car notre objectif est de comparer des dates (et non des heures, des minutes, etc.).
ZonedDateTime zdt1 = ZonedDateTime.ofInstant( instant , zoneId );
LocalDate localDate1 = LocalDate.from( zdt1 );
Faites de même avec le deuxième java.util.Date
l'objet dont nous avons besoin pour la comparaison. Je vais utiliser le moment présent à la place.
ZonedDateTime zdt2 = ZonedDateTime.now( zoneId );
LocalDate localDate2 = LocalDate.from( zdt2 );
Utilisez la fonction spéciale isEqual
pour tester la même valeur de date.
Boolean sameDate = localDate1.isEqual( localDate2 );
0 votes
Pour clarifier : vous voulez savoir si deux objets Date tombent le même jour de la semaine ?
0 votes
Voulez-vous comparer la date complète (jour, mois, année) ou seulement le jour du mois ?
1 votes
@Rob : non, le même jour/mois/année... Je vais préciser.
0 votes
Alors pourquoi n'utilisez-vous pas "égal" ?
8 votes
Parce qu'ils ne sont pas égaux si l'heure, la minute et la seconde sont différentes.
0 votes
Vous dites que vous voulez "sameDay" mais dans vos détails vous indiquez "sameDate" ?
0 votes
Duplicata possible de Comment comparer deux dates sans la partie temps ?
0 votes
@OleV.V. Je suis d'accord mais dans cette question, je ne voulais pas faire appel à des dépendances de bibliothèques et la réponse à cette question utilise Joda time.
0 votes
@JasonS, je voulais juste fournir le lien pour information. Vous avez certainement un point en évitant une dépendance à une bibliothèque tierce, et même si vous en acceptez une, ils disent que JodaTime n'est pas la meilleure option en 2017. Cette autre question a 25 réponses. La réponse acceptée et quelques autres utilisent JodaTime, la plupart ne le font pas.