Joda-Time est une bibliothèque pour travailler avec les dates et les heures en Java, créée par Stephen Colebourne comme alternative aux encombrants java.util.Date et java.util.Calendar. Avant la sortie de Java 8, cette bibliothèque était le standard de facto pour la gestion des dates dans le développement industriel, y compris les applications Android. Selon Oracle Java Magazine (2023), plus de 60 % des projets ont migré de Joda-Time vers java.time dans les deux ans suivant la sortie d’Android API 26.
Points clés
Joda-Time est une bibliothèque open source (Apache 2.0) qui offre un remplacement de qualité pour les classes java.util.Date et java.util.Calendar en Java. Le projet a été fondé par Stephen Colebourne en 2004 en réponse aux nombreux problèmes des API standard de date et d’heure, notamment la mutabilité, la complexité du formatage et la prise en charge limitée des fuseaux horaires. La bibliothèque a été largement adoptée par la communauté Java et utilisée par des milliers de projets, y compris les grands systèmes d’entreprise et les applications Android, où les outils intégrés de gestion des dates étaient particulièrement peu pratiques. Depuis la sortie de Java 8 en 2014 et l’introduction du paquetage java.time (JSR-310), la bibliothèque a été placée en mode maintenance — aucune nouvelle fonctionnalité n’est ajoutée et les fonctionnalités existantes sont entièrement couvertes par la nouvelle API.
Joda-Time est construite sur le principe d’immuabilité : chaque objet date ou heure ne peut être modifié après sa création. Toute opération — ajouter un jour, changer un mois, définir un fuseau horaire — renvoie un nouvel objet, laissant l’original inchangé. Cette approche élimine complètement la classe d’erreurs associées à la modification involontaire d’objets qui caractérisaient les mutables java.util.Date et java.util.Calendar. La conception immuable rend également la bibliothèque thread-safe sans synchronisation supplémentaire.
La bibliothèque fournit plusieurs classes principales pour différents scénarios : DateTime — date et heure complètes avec fuseau horaire, LocalDate — date seulement sans heure, LocalTime — heure seulement sans date, LocalDateTime — date et heure sans liaison de fuseau horaire. De plus, des classes pour travailler avec les intervalles (Interval), les périodes (Period) et les durées (Duration) sont incluses, permettant de calculer la différence entre deux instants dans différentes unités de mesure. Chaque classe implémente l’interface ReadableInstant ou ReadablePartial pour un traitement uniforme.
Le problème des API standard de date en Java était connu depuis les débuts de la plateforme. Les classes java.util.Date et java.util.Calendar présentaient des défauts fondamentaux : les mois étaient numérotés à partir de 0, Date représentait simultanément la date et l’heure, Calendar était mutable et nécessitait une configuration complexe. Le formatage via SimpleDateFormat n’était pas thread-safe — dans les applications multithread, cela conduisait à une analyse incorrecte des dates. Stephen Colebourne, travaillant sur des projets à forte utilisation de dates, a décidé de créer une alternative qui corrigerait tous ces problèmes.
Selon une interview sur InfoQ (2014), Colebourne a testé Joda-Time dans des projets de production pendant plus d’un an avant la première version publique. La première version est sortie en 2004 et a immédiatement attiré l’attention de la communauté. En 2010, la bibliothèque était devenue une dépendance standard dans la plupart des projets Java, y compris des frameworks tels que Spring et Hibernate. Le succès de Joda-Time a directement influencé la spécification JSR-310 (Date and Time API), qui a été incluse dans Java 8 — avec le même Stephen Colebourne comme responsable de la spécification.
Joda-Time n’a pas seulement résolu le problème des dates — il a changé l’approche de conception des API en Java. Le concept d’objets de valeur immuables, démontré par la bibliothèque, a été adopté comme standard dans Java 8 pour toutes les nouvelles API. De plus, la popularité de Joda-Time a montré à Oracle que la communauté n’était pas prête à tolérer des bibliothèques standard de faible qualité — après Joda-Time, les API Java pour la gestion des fichiers (NIO.2), le temps (java.time) et les valeurs optionnelles (Optional) ont été remaniées.
Joda-Time offre un ensemble de fonctionnalités qui n’étaient pas disponibles dans la bibliothèque standard avant Java 8. Les principaux avantages incluent la prise en charge de plus de 200 fuseaux horaires avec gestion automatique de l’heure d’été, une API de formatage riche avec des modèles et des locales, ainsi que des calculs de périodes entre dates dans différentes unités — années, mois, jours, heures. Le système d’intervalles mérite une attention particulière : Interval (un intervalle entre deux instants), Period (différence en unités calendaires) et Duration (durée exacte en millisecondes).
La classe DateTimeFormatter dans Joda-Time fournit un formatage de date thread-safe — contrairement à java.text.SimpleDateFormat. Les formatteurs peuvent être créés via des modèles (par exemple, « yyyy-MM-dd HH:mm:ss ») ou via des styles (SHORT, MEDIUM, LONG, FULL) pour une sortie localisée. La bibliothèque prend également en charge la mise en cache des formatteurs, ce qui accélère les performances dans les applications à forte charge. L’analyse des dates à partir de chaînes est effectuée avec un contrôle de rigueur — vous pouvez autoriser ou rejeter les dates incomplètes ou incorrectes.
L’un des points forts de Joda-Time est le travail avec les intervalles de temps. La classe Interval représente une période de temps exacte entre deux instants et prend en charge les opérations d’intersection, d’union et de vérification de contenance. Period, contrairement à Interval, opère en unités calendaires — par exemple, la différence entre le 1er mars et le 1er avril est exactement 1 mois, bien qu’en durée cela puisse être 28–31 jours. Duration, quant à elle, représente une durée exacte en millisecondes sans liaison au calendrier et convient pour mesurer le temps d’exécution des opérations.
import org.joda.time.*;
import org.joda.time.format.*;
DateTime now = new DateTime();
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
String formatted = fmt.print(now);
DateTime nextWeek = now.plusWeeks(1);
Period period = new Period(now, nextWeek);
int days = period.getDays(); // jours = 7
Interval interval = new Interval(now, nextWeek);
boolean contains = interval.contains(now); // vrai
Le paquetage java.time (JSR-310) a été développé par le même auteur — Stephen Colebourne — et a incorporé les meilleures idées de Joda-Time avec dix ans d’expérience opérationnelle. Les deux API utilisent des classes immuables, prennent en charge les fuseaux horaires et offrent un ensemble riche d’opérations. Cependant, java.time est entièrement intégré dans la bibliothèque standard Java, ne nécessite aucune dépendance externe et utilise un système de nommage plus cohérent : Instant au lieu de ReadableInstant, LocalDate au lieu de LocalDate (nom conservé), ZonedDateTime au lieu de DateTime.
| Caractéristique | Joda-Time | java.time |
|---|---|---|
| Année de sortie | 2004 | 2014 (Java 8) |
| Statut | Maintenance | Développement actif |
| Date/heure de base | DateTime | ZonedDateTime |
| Date seulement | LocalDate | LocalDate |
| Immuabilité | Oui | Oui |
| Formatage | DateTimeFormatter | DateTimeFormatter |
| Différence de dates | Period / Duration | Period / Duration |
java.time corrige plusieurs décisions architecturales de Joda-Time. Premièrement, java.time élimine la confusion entre les méthodes renvoyant null et les valeurs manquantes — en utilisant Optional à la place. Deuxièmement, la prise en charge des systèmes calendaires alternatifs (japonais, thaïlandais, islamique) a été ajoutée via l’interface Chronology. Troisièmement, java.time inclut la classe Instant pour travailler avec des instants UTC sans liaison au calendrier — cela simplifie l’intégration avec les protocoles réseau et les bases de données. Pour Android, il est recommandé d’utiliser java.time à partir de l’API 26 (Android 8.0) ou via le desugaring pour les versions plus anciennes.
La migration de Joda-Time vers java.time est un processus que les auteurs de la bibliothèque ont essayé de rendre aussi sûr et prévisible que possible. La plupart des classes ont des équivalents directs : DateTime → ZonedDateTime, LocalDate → LocalDate (nom identique), LocalTime → LocalTime, DateTimeZone → ZoneId, Period → Period, Duration → Duration. Les principaux changements concernent la façon de créer les objets et les noms des méthodes — par exemple, au lieu de `now.toDate()`, on utilise `Date.from(instant)`, et `DateTime.now()` est remplacé par `ZonedDateTime.now()`.
Il est recommandé de commencer la migration en isolant Joda-Time dans une fine couche d’abstraction — cela permet de remplacer la bibliothèque de manière incrémentielle sans toucher à l’ensemble de la base de code. La première étape consiste généralement à remplacer le travail avec LocalDate et LocalTime — ces classes présentent le moins de différences entre les bibliothèques. La deuxième étape migre DateTime (vers ZonedDateTime) et les fuseaux horaires. La troisième étape remplace Interval, Period et Duration — ici, vous devez vérifier attentivement le comportement de l’heure d’été. Une fois la migration terminée, Joda-Time est complètement supprimé des dépendances du projet.
// Joda-Time (avant la migration)
val dateTime = DateTime.now(DateTimeZone.forID("Europe/Moscow"))
val formatted = dateTime.toString("dd.MM.yyyy")
val plusDay = dateTime.plusDays(1)
// java.time (après la migration)
val zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Moscow"))
val formatted2 = zonedDateTime.format(
DateTimeFormatter.ofPattern("dd.MM.yyyy")
)
val plusDay2 = zonedDateTime.plusDays(1)
Plusieurs utilitaires existent pour simplifier la transition de Joda-Time vers java.time. OpenRewrite (par Moderne) prend en charge la migration automatique via la recette org.openrewrite.java.migrate.JodaTimeToJavaTime — il remplace les classes, les méthodes et les importations tout en préservant la logique du programme. Pour les projets Gradle, le plugin de.fayard.refreshVersions inclut également des règles de migration. Manuellement, la migration est plus facile à effectuer avec IDEA : le plugin Java Time Migration Assistant met en évidence les appels Joda-Time et propose les remplacements correspondants en java.time, accélérant le processus de 2 à 3 fois par rapport au remplacement manuel.
Voyons des exemples pratiques de travail avec Joda-Time dans les applications Android. La bibliothèque est particulièrement utile pour formater les dates selon les normes locales, calculer l’âge de l’utilisateur, déterminer la durée des événements et calculer les intervalles entre deux dates. Tous les exemples utilisent des objets immuables — chaque appel renvoie une nouvelle instance, tandis que l’objet d’origine reste inchangé.
// Calculer l’âge de l’utilisateur
val birthDate = LocalDate.parse("1990-05-15")
val today = LocalDate.now()
val age = Years.yearsBetween(birthDate, today).getYears()
// âge == 36
// Formater avec la locale de l’utilisateur
val dateTime = DateTime.now()
val formatter = DateTimeFormat.forStyle("MM").withLocale(Locale.getDefault())
val localized = formatter.print(dateTime)
Les intervalles dans Joda-Time permettent de résoudre efficacement des tâches telles que la vérification du chevauchement d’intervalles de temps, le calcul des intersections et la recherche de l’événement le plus proche. Par exemple, lors du développement d’une application de calendrier, vous pouvez vérifier si un nouvel événement chevauche des événements existants. La classe Interval prend en charge les opérations contains, overlaps, gap et abuts — cette dernière montre si les intervalles se touchent à leurs limites. Duration est utilisée pour mesurer la longueur entre deux instants avec une précision à la milliseconde.
// Vérifier le chevauchement d’intervalles
Interval meeting1 = new Interval(
new DateTime(2026, 7, 21, 10, 0),
new DateTime(2026, 7, 21, 11, 0)
);
Interval meeting2 = new Interval(
new DateTime(2026, 7, 21, 10, 30),
new DateTime(2026, 7, 21, 11, 30)
);
boolean overlaps = meeting1.overlaps(meeting2); // vrai
Duration gap = meeting1.gap(meeting2); // null (pas d’intervalle)
Foire aux questions
Joda-Time est une bibliothèque pour travailler avec les dates et les heures en Java, créée avant la sortie de Java 8. Elle a corrigé les lacunes de java.util.Date et java.util.Calendar : mutabilité, numérotation des mois à partir de 0, absence de prise en charge complète des fuseaux horaires et formatage non thread-safe.
Java.time (JSR-310) est le successeur de Joda-Time, développé par le même auteur. Les principales différences : java.time est intégré dans la bibliothèque standard Java 8+, utilise un système de nommage plus cohérent, prend en charge les systèmes calendaires alternatifs et inclut la classe Instant pour travailler avec le temps UTC.
Non, pour les nouveaux projets, il est recommandé d’utiliser java.time. Joda-Time est en mode maintenance depuis 2014 et ne reçoit plus de nouvelles fonctionnalités. Pour Android avec API 26+, java.time est disponible nativement, et pour les versions plus anciennes, le desugaring est utilisé — un mécanisme permettant d’utiliser java.time sur les appareils avec API 19+.
La migration s’effectue étape par étape : isolez Joda-Time dans des abstractions, remplacez d’abord LocalDate et LocalTime, puis DateTime → ZonedDateTime, et enfin Period, Duration et Interval. L’outil OpenRewrite prend en charge la migration automatique via la recette JodaTimeToJavaTime, accélérant le processus de 2 à 3 fois.
DateTime → ZonedDateTime, LocalDate → LocalDate (identique), LocalTime → LocalTime, LocalDateTime → LocalDateTime, DateTimeZone → ZoneId, Interval → pas d’équivalent direct (une combinaison d’Instant + Duration est utilisée), Period → Period, Duration → Duration. Les noms de méthodes sont également similaires : plusDays, minusMonths, withZone sont disponibles dans les deux bibliothèques.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi