Accueil > Forum > > > > Calcul de dates avec PHP
Calcul de dates avec PHP
dimanche 3 octobre 2010 à 16:47:12 |
Calcul de dates avec PHP

Renald689
|
Bonjour,
Pour un site web que je suis en train de développer, j'ai besoin de lister toutes les dates comprises dans une période. Sur la première page l'utilisateur saisi une date de début et une date de fin et valide le formulaire. Sur la page de résultat les dates allant de "date_deb" à "date"fin" inclus sont affichées avec un retour chariot entre chaque. (bon en réalité c'est beaucoup plus compliqué, mais je simplifie). Les dates doivent être saisies et affichées au format "Y-m-d" pour être compatible avec ma base SQL.
Mon problème est que certaines dates sont affichées en double dans mon résultat et d'autres manquent. Et bien sur ce ne serait pas drole si le problème était fixe : c'est totalement aléatoire :
Exemple 1 : je demande les dates du 2010-01-01 au 2010-12-31 : aucun problème, j'ai bien 365 dates toutes différentes.
Exemple 2 : je demande les dates du 2010-08-17 au 2010-09-14 : aucun problème, j'ai bien 29 dates toutes différentes
Exemple 3 : je demande les dates du 2011-06-01 au 2011-12-20 : j'ai bien 203 dates, ce qui pourrait paraitre normal, mais en regardant de plus près, je me rend compte que la liste s'arrete au 2011-12-19 et que le 2011-30-10 apparait 2 fois.
Exemple 4 : je demande les dates du 2010-06-01 au 2010-12-31 : même chose que l'exemple 3, mais c'est le 2010-12-31 qui manque et le 2010-10-31 qui est en double.
Voici le code de ma page de résultat :
Code PHP : <?php
include("enteteshtml.php") ;
echo '
<div id="corps">';
$date_deb = $_POST['date_deb'];
$date_fin = $_POST['date_fin'];
$date_debunix = strtotime($date_deb);
$date_finunix = strtotime($date_fin);
for($aunix = $date_debunix; $aunix <= $date_finunix; $aunix = $aunix+86400)
{
$a = date('Y-m-d', $aunix);
echo $a.'<br>';
}
echo '
</div>
</body>
</html>
';
?>
Je vous ai même mis le bouzin en ligne pour tester par vous même si ça peut vous aider à m'aider : http://macqueron.fr/help/
Est-ce que quelqu'un a une idée d'où cela peut venir ? Je ne pense pas avoir fait d'erreur dans le code et je n'ai trouvé aucun bug recensé sur le web qui parle de ça. Bref, je patauge...
--
Rénald
|
|
dimanche 3 octobre 2010 à 17:39:35 |
Re : Calcul de dates avec PHP

Renald689
|
Re-bonjour,
J'avance dans l'analyse de mon problème, et j'ai eut l'idée de modifier mon code comme ceci pour voir ce qui se passe exactement :
Code PHP : <?php
include("avantcorps.php") ;
echo '
<div id="corps">';
$date_deb = $_POST['date_deb'];
$date_fin = $_POST['date_fin'];
$date_debunix = strtotime($date_deb);
$date_finunix = strtotime($date_fin);
for($aunix = $date_debunix; $aunix <= $date_finunix; $aunix = $aunix+86400)
{
$a = date('Y-m-d H:i', $aunix);
echo $a.' = '.$aunix.'<br>';
}
echo '
</div>
</body>
</html>
';
?>
On se rend donc bien compte que la date Unix est bien incrémentée de 86400 à chaque fois, y compris quand le problème se pose, mais il semblerait que ce soit la conversion au format "Y-m-d" qui pose problème... Je relis la page de manuel PHP sur la fonction "date" mais je ne vois rien qui me mette sur la voix
--
Rénald
|
|
dimanche 3 octobre 2010 à 18:07:08 |
Re : Calcul de dates avec PHP

Renald689
|
Réponse acceptée !
Me revoilà une dernière fois : j'ai trouvé tout seul finalement et le problème vient des deux changements d'heure annuels. J'ai donc mis une rustine à mon code mais ça ne me plait pas beaucoup :
Code PHP : <?php
include("avantcorps.php") ;
echo '
<div id="corps">';
$date_deb = $_POST['date_deb'];
$date_fin = $_POST['date_fin'];
$date_debunix = strtotime($date_deb)+43200;
$date_finunix = strtotime($date_fin)+43200;
for($aunix = $date_debunix; $aunix <= $date_finunix+3600; $aunix = $aunix+86400)
{
$a = date('Y-m-d H:i', $aunix);
echo $a.' = '.$aunix.'<br>';
}
echo '
</div>
</body>
</html>
';
?>
Si quelqu'un a quelque-chose de mieux à me proposer, je suis intéressé.
--
Rénald
|
|
dimanche 3 octobre 2010 à 19:47:38 |
Re : Calcul de dates avec PHP

neigedhiver
|
Salut,
Depuis PHP5.1, ne pas préciser le fuseau horaire provoque une erreur.
As-tu essayé de le préciser ? Spécifier le fuseau horaire permet de prendre en compte, dans les calculs de date et heure, le changement d'heure été/hiver (DST).
Exemple :
Code PHP :
<?php
date_default_timezone_set('Europe/Paris');
$debut = strtotime('10/31/2010 01:00');
$fin = strtotime('10/31/2010 04:00');
$diff = $fin - $debut;
echo $diff;
?>
Ce code affichera 14400, en secondes, soit 4h. Ce qui est bien le temps véritablement écoulé, puisqu'à 3h il sera de nouveau 2h...
--
Neige
Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
|
|
lundi 4 octobre 2010 à 06:04:16 |
Re : Calcul de dates avec PHP

jeca
|
Bonjour,
Personnellement, je trouve plus simple d'utiliser la classe "DateTime" qui existe depuis PHP 5.1.
Essaie ce code :
Code PHP : <?php
function calculDate($deb, $fin)
{
$tableauDate = array();
$dateDeb = new DateTime($deb);
while($deb <= $fin)
{
$tableauDate[] = $deb;
$dateDeb -> modify('+ 1 day');
$deb = $dateDeb -> format('Y-m-d');
}
return $tableauDate;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
if(isset($_POST['btn']))
{
echo implode('<br />', calculDate($_POST['dateDeb'], $_POST['dateFin']));
}
else
{
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script type="text/javascript"></script>
<style type="text/css"></style>
</head>
<body>
<form name="date" method="post" action="">
Date début (AAAA-MM-JJ) <input type="text" name="dateDeb" value="" /><br />
Date fin (AAAA-MM-JJ) <input type="text" name="dateFin" value="" /><br />
<input type="submit" name="btn" value="valider" />
</form>
</body>
</html>
<?php } ?>
C'est un tout petit peu plus long à l'exécution (l'écart se situe au niveau du millième de seconde), mais pas besoin de se préoccuper du fuseau horaire ni des changements d'heure ni des années bissextiles (dans ce cas particulier, qui ne réclame qu'une liste de jours).
Cordialement.
JC
|
|
lundi 4 octobre 2010 à 09:20:40 |
Re : Calcul de dates avec PHP

syndrael
|
Comme Jeca.. on goute une fois aux DateTime, on se prend la tête dessus qqs fois mais fini les questions existencielles sur la gestion et autres fonctions..
S.
|
|
lundi 4 octobre 2010 à 09:22:49 |
Re : Calcul de dates avec PHP

neigedhiver
|
@jeca : faux. Avec ton code, j'obtiens :
Code PHP : Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function.
C'est bien quand on n'affiche pas les erreurs, mais on ne les voit pas...
Conclusion : il faut TOUJOURS se préoccuper du fuseau horaire, sinon PHP ne sait pas comment calculer les heures.
--
Neige
Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
|
|
lundi 4 octobre 2010 à 20:04:00 |
Re : Calcul de dates avec PHP

Renald689
|
Bonjour,
Merci pour l'info sur le fuseau horaire neigedhiver, mais celà ne resoud pas le problème : j'ai fait un test en enlevant ma rustine et en mettant le fuseau horaire, et le problème reste le même.
Je garde l'idée du DateTime pour la fin de mon projet, au moment de l'optimisation, parce que pour l'instant ça me parait un peu compliqué à mettre en oeuvre. Donc je reste avec ma rustine pour l'instant.
--
Rénald
|
|
lundi 4 octobre 2010 à 21:35:39 |
Re : Calcul de dates avec PHP

neigedhiver
|
L'origine du problème est assez simple à identifier : c'est le passage à l'heure d'hiver.
A partir de là, décortiquons ce qui se passe.
Je ne sais pas dans quel format tu passes la date de début et de fin, mais je suppose, puisque tu souhaites compter des jours, que tu passes une date sans heure. Donc, par défaut, PHP considère que c'est à 00h00:00.
Au passage à l'heure d'hiver en 2010, le 30 octobre, à 3h, il sera de nouveau 2H. La journée du 30 octobre ne compte pas 24h, mais 25. Donc si tu ajoutes 24h à minuit, il est au final... 23h, toujours le 30 octobre 2010. Donc, tu as 2 fois la même date.
Et au final, ta comparaison dans ta boucle ne sera pas satisfaite la fois qui manque (il manquerait 3600 pour que la boucle soit exécutée une fois de plus). Donc, il te manque la dernière date.
La conclusion, c'est que pour calculer des dates, il faut utiliser... des dates. Et pas des secondes.
Au lieu d'ajouter 86400 secondes, il convient d'ajouter des jours... Tu commences avec un compteur à 0 et tu recalcules la date avec strtotime() en ajoutant litéralement le nombre de jours à la date (puisque PHP est capable de calculer ça). Voici un exemple :
Code PHP : <?php
date_default_timezone_set('Europe/Paris');
$deb_date = '2010-10-01';
$deb = strtotime($deb_date);
$fin = strtotime('2010-11-30');
$curr = $deb;
for ($i = 1; $curr < $fin; $i++) {
echo date('d-m-Y', $curr), '<br />';
$curr = strtotime($deb_date.' +'.$i.'days');
}
?>
Une autre solution consiste à prendre la date de début à midi (mais c'est quand même moins propre).
Pour ce qui est de l'utilisation de l'objet DateTime, voici un exemple commenté :
Code PHP : <?php
$deb = '2010-10-01';
$fin = '2010-11-30';
// On isntancie un nouvel objet DateTime, avec la date de début et le fuseau horaire CET.
$d = new DateTime($deb , new DateTimeZone('Europe/Paris'));
// On crée un objet DateInterval qui correspond à un intervalle d'une journée
// P1D : P pour Period, 1D pour 1 day.
// Cf la liste des paramètres : http://fr2.php.net/manual/fr/dateinterval.construct.php
$di = new DateInterval('P1D');
//On boucle jusqu'à ce que la date de $d soit celle de $fin
while ($d -> format('Y-m-d') != $fin) {
echo $d -> format('Y-m-d'), '<br />';
// On ajoute l'intervalle de 1 jour
$d -> add($di);
}
// On affiche la dernière date
echo $d -> format('Y-m-d');
?>
Dans ce bout de code, le test n'est pas suffisament rigoureux, puisque si la date de fin donnée est antérieure à la date de début, on aura une boucle sans fin. C'est juste pour illustrer le fonctionnement.
J'espère que tu fera bon usage de tout ça, il est assez rare que je prenne autant de temps pour une réponse ;)
--
Neige
Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
|
|
mardi 5 octobre 2010 à 03:33:14 |
Re : Calcul de dates avec PHP

jeca
|
@neigedhiver
DateTime::__construct(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function.
traduction : Faire confiance aux paramètres timezone du système n'est pas fiable. Il est préférable d'utiliser le paramètre date.timezone (php.ini) ou la fonction date_default_timezone_set().
Donc, pas grand chose à voir avec un problème de code.
Conclusion : il faut TOUJOURS se préoccuper du fuseau horaire, sinon PHP ne sait pas comment calculer les heures.
Faux, puisque le paramètre "timezone" du constructeur "DateTime" est optionnel. Par défaut, celui du php.ini est pris en compte.
Au passage à l'heure d'hiver en 2010, le 30 octobre, à 3h, il sera de nouveau 2H. La journée du 30 octobre ne compte pas 24h, mais 25. Donc si tu ajoutes 24h à minuit, il est au final... 23h, toujours le 30 octobre 2010. Donc, tu as 2 fois la même date.
Faux. L'ajout dans le code n'est pas de 24 heures mais de 1 jour, c'est à dire : 31 oct. + 1 jour = 1er nov.
Petite rectification : Le changement d'heure est le 31 à 3 heures.
Pour finir, l'objet "DateInterval" et la méthode "add" n'existent que depuis PHP 5.3, ce que tout le monde n'a pas (PHP 5.1 non plus, peut-être).
Cordialement.
|
|
Cette discussion est classée dans : fin, date, exemple, dates, deb
Répondre à ce message
Sujets en rapport avec ce message
Comparer des dates [ par Blondy ]
Je voudrais comparer des dates pour savoir quel fichier est le plus vieux... Mais lorsque je crée une date avec date("dmy"); par exemple, ça me crée q
histoire de dates [ par LaTatadu91 ]
Salut (encore pr certains) voila je fais un formulaire avec saisie de dates de départ et date de fin afin de pouvoir faire un checkdate j'ai decider d
afficher les dates d'une date de début a une date de fin [ par laura1409 ]
bonjourje suis en train de réaliser un site internet en php qui permet la gestion de planning de formationje travaille en ce moment sur la mise en for
Différence entre deux dates [ par BiBloOo ]
Bonjour a tous !!En cherchant comment faire une différence entre deux dates, je suis tombé sur plusieurs choses dont ce lien ==>http://www.phpcs.com/c
Faire une suite d'insctruction à une date précise en php [ par Shikapowa ]
Mesdames Mesdemoiselles Messieurs bonjour,Alors qu'il pleut intensément dehors, j'essaie de me consoler avec mon projet dans mon bureau et après moult
probleme passage entre les annees [ par nader19 ]
salut . je galere depuis logntemps dans un projet et quand j'ai cru ça termine je tombe sur un beugbref mon beug cette fois çi j'ai decovert c'est pa
petit soucis sur PHP/JS [ par oliopur ]
Voici les p'tit problemes : Sur une base de donnée j'ai un champ qui contient la date et l'heure de suppression future d'un enregistrement sous la for
[PHP] Claculer les date entre deux date [ par michaelminelli1 ]
Bonjour, Pourriez vous m'aider car je cherche un bout de code PHP qui me permet de lister toute les dates entre dates connue (borne comprise) par ex
comparaison dates [ par noussaa19 ]
Bonjour, j'ai un problème dans mon code php je veux comparer 2 dates dont la première récupéré à partir d'une base de donnée mysql mais sous la forme
recuperer toutes les dates superieurs a la date du jours [ par fatatra ]
Bonjour a tous,je veux faire un truc tous simple apparement et pourtant je n'y arrive pas.Je veux lister toutes les dates contenues dans ma bdd superi
Livres en rapport
|
Derniers Blogs
IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc SHAREPOINT BLOG SITE, PROBLèME D'ARCHIVESSHAREPOINT BLOG SITE, PROBLèME D'ARCHIVES par junarnoalg
Dernièrement, nous avons migré le site
myTIC
vers un nouveau serveur SharePoint 2010. Dans les contenus que nous vouloins récupérer, nous avions un certain nombre de blogs.
Nous avons utilisé les commandes Power...
Cliquez pour lire la suite de l'article par junarnoalg
Forum
XML ET PHPXML ET PHP par karouani
Cliquez pour lire la suite par karouani RE : GOOGLE MAPRE : GOOGLE MAP par inwebo
Cliquez pour lire la suite par inwebo
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|