Blog / Article #78
DateTime → DateTimeImmutable en PHP : l'immutabilité qui sauve vos données (et votre santé mentale)

star

20 Août 2026
objet DateTimeImmutable qui reste stable

Ah, les dates en PHP. Ce sujet qui fait frémir même les développeurs les plus aguerris. Entre les DateTime qui se modifient comme par magie et les bugs temporels qui apparaissent sans crier gare, on a parfois l'impression de jouer à la roulette russe avec son code. Et si je vous disais qu'il existe une solution simple, élégante, et surtout sûre pour éviter ces galères ? Bienvenue dans le monde merveilleux de DateTimeImmutable.

Le problème avec DateTime : un objet qui se prend pour un caméléon

Imaginez un instant : vous créez un objet DateTime, vous le passez à une fonction, et pouf, sans prévenir, il a changé de valeur. Non, ce n'est pas de la magie noire, c'est juste le comportement par défaut de DateTime. Un objet mutable, qui se modifie sur place comme un adolescent en crise. Exemple ? Le voici :

$date = new DateTime('2023-01-01');
echo $date->format('Y-m-d'); // Affiche 2023-01-01

$date->modify('+1 day');
echo $date->format('Y-m-d'); // Affiche 2023-01-02

someFunction($date); // Qui sait ce que cette fonction va faire à notre date ?
echo $date->format('Y-m-d'); // Spoiler : probablement pas ce qu'on attendait.

Le problème, c'est que DateTime est mutable. Chaque appel à une méthode comme modify(), setTime() ou setDate() modifie l'objet directement. Résultat : si vous passez cet objet à une fonction ou si vous l'utilisez dans plusieurs parties de votre code, vous ne pouvez jamais être sûr de sa valeur. C'est comme prêter votre voiture à un ami en espérant qu'il ne la ramène pas avec une aile enfoncée. Spoiler : il la ramènera avec une aile enfoncée.

DateTimeImmutable : l'objet qui ne bouge pas (et c'est très bien comme ça)

Heureusement, PHP nous offre une alternative : DateTimeImmutable. Comme son nom l'indique, cet objet est immutable. Une fois créé, il ne change plus. Jamais. Même sous la torture. Les méthodes comme modify() ou setTime() ne modifient pas l'objet original, mais renvoient une nouvelle instance de DateTimeImmutable avec la valeur modifiée. Exemple :

$date = new DateTimeImmutable('2023-01-01');
echo $date->format('Y-m-d'); // Affiche 2023-01-01

$newDate = $date->modify('+1 day');
echo $date->format('Y-m-d'); // Affiche toujours 2023-01-01

echo $newDate->format('Y-m-d'); // Affiche 2023-01-02

Là, c'est la fête. Plus de surprises, plus de valeurs qui changent sans prévenir. Vous pouvez passer votre objet DateTimeImmutable à toutes les fonctions que vous voulez, il restera toujours le même. C'est comme avoir une voiture en titane : même si quelqu'un essaie de la rayer, elle reste intacte.

Et le meilleur dans tout ça ? DateTimeImmutable est compatible avec DateTime. Vous pouvez utiliser les mêmes méthodes, les mêmes formats, et même convertir un objet DateTime en DateTimeImmutable (et vice versa) sans perdre de données. La transition est donc aussi douce qu'un nuage de barbe à papa.

Pourquoi certains résistent encore (et pourquoi ils ont tort)

Malgré tous ces avantages, certains développeurs traînent des pieds pour adopter DateTimeImmutable. Voici leurs arguments (et pourquoi ils sont nuls) :

  • "C'est plus lent" : Oui, créer une nouvelle instance à chaque modification a un coût. Mais franchement, à moins de manipuler des millions de dates en boucle, la différence est négligeable. Et même si c'était le cas, la stabilité de votre code vaut bien quelques millisecondes de plus.
  • "Mon code marche déjà avec DateTime" : Super. Mais est-ce qu'il marche toujours ? Est-ce que vous êtes sûr à 100% que personne ne va modifier votre objet DateTime quelque part dans le code ? Spoiler : non. Et un jour, ce bug vous explosera à la figure.
  • "Je n'ai pas besoin de l'immutabilité" : Ah, le fameux "ça ne m'arrivera pas". Jusqu'au jour où ça arrive. L'immutabilité n'est pas une option, c'est une garantie. Comme une ceinture de sécurité : vous ne pensez pas en avoir besoin, jusqu'au jour où vous en avez vraiment besoin.

Alors oui, DateTimeImmutable peut sembler un peu plus verbeux. Oui, il faut penser différemment. Mais une fois que vous aurez goûté à la tranquillité d'esprit qu'il procure, vous ne voudrez plus jamais revenir en arrière. C'est comme passer d'un vélo sans freins à une voiture avec ABS : une fois que vous avez essayé, vous ne comprenez même plus comment vous faisiez avant.

Comment migrer sans se prendre la tête

Vous êtes convaincu ? Parfait. Voici comment migrer sans tout casser :

1. Remplacez les new DateTime() par new DateTimeImmutable(). C'est la première étape, la plus simple. Si votre code utilise des DateTime en lecture seule, ça suffira.

2. Adaptez les modifications. Là où vous faisiez $date->modify('+1 day'), vous devrez maintenant faire $date = $date->modify('+1 day'). Oui, c'est un peu plus long à écrire, mais c'est le prix à payer pour la tranquillité.

3. Utilisez DateTimeImmutable::createFromMutable() pour convertir vos anciens objets. Si vous avez des fonctions qui retournent ou acceptent des DateTime, cette méthode permet de les convertir en DateTimeImmutable sans douleur.

4. Testez, testez, testez. Comme pour toute migration, il faut vérifier que tout fonctionne comme avant. Mais cette fois, avec l'assurance que vos dates ne vont pas se mettre à danser la salsa sans prévenir.

Et voilà. En quelques étapes simples, vous avez rendu votre code plus robuste, plus prévisible, et surtout, plus facile à maintenir. Et ça, c'est ce qu'on appelle un win-win.

Conclusion : l'immutabilité, c'est la vie

Passer de DateTime à DateTimeImmutable, ce n'est pas juste une question de mode ou de hype. C'est une question de santé mentale. C'est la différence entre un code qui vous fait des surprises et un code sur lequel vous pouvez compter. Alors oui, ça demande un petit effort d'adaptation. Oui, ça peut sembler un peu plus contraignant au début. Mais une fois que vous aurez goûté à la stabilité, vous ne voudrez plus jamais revenir en arrière.

Alors, prêt à sauter le pas ? Votre futur moi (et vos collègues) vous remercieront.

Publié le 20/08/2026 · 5 min de lecture Partager X LinkedIn

← Précédent Makefile + docker : parce que taper `docker-compose up -d --build` 42 fois par jour, c’est has been Suivant → 2026 : 50 bases de données et toujours mariadb ? pourquoi changer (ou pas)