W3docs

Java LocalTime

Représentez des heures sans date ni fuseau horaire en Java avec LocalTime.

LocalTime est le miroir de LocalDate : une heure de la journée — heure, minute, seconde, nanoseconde — sans date ni fuseau horaire. Il représente la même lecture d'horloge murale chaque jour du calendrier, partout : LocalTime.of(9, 30) correspond à neuf heures et demie, n'importe quel jour dans n'importe quelle ville.

C'est le bon type pour une heure récurrente de la journée — ouverture d'un magasin à 09:30, une tâche quotidienne de type cron à 03:15, une réunion qui commence à 14:00 quel que soit le jour. Ce n'est pas le bon type pour "le moment où l'utilisateur a cliqué sur Envoyer à 14:30 aujourd'hui" — cela nécessite une date, et probablement un fuseau horaire. Les deux combinés donnent LocalDateTime, le sujet du chapitre suivant.

Création

LocalTime now = LocalTime.now();                              // current time in the JVM default zone
LocalTime nine = LocalTime.of(9, 0);                          // hour, minute
LocalTime nineThirty = LocalTime.of(9, 30, 15);               // hour, minute, second
LocalTime nineThirtyNanos = LocalTime.of(9, 30, 15, 500_000_000);   // + nanosecond (0 ..999_999_999)
LocalTime parsed = LocalTime.parse("09:30:15");               // ISO-8601 HH:mm[:ss[.nnnnnnnnn]]

Les constantes prédéfinies sont utiles pour les conditions aux limites :

LocalTime.MIDNIGHT     // 00:00
LocalTime.NOON         // 12:00
LocalTime.MIN          // 00:00:00.000000000
LocalTime.MAX          // 23:59:59.999999999

MIN et MAX sont particulièrement utiles lorsqu'on les combine avec un LocalDate pour couvrir toute une journée : LocalDateTime.of(date, LocalTime.MIN) correspond à "minuit au début de la date" ; LocalTime.MAX est la dernière nanoseconde représentable de la journée.

Résolution : nanosecondes

LocalTime est précis à la nanoseconde — neuf champs de résolution (1 seconde = 1 000 000 000 ns). Sur la plupart des systèmes d'exploitation, la résolution réelle de l'horloge est en millisecondes (1 000 000 ns chacune) ou en microsecondes (1 000 ns chacune) ; la précision supplémentaire est là pour que le type ne perde pas d'information lors d'interactions avec des systèmes ayant des horloges à résolution plus élevée.

Accesseurs directs :

time.getHour();           // 0-23
time.getMinute();         // 0-59
time.getSecond();         // 0-59
time.getNano();           // 0-999_999_999

Il n'y a pas de getMilli() ; si vous voulez des millisecondes, divisez les nanosecondes : time.getNano() / 1_000_000.

Format 24 heures, sans AM/PM

LocalTime utilise le format 24 heures en interne. LocalTime.of(13, 0) correspond à "13h00" et le type ne connaît pas AM/PM. L'analyse de chaînes avec "AM"/"PM" nécessite un DateTimeFormatter personnalisé (le chapitre Analyse des dates couvre cela) — le parse par défaut est uniquement au format ISO-8601 sur 24 heures.

Arithmétique et modifications

Même syntaxe fluide que LocalDate :

time.plusHours(2);
time.plusMinutes(30);
time.plusSeconds(45);
time.plusNanos(500_000);

time.withHour(14);                                            // replace one field
time.withMinute(0);

Le comportement de bouclage : chaque méthode plus/minus sur LocalTime boucle silencieusement autour de minuit. LocalTime.of(23, 0).plusHours(2) donne 01:00, pas "demain à 01:00" — il n'y a pas de "demain" dans LocalTime. Si vous avez besoin de savoir si un bouclage s'est produit, utilisez LocalDateTime ou faites le calcul vous-même :

LocalTime late = LocalTime.of(23, 0);
LocalTime later = late.plusHours(2);                          // 01:00 — silently wrapped
// To detect wrap: compare the new value's getHour with what you expected, or use LocalDateTime.

Ce bouclage est documenté et intentionnel, mais c'est un piège si vous l'oubliez. Pour les calculs de type "quand ce quart de travail se termine-t-il ?" pouvant traverser minuit, le bon type est LocalDateTime, pas LocalTime.

Comparaison

time.isBefore(other);
time.isAfter(other);
time.compareTo(other);
time.equals(other);

Ordre lexical par heure:minute:seconde:nano. LocalTime implémente Comparable<LocalTime>, vous pouvez donc trier une liste d'heures ou l'utiliser directement comme clé de TreeMap.

Distance

Duration.between et ChronoUnit.X.between fonctionnent tous les deux :

Duration d = Duration.between(start, end);
long minutes = ChronoUnit.MINUTES.between(start, end);
long seconds = ChronoUnit.SECONDS.between(start, end);

Le signe : positif lorsque end est après start, négatif sinon. La même mise en garde de bouclage s'applique — Duration.between(LocalTime.of(23, 0), LocalTime.of(1, 0)) est −22 heures, pas +2 heures ; l'API traite 01:00 comme antérieur à 23:00 du même jour notionnel. Pour "le quart de travail s'est poursuivi après minuit", l'arithmétique basée sur LocalDateTime est le bon outil.

Combinaison avec LocalDate

Vous convertirez souvent vers une date avec heure :

LocalDate date = LocalDate.of(2025, 11, 4);
LocalTime time = LocalTime.of(9, 30);

LocalDateTime dt = date.atTime(time);                         // 2025-11-04T09:30
LocalDateTime dt2 = time.atDate(date);                        // same thing

atTime / atDate sont les méthodes de jonction. Le résultat est un LocalDateTime — toujours sans fuseau horaire, mais maintenant ancré à un jour du calendrier. Le chapitre suivant va plus loin.

Un exemple concret : un petit assistant de planification

Le programme ci-dessous utilise LocalTime pour une tâche de type planning quotidien : définir une fenêtre "heures d'ouverture", vérifier si un moment donné s'y situe, calculer combien de temps avant la prochaine ouverture, et illustrer le piège du bouclage à minuit.

java— editable, runs on the server

Ce qu'il faut retenir de l'exécution :

  • LocalTime affiché comme 09:00, 17:30, 12:30 — la forme canonique ISO-8601 sur 24 heures. Pas d'AM/PM dans le type. Si vous avez besoin d'afficher "5:30 PM" à un utilisateur, le chapitre Formatage des dates contient le formateur approprié ; le type lui-même ne le sait pas.
  • La vérification "l'heure est-elle dans la fenêtre" utilise !isBefore(open) && !isAfter(close). C'est l'idiome de l'intervalle semi-ouvert vs fermé — les deux extrémités sont incluses. Pour "strictement à l'intérieur", basculez vers les formes non niées.
  • Duration.between(LocalTime.of(22, 0), LocalTime.of(2, 0)) a renvoyé PT-20H, pas PT4H. LocalTime n'a aucune notion de "jour suivant" — lorsque end est plus tôt que start en termes d'horloge, la durée devient négative. Pour un quart de travail qui traverse minuit, changez les entrées en LocalDateTime et laissez les dates résoudre l'ambiguïté. C'est le piège principal de LocalTime.
  • LocalTime.of(23, 30).plusHours(2) a renvoyé 01:30. Le bouclage est silencieux — pas d'exception, pas de drapeau, pas de report dans la date. Si vous avez besoin de savoir "est-ce que ça a bouclé ?", utilisez LocalDateTime. Si vous souhaitez vraiment une arithmétique d'horloge modulo 24 (un planning récurrent, par exemple), le bouclage est le comportement correct.
  • date.atTime(time) était la jonction canonique vers LocalDateTime. Son miroir time.atDate(date) produit le même résultat. Vous les utiliserez constamment lorsque vous lirez une heure d'une source et une date d'une autre, puis les combinerez en un seul objet pour l'API en aval.

Prochaine étape

Le chapitre suivant, Java LocalDateTime, combine LocalDate et LocalTime en un troisième type "local" : une date et une heure, toujours sans fuseau horaire. C'est l'unité naturelle pour "cela s'est produit à 14:30 le 4 novembre" lorsque le fuseau horaire est sans importance ou enregistré séparément.

Pratique

Pratique
Que retourne `LocalTime.of(23, 0).plusHours(3)`, et pourquoi ?
Que retourne `LocalTime.of(23, 0).plusHours(3)`, et pourquoi ?
Was this page helpful?