[PHP][Résolu] Probleme avec getdate() et le mois d'octobre !

Probleme avec getdate() et le mois d'octobre ! [PHP][Résolu] - PHP - Programmation

Marsh Posté le 08-07-2004 à 15:23:46    


Mise a jour :
 
Et voila les bugs évoqués plus bas ne sont pas des bugs, il faut savoir que getdate prend en compte le changement d'heure (été-hivers) donc il y a un jour dans l'année ou il faut ajouter plus que 24h pour passer au jour d'après (le dernier dimanche d'octobre dure 25h).
 
Fonctionnalité interessante, mais qui a été difficile à isoler :]  
 
 
---------------- Message intermédiaire -----------------
 
Le bug est simple, prenez n'importe quel 31 octobre, calculez la date du lendemain : getdate(mktime(0,0,0,10,31,ANNEE)+1*24*3600);
 
En résumé : getdate(mktime(0,0,0,10,31,2003)+1*24*3600) donne le 1/11/2003 comme vous vous en doutiez, mais étrangement pour l'année 2004 le jour d'après est encore le 31/10/2004 !
 
Pourquoi ? :(
 
 
--------------- Message original -----------------------
Je gere un affichage de planning hebdomadaire et pour naviguer entre les semaines, je propose un menu de ce type :
 
<- Semaine du 25-10-2004 au 31-10-2004 ->
 
<- étant un lien transportant dans l'url la variable du lundi précédent
-> celui transportant le lundi suivant
 
Tout ceci est calculé avec la fonction getdate :
 

Code :
  1. $dateLundiSuiv = getdate(mktime(0,0,0,$moisLundi,$jourLundi,$anneeLundi)+7*24*3600);


 
Ce code marche trés bien, il me donne à chaque fois une date valide pour le lundi précédent ou suivant. Seul soucis, le mois d'octobre 2004 est rebel, en effet pour la dernière semaine, celle affichée en exemple, il me calcule un lundi suivant égal au dimanche (donc le 31) :/
 
En résumé tout marche sauf pour le mois d'octobre.
 
Je ne comprends vraiment pas.
 
 
 
A vous les studios et merci par avance.


Message édité par WarDrone le 08-07-2004 à 22:03:05
Reply

Marsh Posté le 08-07-2004 à 15:23:46   

Reply

Marsh Posté le 08-07-2004 à 15:30:44    

sans ton code, les studios ne peuvent rien


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 08-07-2004 à 15:37:03    

Code :
  1. /* Je recup la date du lundi passée dans l'url */
  2. if(!empty($_GET['dateLundi'])) {
  3.     $dateLundi = $_GET['dateLundi'];
  4.     $tempdate = split("-",$dateLundi,3);
  5.     $curday = strval($tempdate[0]);
  6.     if($curday>0 && $curday<10)
  7.         $curday="0".intval($curday);
  8.     $curmonth = strval($tempdate[1]);
  9.     $curyear = strval($tempdate[2]);
  10. }
  11. /* Dans le cas ou la date est inexistante (a fortiori invalide) ou invalide */
  12. if(!checkdate($curmonth, $curday,$curyear)) {
  13.     $curyear  = date("Y" );
  14.     $curmonth = date("m" );
  15.     $curday   = date("d" );
  16.     if($curday>0 && $curday<10)
  17.         $curday="0".intval($curday);
  18.     /* jour de la semaine en numérique : de "0" (dimanche) à "6" (samedi) */   
  19.     $weekday = date("w" );
  20.     /* Date du lundi de la semaine */
  21.     $dateLundi = getdate(mktime(0,0,0,$curmonth,$curday,$curyear)-($weekday-1)*24*3600);
  22. }
  23. else
  24.     $dateLundi = getdate(mktime(0,0,0,$curmonth,$curday,$curyear));
  25. $jourLundi = $dateLundi['mday'];
  26. $moisLundi = $dateLundi['mon'];
  27. $anneeLundi = $dateLundi['year'];
  28. /* Calcul du dimanche par rapport au lundi */
  29. $dateDimanche = getdate(mktime(0,0,0,$moisLundi,$jourLundi,$anneeLundi)+6*24*3600);
  30. $jourDimanche = $dateDimanche['mday'];
  31. $moisDimanche = $dateDimanche['mon'];
  32. $anneeDimanche = $dateDimanche['year'];
  33. /* Calcul du lundi précédent */
  34. $dateLundiPrec = getdate(mktime(0,0,0,$moisLundi,$jourLundi,$anneeLundi)-7*24*3600);
  35. $dateLundiPrec = $dateLundiPrec['mday']."-".$dateLundiPrec['mon']."-".$dateLundiPrec['year'];
  36. /* Calcul du lundi suivant */
  37. $dateLundiSuiv = getdate(mktime(0,0,0,$moisLundi,$jourLundi,$anneeLundi)+7*24*3600);
  38. $dateLundiSuiv = $dateLundiSuiv['mday']."-".$dateLundiSuiv['mon']."-".$dateLundiSuiv['year'];
  39. /* Affichage du menu de navigation */
  40. echo "<small><a href=\"impressionSemaine.php?dateLundi=$dateLundiPrec\"><img src='gauche.gif' border=0></a>&nbsp";
  41. echo "Semaine du <b>".$jourLundi."-".$moisLundi."-".$anneeLundi."</b> au <b>".$jourDimanche."-".$moisDimanche."-".$anneeDimanche."</b>";
  42. echo "&nbsp<a href=\"impressionSemaine.php?dateLundi=$dateLundiSuiv\"><img src='droite.gif' border=0></a><br>";


 
 
Edit : Ne pas faire gaffe aux parenthèses manquantes pour les if, c'est l'affichage qui bug.


Message édité par WarDrone le 08-07-2004 à 16:16:46
Reply

Marsh Posté le 08-07-2004 à 15:59:33    

if $curday>0 && $curday<10) => il manque une ( dans tes 2 premiers if
 
date("d-m-Y", mktime(...)) est équivalent à
$dateLundiSuiv = getdate(mktime(...);
  $dateLundiSuiv = $dateLundiSuiv['mday']."-".$dateLundiSuiv['mon']."-".$dateLundiSuiv['year'];
 
Ton erreur, je ne l'ai pas localisée pour le moment.
 
Juste une chose, pour simplifier ton script. Pourquoi passes tu en paramètre d'url des dates plutôt que des timestamps ?
Cela t'éviterait les conversions systématiques.


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 08-07-2004 à 16:13:47    

T509 a écrit :

if $curday>0 && $curday<10) => il manque une ( dans tes 2 premiers if


C'est l'affichage qui bug, mais ils y sont :)
 

T509 a écrit :

date("d-m-Y", mktime(...)) est équivalent à
$dateLundiSuiv = getdate(mktime(...);
  $dateLundiSuiv = $dateLundiSuiv['mday']."-".$dateLundiSuiv['mon']."-".$dateLundiSuiv['year'];


Merci pour l'astuce.
 

T509 a écrit :

Juste une chose, pour simplifier ton script. Pourquoi passes tu en paramètre d'url des dates plutôt que des timestamps ?
Cela t'éviterait les conversions systématiques.


En effet je vais faire comme ça.


Message édité par WarDrone le 08-07-2004 à 16:15:53
Reply

Marsh Posté le 08-07-2004 à 16:31:44    

C'est bluffant, t'embete pas avec mes sources elles sont correctes, regarde plutôt ça :
 

Code :
  1. <?php
  2. $date = getdate(mktime(0,0,0,1,26,2004)+7*24*3600);
  3. echo $date['mday']."-".$date['mon']."-".$date['year'];
  4. echo "<br>";
  5. $date = getdate(mktime(0,0,0,10,25,2004)+7*24*3600);
  6. echo $date['mday']."-".$date['mon']."-".$date['year'];
  7. ?>


 
Resultat :  
 

Code :
  1. 2-2-2004
  2. 31-10-2004


 
En effêt le lundi d'après le lundi 26 janvier 2004 est bien le 2 février, mais le lundi d'après le 25 octobre n'est pas le 31 octobre ! (c'est un dimanche le 31).
 
La fonction getdate() marche parfaitement pour chaque passage de mois sauf de octobre vers novembre.
 
 
 
...


Message édité par WarDrone le 08-07-2004 à 16:38:27
Reply

Marsh Posté le 08-07-2004 à 16:56:51    

Mais il fait vraiment un blocage sur cette fin de mois :
 

Code :
  1. $date = getdate(mktime(0,0,0,10,31,2004)+1*24*3600);
  2. echo $date['mday']."-".$date['mon']."-".$date['year'];


 
Donc j'ajoute un jour au 31 octobre 2004 et comme par magie je me retrouve au 31 octobre 2004 !
 
Vous allez me demander pourquoi je repete 2004 à chaque fois , tout simplement parce qu'en 2003 ou 2005 il passe bien au jour d'après et ne reste pas coincé :(
 
(et ce n'est pas une question d'année bisextile car 2000 et 2008 marchent aussi !)

Reply

Marsh Posté le 08-07-2004 à 16:58:28    

Je ne comprends pas ton souci, il doit y avoir autre chose.
 
Je viens d'essayer avec un script à moi et cela fonctionne bien.
 

Code :
  1. <?php
  2. //en url sont passés des timestamps
  3. //page.php?position={timestamp lundi affiché}&direction={-1 || 1}
  4. function lundi_courant() {
  5. $aujourdhui = time();
  6. $jour = date("w", $aujourdhui);
  7. if ($jour > 1) {
  8.  $aujourdhui = $aujourdhui - (86400 * ($jour - 1));
  9. }
  10. if ($jour == 0) {
  11.  //on est dimanche
  12.  $aujourdhui = $aujourdhui - (86400 * 6);
  13. }
  14. //sinon on est déjà lundi
  15. return $aujourdhui;
  16. }
  17. //verif des entrées
  18. $position = (isset($_GET['position']) && !empty($_GET['position']) && is_numeric($_GET['position'])) ? $_GET['position'] : lundi_courant();
  19. $direction = (isset($_GET['direction']) && !empty($_GET['direction']) && ($_GET['direction']=='1' || $_GET['direction']=='-1')) ? intval($_GET['direction']) : 0;
  20. //verification que la position est une date valide
  21. if (!checkdate(date("m",$position), date("d",$position), date("Y",$position))) {
  22. $position = lundi_courant();
  23. echo "date hs <br>";
  24. }
  25. //positionnement au lundi à afficher selon la direction
  26. $position = $position + (7 * 86400 * $direction);
  27. //affichage
  28. $semaine = date(" d/m/Y ", $position)."au".date(" d/m/Y ", $position+(6*86400));
  29. $html = "<html><body><a href=\"".$PHP_SELF."?position=".$position."&direction=-1\">&lt;-</a>&nbsp;";
  30. $html .= $semaine;
  31. $html .= "&nbsp;<a href=\"".$PHP_SELF."?position=".$position."&direction=1\">-&gt;</a></body></html>";
  32. echo $html;
  33. ?>


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 08-07-2004 à 17:04:22    

Code :
  1. <?php
  2. $date = getdate(mktime(0,0,0,10,31,2004)+1*24*3600);
  3. echo $date['mday']."-".$date['mon']."-".$date['year'];
  4. ?>


 
Essaye ça !

Reply

Marsh Posté le 08-07-2004 à 17:09:03    

Bizarre, je ne comprends pas


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 08-07-2004 à 17:09:03   

Reply

Marsh Posté le 08-07-2004 à 17:09:20    

Code :
  1. <?php
  2. for($i=1990;$i<2011;$i++) {
  3.     $date = getdate(mktime(0,0,0,10,31,$i)+1*24*3600);
  4.     echo $date['mday']."-".$date['mon']."-".$date['year'];
  5.     echo "<br>";
  6. }
  7. ?>


 
Résultat :
 

Code :
  1. 1-11-1990
  2. 1-11-1991
  3. 1-11-1992
  4. 31-10-1993
  5. 1-11-1994
  6. 1-11-1995
  7. 1-11-1996
  8. 1-11-1997
  9. 1-11-1998
  10. 31-10-1999
  11. 1-11-2000
  12. 1-11-2001
  13. 1-11-2002
  14. 1-11-2003
  15. 31-10-2004
  16. 1-11-2005
  17. 1-11-2006
  18. 1-11-2007
  19. 1-11-2008
  20. 1-11-2009
  21. 31-10-2010


 
Plantage régulier tous les 6 ans ou presque ...


Message édité par WarDrone le 08-07-2004 à 17:10:22
Reply

Marsh Posté le 08-07-2004 à 17:13:57    

lol ok ça bug des que le dernier jour d'octobre est un dimanche...

Reply

Marsh Posté le 08-07-2004 à 17:15:13    

eh bien tu viens de trouver un bug de mktime()
 
tu peux le signaler à la en postant dans les commentaires de la doc officielle. Bizarre
 
Ma solution ne souffre pas de ce bug


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 08-07-2004 à 17:21:35    

Merci en tout cas d'avoir lutté avec moi, je vais étudier ta solution.
 
Quand l'erreur vient de la clé a molette et non du plombier c'est pas le top =)

Reply

Marsh Posté le 08-07-2004 à 18:14:39    

C'est bizarre, en remplaçant getdate() par date() dans ta boucle buggée, le 01/11/1993 passe bien.


---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 08-07-2004 à 21:55:55    

WarDrone a écrit :

Code :
  1. <?php
  2. $date = getdate(mktime(0,0,0,10,31,2004)+1*24*3600);
  3. echo $date['mday']."-".$date['mon']."-".$date['year'];
  4. ?>


 
Essaye ça !


 
L'erreur est due (en théorie) aux passages heure d'été/hivers. Il y aurait quand même un bug.
 
Pour ne pas y être sensible, il faut utiliser gmmktime() et gmdate()
 
C'est toujours bon à savoir.


Message édité par T509 le 09-07-2004 à 10:28:22

---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 08-07-2004 à 21:58:46    

En effet ! Probleme résolu,
 
Merci à tous ! Enfin merci à toi et moi =)

Reply

Marsh Posté le 09-07-2004 à 10:27:41    

Après discussion avec un gars de PHP.net, il y aurait vraiment un bug. A suivre ...


Message édité par T509 le 09-07-2004 à 10:28:38

---------------
fermez vos topics résolus avec le tag [Résolu] en fin de titre. Merci !
Reply

Marsh Posté le 27-01-2005 à 13:36:21    

Une solution apportée par un collègue :
 
Son commentaire :

Citation :


c'est crade de faire un getdate sur un timestamp sorti d'on ne sait où... :)
Si tu dois faire des opérations sur les dates, c'est lors de l'appel à mktime et pas sur son résultat :


 

Code :
  1. for ($i = 1990 ;$i < 2011 ; $i++) {
  2. $date = getdate(mktime(0, 0, 0 + (24*3600), 10, 31, $i));
  3. echo $date['mon']."/".$date['mday']."/".$date['year']."\n";
  4. }


Le résultat

Citation :


11/1/1990
11/1/1991
11/1/1992
11/1/1993
11/1/1994
11/1/1995
11/1/1996
11/1/1997
11/1/1998
11/1/1999
11/1/2000
11/1/2001
11/1/2002
11/1/2003
11/1/2004
11/1/2005
11/1/2006
11/1/2007
11/1/2008
11/1/2009
11/1/2010


 
--Edit : ajout du commentaire


Message édité par T509 le 27-01-2005 à 13:38:01
Reply

Marsh Posté le 27-01-2005 à 14:17:08    

C'est cool d'avoir trouvé ce bug/fonctionnalité mais pourquoi ne pas avoir fait dès le début
 

Code :
  1. $dateLundiSuiv = getdate(mktime(0,0,0,$moisLundi,$jourLundi + 7,$anneeLundi));


 
Il prend le jour en cours, rajoute 7 jours, change de mois/année tout seul si nécessaire et pouf, c'est tout ...  
Et en plus, c'est vachement plus lisible je trouve

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed