API Date
Introduction aux dates et heures
Maintenant que nous avons introduit les aéroports et leurs fuseaux horaires, il est temps de nous concentrer sur un
aspect crucial des voyages : les dates et les heures. Nous allons utiliser l'API java.time
pour cela.
API java.time
L'API java.time
comporte 5 implémentations importantes :
LocalDate
: Représente une date sans heure ni fuseau horaire (par exemple, 2023-12-15).LocalTime
: Représente une heure sans date ni fuseau horaire (par exemple, 10:15:30).LocalDateTime
: Combine LocalDate et LocalTime, représentant une date et une heure sans fuseau horaire.ZonedDateTime
: Comme LocalDateTime, mais avec la prise en charge des fuseaux horaires.Instant
: Représente un moment précis sur la timeline UTC.Period
,Duration
: Représente des intervalles dans le temps.
Exemples d'utilisation :
LocalTime uneHeure = LocalTime.of(14, 30); // 14h30
LocalDateTime dateEtHeure = LocalDateTime.of(2023, Month.JULY, 15, 14, 30); // 15 juillet 2023, 14h30
ZonedDateTime dateHeureZone = ZonedDateTime.of(2023, 7, 15, 14, 30, 0, 0, ZoneId.of("Europe/Paris")); // 15 juillet 2023, 14h30, heure de Paris
Instant instant = Instant.now(); // Capture le moment courant en UTC
Period period = Period.between(dateEtHeure.toLocalDate(), dateHeureZone.toLocalDate());
Duration duration = Duration.between(instant, instant);
Period
vs Duration
Period
: utilise les unités année, mois et jour pour représenter une période de temps (prend des LocalDate
en paramètre).
Duration
: représente un intervalle de temps en secondes ou en nanosecondes et convient mieux pour traiter les
cas qui requièrent plus de précision (prend des Instant
en paramètre).
Intégration des dates du voyage
À vous de jouer
- Ajoutez un attribut
departure
etarrival
dans la classeTravel
pour gérer les dates de départ et d'arrivée ainsi que les heures. Vous utiliserez unInstant
. - Ajoutez dans le constructeur une levée d'exception si la date de départ est postérieure à la date d'arrivée. Vous pourrez utiliser une
IllegalArgumentException
avec un message indiquant que la date de départ est après la date d'arrivée.
Pourquoi un Instant
plutôt qu'un ZonedDateTime
?
On privilégie l'utilisation d'Instant
plutôt que ZonedDateTime car les dates/heures dépendent des fuseaux horaires, qui varient selon les régions du monde.
Ainsi, il est plus judicieux de convertir l'Instant
en date/heure dans le frontend, permettant d'afficher la
date et l'heure selon le fuseau horaire de chaque utilisateur. (Dans notre cas, nous ferons la conversion dans notre
vue, au niveau du DTO).
DTO de sortie
Les DTO (Data Transfer Object) représentent notre modèle tel qu'il est exposé à l'extérieur. Ils permettent de contrôler les objets entrants et sortants de notre application, on parle donc de request DTO
et de response DTO
. Par souci de simplicité, on se focalisera uniquement sur les DTO de sortie dans notre application.
Les DTO de sortie représentent ce qui est exposé à l'extérieur (par exemple au frontend). On n'envoie pas directement le modèle, car il pourrait contenir des informations sensibles ou inutiles. Dans une application web complète, on ajouterait des controllers à nos DTO pour qu'ils puissent être transmis à notre frontend via le protocole HTTP.
En fait, jusqu'à présent, nous vous avions demandé de créer des classes, mais depuis Java 17, il est possible de concevoir des classes immuables avec moins de code boilerplate avec les records.
Record
Avec les records, il n'est plus nécessaire de créer les méthodes equals(), hashCode() et toString(), ainsi que les constructeurs et les accesseurs.
C'est l'occasion d'utiliser les records pour nos DTO.
Création du DTO de sortie Travel
À vous de jouer
- Créez un fichier
TravelResponseDto
qui correspondra à une représentation du modèleTravel
contenant seulement les informations à exposer (pour les dates en renverra desZonedDateTime
).
Création d'un mapper pour convertir les modèles en DTO
Maintenant que nous avons nos DTO, il faut pouvoir convertir nos classes dans leur DTO correspondants. Nous allons créer des méthodes permettant de faire cela.
Une première stratégie serait de créer des classes avec des méthodes de mapping public et static à l'intérieur.
Exemple
À vous de jouer
- Créez une classe
TravelDtoMapper
avec une méthodefromTravel
pour convertir le modèleTravel
dans son DTO de sortie.- La méthode
fromTravel
devra gérer la conversion d'Instant en date / heure exprimée dans le fuseau hoaire de l'aéroport de départ et d'arrivée. Utilisez l'AirportManager
créé dans la partie précédente pour lier l'aéroport à son fuseau horaire.
- La méthode
Optionnel
Calcul de durée et gestion des retards
À vous de jouer
Faites les modifications suivantes dans la classe TravelService
:
-
Créez une méthode
computeTravelDuration
qui calcule la durée totale du voyage ( méthode de la librairieDuration
). -
Créez une méthode qui permet de modifier les dates des vols en cas de retard. La méthode prendra en paramètre un objet
Travel
et undelay
qui correspondra à une durée de retard, par exemple 2 heures, 2 jours ou encore 1 semaine ( méthode de la librairieInstant
).
Essayez votre code dans le Main
À vous de jouer
Faites les modification suivantes dans le Main
:
Jérôme s'inscrit à un voyage entre Paris et Tokyo du 26/04/2023, l'avion décolle à 12h10 et arrive le 27/04/2023 à 06h36.
- Vérifiez que la méthode
computeTravelDuration
retourne bien 11 heures et 26 minutes. - Ajoutez un retard de 5h à la date de départ et assurez-vous que cela fonctionne en affichant la date de départ dans le bon fuseau horaire.
Date formatter
// Création de l'objet LocalDateTime pour la date et l'heure spécifiées
LocalDateTime dateTime = LocalDateTime.of(2024, Month.DECEMBER, 21, 12, 30);
// Conversion en Instant
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
// Convertir Instant en LocalDateTime
LocalDateTime newLocalDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
Récapitulatif
Félicitations ! Vous avez maintenant intégré la gestion des dates et des heures dans votre application. Vous êtes dorénavant prêt à gérer des voyages dans différents fuseaux horaires et à effectuer des opérations complexes sur les dates.
Check
N'oubliez pas de commit
votre travail !