Allez, allez! Petite énigme de fin de semaine!
D’après vous, en PHP, que peut bien retourner
date('d/m/Y', strtotime('0000-00-00')), hein ?
Moi, au début, je pensais que ça allait me sortir EPOCH, donc quelque chose qui aurait dû ressembler à 01/01/1970.
Que nenni! Cela affiche 30/11/1999.
Ah… il a fallu chercher… et une fois trouvé, c’est tout à fait logique.
Cela part d’un bug PHP[1] du parser de PHP qui ne fait aucune différence entre l’année ’0′, ’00′, ’000′ ou ’0000′ et qu’il traduit inévitablement en l’an 2000. A partir de là, dans la gymnastique microprocessoromentale de PHP, il se passe les choses suivantes:
- 0000-00-00 devient 2000-00-00
- 2000-00-00 n’existe pas, il prend le 00 du mois et décide donc que c’est le mois précédent: 1999-12-00[2]
- 1999-12-00 n’existe pas, il prend le 00 du jour et décide que c’est le jour précédent: 1999-11-30[3]
Nous voila donc propulsé fin novembre 1999.
Conclusion:
- il vaut mieux avoir NULL plutôt que ’0000-00-00′ pour une date non utilisée
- pour avoir rapidement la fin d’un mois, il suffit de se mettre au jour 00 du mois suivant. Exemple: si on veut le 31 aout 2010, il suffit d’avoir ’2010-09-00′, strtotime se chargera de revenir un jour en arrière.
Notes
[1] Contrairement à ce qui est écrit dans le rapport de bugs et ses commentaires, le bug existe toujours en PHP5
[2] De la même manière, si vous aviez le mois 13, il passerait à janvier de l’année suivante
[3] De la même manière, si vous aviez le 32 janvier, il passerait au 1er févier et si c’était le 40 janvier, vous arriveriez au 9 février.






10 mai 2007 23h47
Ceci est bien pratique dans un cas: pas se faire ch*** à calculer si février de l’année 2134 sera bissextile ou non!
On peut ainsi pointer sur la date 2134-03-00 et on aura le dernier jour de février (qui est le 28 en l’occurrence, 2134 n’étant pas divisible par 4 ce n’est donc pas une année bissextile ;-) )
11 mai 2007 00h16
bien joué
11 mai 2007 08h30
Il faut rendre à césar ce qui appartient à un autre: c’est Geoffrey, dans un effort surhumain, qui, en tapant strtotime(’0000-00-00′) dans Google (puisque c’est son ami) qui a trouvé le bug, donc les prémices de l’explication :)
Merci
césarGeoffrey :)11 mai 2007 14h17
je rox
6 novembre 2007 00h14
Ah ah et ah !
Et on me demande pourquo j’aime pas manipuler des dates ? Tsss… ;-)