« Combien de jours se sont écoulés ? » — une question qui piège les débutants
\n\nChaque développeur PHP rencontre tôt ou tard un problème : il faut savoir combien de jours se sont écoulés entre deux dates. Cela semble simple, non ? On prend deux chaînes, on soustrait l'une de l'autre — et voilà. Mais c'est précisément ici, sans raison apparente, que les erreurs les plus sournoises sont commises.
\n\nNous avons jeté un œil sur Stack Overflow et trouvé une question réelle « Finding the number of days between two dates », qui a rassemblé des milliers de vues. Il s'avère que même les programmeurs expérimentés tombent dans des pièges liés aux fuseaux horaires, aux timestamps Unix et au comportement inattendu de strtotime().
Dans cet article, nous allons analyser les cinq erreurs les plus courantes lors du calcul du nombre de jours entre deux dates en PHP et montrer comment les éviter. Préparez votre éditeur — il y aura beaucoup de code et de conseils pratiques.
\n\nErreur n°1 : Soustraction brute des timestamps Unix
\n\nL'erreur la plus courante — essayer d'obtenir la différence entre deux dates par simple soustraction de timestamps :
\n\n<?php\n$date1 = strtotime('2024-01-01');\n$date2 = strtotime('2024-01-10');\n$days = ($date2 - $date1) / (60 * 60 * 24);\necho $days; // 9\n?>\n\nEn apparence, tout fonctionne. Mais essayez de passer à l'heure d'été. Lors du passage à l'heure d'été, la journée est raccourcie d'une heure, et lors du retour à l'heure d'hiver, elle est allongée. Résultat : 9,04166 ou 8,95833 jours au lieu de 9 exactement.
\n\nComment corriger
\nUtilisez les objets DateTime et la méthode diff(). Ils prennent en compte tous les sauts de temps :
<?php\n$date1 = new DateTime('2024-01-01');\n$date2 = new DateTime('2024-01-10');\n$interval = $date1->diff($date2);\necho $interval->days; // 9 — toujours correct\n?>\n\nTravailler avec la différence de dates PHP via DateTime::diff est la norme de l'industrie. Retenez ce modèle.
Erreur n°2 : Ignorer le fuseau horaire
\n\nImaginez : votre serveur est en Europe/Moscou, et un utilisateur de New York saisit la date « 2024-03-10 ». Vous créez un DateTime sans spécifier de fuseau horaire. PHP utilise le fuseau horaire système du serveur. Résultat : la différence en jours peut « dériver » d'une unité.
C'est particulièrement critique pour les fins de mois et les passages à l'heure d'été. L'erreur se manifeste rarement, mais lorsqu'elle survient en production, il est très difficile de la détecter.
\n\nSolution : spécifiez explicitement le fuseau horaire
\n<?php\n$tz = new DateTimeZone('UTC');\n$date1 = new DateTime('2024-03-10', $tz);\n$date2 = new DateTime('2024-03-20', $tz);\n$interval = $date1->diff($date2);\necho $interval->days; // 10 — honnête\n?>\n\nUtilisez toujours UTC pour les calculs internes. Si vous devez afficher la date à l'utilisateur — convertissez-la dans son fuseau local uniquement lors de l'affichage.
\n\nErreur n°3 : Confusion entre days et format('%a')
\n\nL'objet DateInterval possède une propriété days et une méthode format('%a'). Il semble que ce soit la même chose. Mais il y a une nuance :
- \n
$interval->days— le nombre total de jours (inclut tous les mois et années). La valeur est toujours correcte. \n $interval->format('%a')— la même chose, mais sous forme de chaîne. \n $interval->d— uniquement les jours sans tenir compte des mois. Si la différence est de 35 jours, alorsdretournera 4 (le reste après soustraction d'un mois). \n
Les débutants confondent souvent d et days. En conséquence, ils obtiennent 4 jours au lieu de 35. D'où des bugs dans les rapports, la facturation et les planificateurs de tâches.
Vérifiez toujours quelle propriété vous utilisez
\n<?php\n$date1 = new DateTime('2024-01-01');\n$date2 = new DateTime('2024-02-05');\n$interval = $date1->diff($date2);\n\necho $interval->days; // 35\necho $interval->d; // 4 — PAS LA MÊME CHOSE !\n?>\n\nSi vous avez besoin précisément du nombre de jours entre deux dates — prenez