De l'importance de ne pas trop pré-calculer
- 09/11/2006
Développement://
De l'importance de ne pas trop pré-calculerUn copain m'a signalé un bug étrange de date sur le forum Integralsport : un évènement commençant le 23 mars 2007 se fini le 24 inclu s'il dure deux jours, et le 26 s'il en dure trois. Traque et élimination du bug au menu, et leçon de développement.
J'ai mis un peu de temps à le trouver celui là. Il faut dire qu'il se niche dans un module additionnel (calendar) de phpBB, module bien pratique qui permet de situer sur un calendrier les concours et autres manifestations sportives. Chaque sujet peut être associé à une période de temps, via un couple "date de début" et "durée de l'évènement". La durée est saisie en jours, heures et minutes. Mais quand on regarde le code qui stocke cette durée, on voit qu'il mémorise en fait le nombre de secondes total, soit jours*86400+heures*3600+minutes*60.
Le problème est que le dimanche 25 mars 2007 se produit en France le passage à l'heure d'été, et que l'on perd une heure. La journée dure donc 3600 secondes de moins que d'habitude, et pour 3600 secondes de trop, on passe au jour suivant. Le problème est le même 6 mois plus tard quand on regagne une heure, d'ailleurs.
La solution est de stocker la différence réelle entre la date de départ et la date de départ plus les 3 jours que dure l'évènement. Le code qui suit est en PHP, mais plutôt lisible. mktime() calcule une date en nombre de secondes écoulées depuis le 1 janvier 1970 en tenant compte de toutes les particularités, et donc des changements d'heure.
On passe donc de<?$duree=$duree_jours*86400+$duree_heures*3600+$duree_minutes*60;?>
à<?$duree=mktime($heure+$duree_heures, $minutes+$duree_minutes, 0, $mois, $jour+$duree_jours, $annee)-$debut_evenement;?>
$heure, $minutes, $mois, $jour et $annee contiennent les valeurs de la date de départ, alors que $duree_heures, $duree_minutes et $duree_jours contiennent la durée pour chaque mesure.
Dans notre cas, on obtient bien nos trois jours moins une heure.
La leçon que l'on peut tirer de ce bug est qu'il ne faut pas toujours compresser les données, les calculer en perdant les données initiales et réelles. La seconde leçon est que PHP fournit de très bonnes fonctions pour jouer avec les dates, que c'est probablement le cas de nombreux outils, et qu'il vaut mieux les utiliser plutôt que de ré-inventer la roue.
Rubriques des billets
- Agilité - 15 billets
- Archerie - 8 billets
- Avis - 47 billets
- Cultures - 8 billets
- Délires - 33 billets
- Démocrachie - 3 billets
- Développement - 18 billets
- Développement web - 16 billets
- Ergonomie - 15 billets
- Geekerie - 8 billets
- Inclassable - 4 billets
- Informatique - 19 billets
- Littératures - 34 billets
- PHP - 2 billets
- Poor Lonesome Coder - 17 billets
- Régalons-nous - 6 billets
- Sortons! - 2 billets
- Travail - 14 billets
- Voyages - 2 billets
- Webmasteriat - 18 billets
Commentaires(s)
Ecrire votre commentaire
29/06/2007 - Systeme