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.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeQuébec = new DateTime( date , 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.
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;
}
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é.
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
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.
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 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.
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 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 un ZonedDateTime
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.
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 de fuseau horaire au Instant
pour obtenir un ZonedDateTime
. De là, nous extrayons une valeur de date uniquement (a LocalDate
) car notre objectif est de comparer les dates (pas les heures, les minutes, etc.).
ZonedDateTime zdt1 = ZonedDateTime.ofInstant( instant , zoneId );
LocalDate localDate1 = LocalDate.from( zdt1 );
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.
ZonedDateTime zdt2 = ZonedDateTime.now( zoneId );
LocalDate localDate2 = LocalDate.from( zdt2 );
Utilisez la isEqual
méthode spéciale pour tester la même valeur de date.
Boolean sameDate = localDate1.isEqual( localDate2 );