1. Addition et soustraction de dates et d’heures
En programmation, travailler avec les dates et les heures — ce n’est pas seulement « afficher joliment la date à l’écran ». Très souvent, il faut :
- savoir combien de jours il reste avant un événement important ;
- calculer l’âge d’un utilisateur ;
- déterminer combien de temps s’est écoulé entre deux événements ;
- vérifier si la date limite n’est pas déjà arrivée ;
- ajouter à une date un certain nombre de jours, de semaines, de mois ou d’heures.
Par exemple, dans notre application, nous voulons rappeler à l’utilisateur qu’il reste 3 jours avant la date limite d’une tâche. Ou le féliciter pour son anniversaire passé (si la date est déjà passée).
Pour cela, le package java.time propose des classes et méthodes dédiées qui rendent ces calculs simples et sûrs.
Méthodes de base pour additionner et soustraire
Tous les types de date et d’heure (LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant) proposent des méthodes :
- plusXxx() — ajouter (jours, mois, années, heures, minutes, etc.)
- minusXxx() — soustraire (idem)
import java.time.LocalDate;
LocalDate today = LocalDate.now(); // Date d’aujourd’hui
LocalDate tomorrow = today.plusDays(1); // Demain
LocalDate nextMonth = today.plusMonths(1); // Dans un mois
LocalDate lastWeek = today.minusWeeks(1); // Il y a une semaine
System.out.println("Aujourd’hui: " + today);
System.out.println("Demain: " + tomorrow);
System.out.println("Dans un mois: " + nextMonth);
System.out.println("Il y a une semaine: " + lastWeek);
Toutes ces méthodes renvoient un nouvel objet et ne modifient pas l’original. L’immuabilité, c’est la clé !
import java.time.LocalTime;
LocalTime now = LocalTime.now();
LocalTime inTwoHours = now.plusHours(2);
LocalTime tenMinutesAgo = now.minusMinutes(10);
System.out.println("Maintenant: " + now);
System.out.println("Dans 2 heures: " + inTwoHours);
System.out.println("Il y a 10 minutes: " + tenMinutesAgo);
Méthodes chaînées
LocalDate vacation = today.plusMonths(2).plusDays(10);
System.out.println("Vacances: " + vacation);
2. Obtenir une différence entre dates: Period et Duration
Quand vous devez savoir combien de temps s’est écoulé entre deux dates ou deux instants, deux héros entrent en scène — Period et Duration. Faisons leur connaissance.
Quelle est la différence entre Period et Duration ?
- Period — pour travailler avec des dates (année, mois, jour). Par exemple, « 3 ans, 2 mois et 5 jours ».
- Duration — pour travailler avec le temps (heures, minutes, secondes, nanosecondes). Par exemple, « 5 heures 30 minutes ».
| Classe | À quoi sert | Exemple d’utilisation |
|---|---|---|
|
Différence entre des dates | Combien d’années/mois/jours entre des dates |
|
Différence entre des instants | Combien d’heures/minutes/secondes entre des événements |
Exemple : calcul de l’âge d’un utilisateur
import java.time.LocalDate;
import java.time.Period;
LocalDate birthday = LocalDate.of(2000, 1, 15); // Date de naissance
LocalDate today = LocalDate.now();
Period age = Period.between(birthday, today);
System.out.println("Âge: " + age.getYears() + " ans, " +
age.getMonths() + " mois, " +
age.getDays() + " jours");
Analogie : Period, c’est une différence « humaine » entre des dates (« j’ai 24 ans 5 mois 12 jours »).
Exemple : combien de temps reste-t-il avant la date limite
import java.time.LocalDate;
LocalDate deadline = LocalDate.of(2025, 7, 1);
LocalDate today = LocalDate.now();
if (today.isBefore(deadline)) {
Period left = Period.between(today, deadline);
System.out.println("Il reste avant la date limite: " +
left.getMonths() + " mois et " +
left.getDays() + " jours");
} else {
System.out.println("La date limite est déjà passée !");
}
Duration : différence dans le temps
import java.time.LocalDateTime;
import java.time.Duration;
LocalDateTime start = LocalDateTime.of(2025, 6, 1, 10, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 6, 1, 15, 30, 0);
Duration duration = Duration.between(start, end);
System.out.println("Durée: " + duration.toHours() + " heures " +
(duration.toMinutes() % 60) + " minutes");
Duration mesure des différences en secondes, minutes, heures, jours (mais les jours valent toujours 24 heures, sans tenir compte des particularités du calendrier).
Comparaison : quand utiliser Period et quand utiliser Duration ?
- Si vous n’avez que des dates (sans heure) — utilisez Period.
- Si vous avez une heure (par exemple, LocalDateTime, Instant) — utilisez Duration.
3. Comparer des dates et des heures : isBefore, isAfter, equals
Parfois, il faut simplement savoir : la date est-elle déjà arrivée ou pas encore ? L’événement est-il dans le passé ou dans le futur ? Pour cela, tous les types de date et d’heure proposent :
- isBefore(autreDate)
- isAfter(autreDate)
- isEqual(autreDate) (ou simplement equals)
import java.time.LocalDate;
LocalDate today = LocalDate.now();
LocalDate deadline = LocalDate.of(2025, 7, 1);
if (today.isBefore(deadline)) {
System.out.println("Il reste encore du temps !");
} else if (today.isEqual(deadline)) {
System.out.println("C’est la date limite aujourd’hui !");
} else {
System.out.println("La date limite est déjà passée :(");
}
import java.time.LocalTime;
LocalTime now = LocalTime.now();
LocalTime lunch = LocalTime.of(13, 0);
if (now.isAfter(lunch)) {
System.out.println("Le déjeuner est déjà passé !");
} else {
System.out.println("Il reste encore du temps avant le déjeuner.");
}
Important : on ne peut comparer que des objets du même type (LocalDate avec LocalDate, LocalDateTime avec LocalDateTime, etc.).
4. Pratique : exercices sur le calcul des différences et le contrôle des délais
Exemple : combien de jours restent avant la date limite d’une tâche
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
LocalDate today = LocalDate.now();
LocalDate deadline = LocalDate.of(2025, 7, 1);
long daysLeft = ChronoUnit.DAYS.between(today, deadline);
if (daysLeft > 0) {
System.out.println("Il reste " + daysLeft + " jours avant la date limite");
} else if (daysLeft == 0) {
System.out.println("C’est la date limite aujourd’hui !");
} else {
System.out.println("La date limite est passée il y a " + Math.abs(daysLeft) + " jours");
}
ChronoUnit.DAYS.between() est un moyen pratique d’obtenir le nombre exact de jours entre deux dates (sans tenir compte des mois et des années).
Exemple : combien de secondes entre deux événements
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
LocalDateTime start = LocalDateTime.of(2025, 6, 1, 10, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 6, 1, 15, 30, 0);
long seconds = ChronoUnit.SECONDS.between(start, end);
System.out.println("Il s’est écoulé " + seconds + " secondes entre les événements");
Exemple : âge d’une tâche
import java.time.LocalDate;
import java.time.Period;
LocalDate created = LocalDate.of(2025, 5, 20);
LocalDate today = LocalDate.now();
Period period = Period.between(created, today);
System.out.println("La tâche a été créée il y a " +
period.getDays() + " jours, " +
period.getMonths() + " mois et " +
period.getYears() + " ans.");
Exemple : durée entre deux Instant
import java.time.Instant;
import java.time.Duration;
Instant start = Instant.now();
// ... faire quelque chose ...
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("L’exécution a pris " + duration.toMillis() + " millisecondes");
5. Particularités d’utilisation de Period et Duration
Particularités de Period
- Period calcule la différence selon le calendrier : entre le 28 février et le 1er mars — 1 jour, même si ce sont des mois différents.
- On peut obtenir séparément le nombre d’années, de mois, de jours : getYears(), getMonths(), getDays().
- Si vous avez besoin du nombre total de jours entre des dates — utilisez ChronoUnit.DAYS.between().
Particularités de Duration
- Duration travaille avec le temps exact (heures, minutes, secondes).
- Peut fonctionner avec LocalTime, LocalDateTime, Instant.
- À ne pas utiliser avec des dates sans heure (LocalDate) — cela lèvera une exception.
Exemple : différence entre Period et Duration
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Duration;
import java.time.Period;
LocalDate date1 = LocalDate.of(2025, 2, 28);
LocalDate date2 = LocalDate.of(2025, 3, 1);
Period period = Period.between(date1, date2); // 2 jours (année bissextile)
long days = java.time.temporal.ChronoUnit.DAYS.between(date1, date2); // 2 jours
System.out.println("Period: " + period.getDays() + " jours");
System.out.println("ChronoUnit: " + days + " jours");
LocalDateTime dt1 = LocalDateTime.of(2025, 6, 1, 23, 0);
LocalDateTime dt2 = LocalDateTime.of(2025, 6, 2, 1, 0);
Duration duration = Duration.between(dt1, dt2); // 2 heures
System.out.println("Duration: " + duration.toHours() + " heures");
6. Utiliser Duration et Period pour présenter une différence de manière lisible
Quand vous calculez une différence entre des dates ou des heures pour un utilisateur, il n’est pas toujours utile d’afficher « 123456 secondes ». On préfère généralement quelque chose comme « 2 jours 3 heures 15 minutes ».
Exemple : affichage d’une différence entre dates et heures
import java.time.LocalDateTime;
import java.time.Duration;
LocalDateTime start = LocalDateTime.of(2025, 6, 1, 14, 0);
LocalDateTime end = LocalDateTime.of(2025, 6, 3, 16, 30);
Duration duration = Duration.between(start, end);
long days = duration.toDays();
long hours = duration.minusDays(days).toHours();
long minutes = duration.minusDays(days).minusHours(hours).toMinutes();
System.out.println("Différence: " + days + " jours " +
hours + " heures " + minutes + " minutes");
7. Particularités avec ZonedDateTime et Instant
- La différence entre deux ZonedDateTime dans des zones différentes est calculée en temps absolu, et non selon le « temps humain » de chaque zone.
- Le passage à l’heure d’été/d’hiver peut influencer la différence en heures entre des dates.
Exemple : différence entre deux ZonedDateTime
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.Duration;
ZonedDateTime MinskTime = ZonedDateTime.of(2025, 6, 1, 12, 0, 0, 0, ZoneId.of("Europe/Minsk"));
ZonedDateTime nyTime = ZonedDateTime.of(2025, 6, 1, 5, 0, 0, 0, ZoneId.of("America/New_York"));
Duration diff = Duration.between(nyTime, MinskTime);
System.out.println("Différence: " + diff.toHours() + " heures");
8. Erreurs typiques lors des calculs avec dates et heures
Erreur n° 1 : Confusion entre Period et Duration.
Si vous tentez d’utiliser Duration avec un LocalDate, vous obtiendrez une exception. Pour les dates, utilisez Period ; pour le temps — Duration.
Erreur n° 2 : Ne pas tenir compte des fuseaux horaires.
Si vous comparez des dates et des heures dans des fuseaux différents, vous pouvez obtenir des résultats inattendus. Mieux vaut tout ramener à un même fuseau ou utiliser Instant.
Erreur n° 3 : S’attendre à ce que les méthodes plus/minus modifient l’objet.
Tous les objets java.time sont immuables ! N’oubliez pas d’affecter le résultat à une nouvelle variable (par exemple, today = today.plusDays(1)).
Erreur n° 4 : Utiliser getDays() de Period en pensant que c’est le nombre total de jours.
En réalité, ce ne sont que les jours restants après soustraction des années et des mois. Pour le total des jours, utilisez ChronoUnit.DAYS.between().
Erreur n° 5 : Comparer des objets de types différents.
Les méthodes isBefore, isAfter, isEqual ne fonctionnent qu’avec des objets du même type (par exemple, LocalDate avec LocalDate).
GO TO FULL VERSION