Migration de Joda-Time vers java.time
La migration de code (comprenez : le code existant) n'est pas une partie de plaisir. Cela demande une planification et des efforts considérables pour aboutir. Bien que ce ne soit pas la tâche la plus motivante pour les développeurs, migrer du code existant vers de nouvelles versions de bibliothèques exige de la détermination et une expertise adaptée.Joda-Time vers java.time est une migration de ce type, qui nécessite une planification et une exécution minutieuses.
Si votre projet Java a vu le jour avant Java SE 8 et utilise le traitement des dates et heures, il a probablement utilisé Joda-Time, une excellente bibliothèque qui faisait figure de standard pour gérer ces fonctions avant SE 8. Si votre projet utilise toujours Joda-Time mais que vous souhaitez migrer vers java.time, lisez la suite.
La version Java SE 8 a introduit une nouvelle API standard de date et d'heure améliorée, communément appelée java.time (JSR-310). Le projet Joda-Time recommande désormais de migrer vers java.time (JSR-310).
Bien que java.time (JSR-310) ait été fortement inspiré par Joda-Time, il n'est pas rétrocompatible et les concepts ainsi que la terminologie ont évolué. C'est pourquoi la migration de Joda-Time vers java.time exige une attention particulière sur chaque ligne de code modifiée. Cela peut être chronophage et vous faire regretter l'absence d'une méthode de migration automatisée plus simple.
Il existe une meilleure façon de migrer, que nous avons créée avec Sensei : un plugin IntelliJ permettant d'effectuer automatiquement des transformations de code selon les recettes (règles) que vous définissez. Consacrez votre temps à définir des recettes réutilisables plutôt qu'à effectuer des tâches de migration répétitives. L'automatisation transformera non seulement votre code Joda-Time existant, mais aidera également les équipes à suivre les directives directement dans l'IDE lors de l'écriture de nouveau code.
Pour vous aider à prendre une longueur d'avance, nous avons créé un livre de recettes Sensei public intitulé Standardisation sur java.time (JSR-310), qui inclut des recettes pour migrer de Joda-Time vers java.time de manière moins pénible. Il s'agit d'un ensemble évolutif de recettes que nous continuerons d'enrichir pour offrir une meilleure couverture.
Voici un exemple de migration type qui vous aidera à comprendre comment Sensei simplifie la migration de code existant.

Passer de la migration manuelle répétitive aux transformations de code automatisées
Examinons un exemple de création d'un nouveau DateTime, qui met en évidence quelques pièges cachés lors de la migration d'une seule ligne de code de Joda-Time vers java.time. Nous verrons ensuite l'une de nos recettes Sensei issue de notre livre de recettes « Standardisation sur java.time (JSR-310) » et montrerons comment elle capture toutes ces informations, afin que cette même migration puisse être réutilisée encore et encore par n'importe quel développeur.
Dans cet exemple, nous construisons un DateTime Joda-Time à partir de 7 arguments entiers représentant les valeurs des champs DateTime.
Comment migrer cela vers un équivalent java.time ?
La javadoc de Joda-Time pour ce constructeur indique :
Construit une instance à partir des valeurs des champs de date et d'heure en utilisant ISOChronology dans le fuseau horaire par défaut.
Au premier abord, on pourrait supposer qu'il existe une classe DateTime dans java.time, mais ce n'est pas le cas. Si vous cherchez sur Google « migrate from joda time to java time », vous tomberez très probablement sur l'article de blog de Stephen Colebourne intitulé Converting from Joda-Time to java.time.
Cela constitue un bon point de départ et nous oriente vers l'utilisation de java.time.ZonedDateTime ou java.time.OffsetDateTime. Voici notre première question : lequel utiliser ? Probablement ZonedDateTime, si l'on se fie aux commentaires de Stephen.
En consultant la javadoc de ZonedDateTime, nous ne voyons aucun constructeur. En revenant à l'article de blog de Stephen, nous lisons plus bas :
Construction. Joda-Time propose un constructeur qui accepte un objet et effectue une conversion de type. java.time ne propose que des méthodes de fabrique, la conversion est donc à la charge de l'utilisateur, bien qu'une méthode parse() soit fournie pour les chaînes de caractères.
Il doit donc exister une méthode de fabrique statique. En parcourant les méthodes statiques, nous en trouvons une qui semble correspondre, mais elle n'est pas tout à fait identique.
Elle possède 7 paramètres de type int, tout comme notre constructeur DateTime original de Joda-Time. Cependant, si vous n'y prêtez pas attention, vous passerez à côté d'un détail important. Le 7e paramètre ne représente plus les millisecondes, mais les nanosecondes, car java.time offre une précision supérieure à Joda-Time et mesure les instants à la nanoseconde près. C'est un détail crucial qui peut facilement échapper. De plus, cette méthode attend un ZoneId, ce qui amène à se demander pourquoi ce n'était pas nécessaire auparavant et pourquoi cela l'est devenu maintenant.
En nous rappelant la javadoc de notre constructeur original, qui mentionnait l'utilisation du fuseau horaire par défaut, peut-être existe-t-il un moyen d'obtenir le ZoneId par défaut ?
La javadoc de ZoneId ne mentionne aucun constructeur, mais en examinant les méthodes statiques, nous voyons que nous pouvons utiliser systemDefault()
Maintenant que nous avons réglé la question du ZoneId, que faire de notre conversion des millisecondes en nanosecondes ? Peut-être pouvons-nous utiliser java.util.concurrent.TimeUnit pour effectuer cette conversion.
Cette méthode renvoie un long, alors que notre méthode attend un int ; nous avons donc un problème de conversion supplémentaire à résoudre. Essayons quelque chose de simple. Une multiplication ?
Cela fonctionnera, mais semble un peu déplacé. Si vous ne l'avez pas encore remarqué, nous avons consacré beaucoup de temps et d'efforts à migrer une seule ligne de code. Comme vous pouvez l'imaginer, nous avons de nombreuses modifications de ce type à effectuer manuellement, et cela ne va pas en s'améliorant.
Cependant, en examinant de plus près l'API java.time, nous pouvons découvrir une solution un peu plus fluide.
Bien que ZonedDateTime n'offre aucun moyen évident de définir les millisecondes, cela peut être fait en utilisant la méthode with(TemporalField field, long newValue), avec ChronoField.MILLI_OF_SECOND comme TemporalField.
Et la javadoc mentionne qu'elle effectuera la conversion en nanosecondes pour nous :
Lorsque ce champ est utilisé pour définir une valeur, il doit se comporter de la même manière que NANO_OF_SECOND, avec la valeur multipliée par 1 000 000.
Nous pouvons donc simplement spécifier 0 pour nos nanosecondes dans la méthode de fabrique, puis utiliser la méthode with pour créer un ZonedDateTime contenant toutes les valeurs originales ainsi que les millisecondes.
En regardant notre résultat final, on dirait que nous n'avons modifié qu'une seule ligne de code ; cela ne reflète pas vraiment les efforts déployés pour effectuer cette seule migration !
Créer une recette pour migrer plus rapidement et plus facilement
Sensei nous permet de partager ces connaissances durement acquises avec d'autres développeurs. En créant une recette qui capture toutes ces exigences, les utilisateurs de Sensei pourront effectuer cette migration en un clic.
Une recette Sensei se compose de 3 sections principales :
- Métadonnées
- Recherche
- Correctifs disponibles
Examinons une recette Sensei (qui peut également être visualisée sous forme de recette YAML) qui nous aidera à migrer cet appel vers son équivalent java.time.
DateTime foo = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond);
Section Métadonnées
La section des métadonnées contient des informations sur la recette et sur la manière de l'utiliser.
Section Recherche
La section de recherche d'une recette Sensei spécifie les éléments de code auxquels cette recette doit s'appliquer.
search:
instanceCreation:
args:
1:
type: int
2:
type: int
3:
type: int
4:
type: int
5:
type: int
6:
type: int
7:
type: int
argCount: 7
type: org.joda.time.DateTime
Dans cette section de recherche, nous voyons que nous :
- Recherchons une instanceCreation, c'est-à-dire l'utilisation d'un constructeur. Remarque : il existe de nombreuses autres cibles de recherche disponibles
- Le constructeur doit avoir 7 arguments, ce qui est spécifié par la propriété argCount. Les
- args 1 à 7 doivent être de type int.
- Nous recherchons des constructeurs du type org.joda.time.DateTime
Section Correctifs disponibles
La section availableFixes peut spécifier un ou plusieurs correctifs applicables à l'élément de code correspondant. Chaque correctif peut comporter plusieurs actions ; dans notre cas, nous avons un seul correctif qui effectue 2 actions.
- Le nom du correctif est affiché à l'utilisateur dans le menu « Quickfixes » et décrit ce qui se passera si l'utilisateur applique ce correctif rapide.
- La liste des actions montre les opérations qui seront effectuées par ce correctif.
- L'action rewrite réécrira l'élément de code à l'aide d'un modèle mustache. Elle peut utiliser des variables et des fonctions de remplacement de chaînes.
- L'action modifyAssignedVariable vérifiera si ce constructeur est utilisé pour affecter une valeur à une variable. Si tel est le cas, cette action modifiera la déclaration de la variable pour qu'elle soit du type spécifié par type
Utiliser la recette pour effectuer une transformation de code
Une fois notre recette écrite et activée, elle analyse notre code et met en évidence les segments auxquels elle peut être appliquée.
Dans la capture d'écran ci-dessous, nous pouvons voir que le constructeur cible a été marqué par Sensei. Survoler le constructeur marqué nous montre la shortDescription de la recette et l'option de correctif rapide Migrate to java.time.ZonedDateTime

Après avoir sélectionné le correctif rapide Migrate to java.time.ZonedDateTime, le code est transformé conformément aux actions que nous avons spécifiées dans la recette.

Une migration ponctuelle et des pratiques de codage uniformes entre les équipes - avec Sensei
Comme le montre notre exemple ci-dessus, la migration d'une seule ligne de code peut impliquer des connaissances acquises difficilement. Sensei peut transformer ces connaissances en recettes ou guides pratiques partageables au sein des équipes. Vous pouvez planifier un sprint de migration unique ou adopter une approche de transformations instantanées et progressives vers java.time au fur et à mesure que vous rencontrez du code Joda-Time. Vous pouvez activer/désactiver des recettes pour effectuer des migrations par étapes logiques, et même étendre ou réduire la portée des fichiers analysés par Sensei : la flexibilité qui rend les migrations de code moins pénibles.
La migration de bibliothèques n'est qu'un exemple parmi tant d'autres de la façon dont Sensei peut être utilisé pour standardiser vos projets. Vous pouvez toujours rester à l'affût des anti-modèles ou de certaines transformations de code manuelles que vous rencontrez fréquemment dans les pull requests ou lors de votre propre codage. Si vous avez un ensemble de directives de codage souvent oubliées par les développeurs, vous pouvez les convertir en recettes, permettant ainsi aux développeurs d'appliquer des transformations de code approuvées en toute confiance.
Si vous avez des questions, n'hésitez pas à nous contacter ! Rejoignez-nous sur Slack à l'adresse : sensei-scw.slack.com
Gouvernez le développement assisté par IA avant la mise en production
Évaluez les risques liés à l'IA, appliquez des politiques de codage sécurisé dès le commit et accélérez la livraison sécurisée tout au long de votre cycle de développement.
Explorer plus d'articles
Accédez à du contenu expert sur le codage sécurisé, la gouvernance de l'IA et la gestion des risques logiciels.
%252520%252520(3).avif)
Supercharged Security Awareness: How Tournaments are Inspiring Developers at Erste Group
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

Security as culture: How Blue Prism cultivates world-class secure developers
Learn how Blue Prism, the global leader in intelligent automation for the enterprise, used Secure Code Warrior's agile learning platform to create a security-first culture with their developers, achieve their business goals, and ship secure code at speed

Une culture de la sécurité : comment Sage a bâti son programme de champions
Découvrez comment Sage a renforcé sa sécurité grâce à une approche flexible axée sur les relations humaines, formant plus de 200 champions de la sécurité et obtenant une réduction mesurable des risques.

Mois de la sensibilisation à la cybersécurité 2026 : comprendre la sécurité de l'IA est essentiel à la défense de l'entreprise
Nous avons atteint un point où la plupart des grandes entreprises d'IA ont publiquement appelé à un ralentissement mondial du développement de l'IA afin de permettre aux garde-fous de sécurité de rattraper leur retard. Pourtant, la réalité est que de graves problèmes de sécurité se sont déjà concrétisés. Cela place d'innombrables responsables de la sécurité et équipes de direction dans une situation d'urgence, alors que les coûts financiers et les risques liés à la mise en œuvre de l'IA ne cessent de s'accumuler.

Levier 8 : Valoriser votre programme
Un programme de codage sécurisé a besoin de plus qu'un contenu de qualité pour réussir. Le levier 8 montre comment l'image de marque transforme la participation en une expérience convoitée, axée sur le statut.
.avif)
Chaque employé est désormais en première ligne de la cybersécurité IA
Le paysage technologique des entreprises évolue à une vitesse que peu avaient anticipée avant qu'il ne soit trop tard. Nous avons officiellement franchi le cap du code écrit par l'humain et de l'assistance basique par copilote pour entrer dans l'ère du cycle de vie de développement agentique (ADLC). Si les agents IA autonomes promettent une efficacité sans précédent dans de multiples fonctions, ils apportent également une toute nouvelle catégorie de risques en matière de sécurité et de réglementation.
Sécurisez le développement piloté par l'IA avant le déploiement
Identifiez les risques de développement, appliquez vos politiques et prévenez les vulnérabilités tout au long du cycle de vie de vos logiciels.
