Travail avancé avec les dates et l'heure en Java : de LocalDate aux manipulations complexes
Dans le Java moderne (à partir de la version 8), le standard de facto pour travailler avec les dates et l'heure est le package java.time. Il a remplacé les obsolètes java.util.Date et java.util.Calendar, offrant des objets immuables, la sécurité des threads et une API intuitive. Dans cet article, nous aborderons des techniques avancées : le travail avec les fuseaux horaires, les calculs précis de différences, les ajusteurs personnalisés et le formatage complexe.
1. Manipulations de dates avec TemporalAdjusters
L'une des fonctionnalités les plus puissantes de java.time est l'interface TemporalAdjuster. Elle permet d'effectuer des ajustements complexes de dates — par exemple, trouver le « mardi suivant » ou le « dernier jour du mois ».
La classe TemporalAdjusters (notez le pluriel) contient des méthodes statiques prêtes à l'emploi :
firstDayOfMonth()— premier jour du mois ;lastDayOfMonth()— dernier jour du mois ;next(DayOfWeek.FRIDAY)— le jour de la semaine suivant spécifié ;previousOrSame(DayOfWeek.MONDAY)— le lundi précédent ou actuel.
Exemple : trouvons la date du mercredi suivant après le 15 mars 2024.
import java.time.LocalDate;import java.time.DayOfWeek;import java.time.temporal.TemporalAdjusters;
public class TemporalExample { public static void main(String[] args) { LocalDate date = LocalDate.of(2024, 3, 15); LocalDate nextWednesday = date.with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY)); System.out.println("Mercredi suivant : " + nextWednesday); // Sortie : 2024-03-20 }}Vous pouvez également créer vos propres ajusteurs en implémentant l'interface fonctionnelle TemporalAdjuster. Cela est particulièrement utile pour la logique métier : « premier jour ouvrable du mois » ou « dernier vendredi du trimestre ».
2. Travail avec les fuseaux horaires et ZonedDateTime
Les applications globales doivent tenir compte des fuseaux horaires. La classe ZonedDateTime combine la date, l'heure et le fuseau (ZoneId).
Exemple : conversion de l'heure de New York à Berlin en tenant compte de l'heure d'été/d'hiver.
import java.time.ZonedDateTime;import java.time.ZoneId;import java.time.format.DateTimeFormatter;
public class ZoneExample { public static void main(String[] args) { ZonedDateTime newYork = ZonedDateTime.now(ZoneId.of("America/New_York")); ZonedDateTime berlin = newYork.withZoneSameInstant(ZoneId.of("Europe/Berlin"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm z"); System.out.println("New York : " + newYork.format(formatter)); System.out.println("Berlin : " + berlin.format(formatter)); }}Important : pour obtenir tous les fuseaux disponibles, utilisez ZoneId.getAvailableZoneIds(). Évitez les abréviations à trois lettres (EST, PST) — elles sont ambiguës. Utilisez toujours le format continent/ville (par exemple, Asia/Tokyo).
3. Calculs précis de différences : ChronoUnit et Duration
Pour calculer la différence entre des dates en Java, il existe deux approches :
ChronoUnit— pour la différence en unités calendaires (jours, mois, années) ;Duration— pour les intervalles de temps précis (secondes, nanosecondes).
Exemple : combien de jours et de mois reste-t-il jusqu'au Nouvel An ?
import java.time.LocalDate;import java.time.temporal.ChronoUnit;
public class DiffExample { public static void main(String[] args) { LocalDate today = LocalDate.now(); LocalDate newYear = LocalDate.of(today.getYear() + 1, 1, 1);
long days = ChronoUnit.DAYS.between(today, new