NOMBRE DE MOIS ENTRE 2 DATES

cs_GRenard Messages postés 1662 Date d'inscription lundi 16 septembre 2002 Statut Membre Dernière intervention 30 juillet 2008 - 2 févr. 2005 à 16:24
nihilis Messages postés 2 Date d'inscription vendredi 4 mars 2005 Statut Membre Dernière intervention 18 juillet 2006 - 18 juil. 2006 à 12:27
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/29241-nombre-de-mois-entre-2-dates

nihilis Messages postés 2 Date d'inscription vendredi 4 mars 2005 Statut Membre Dernière intervention 18 juillet 2006
18 juil. 2006 à 12:27
Merci beaucoup RDave pour cette petite fonction, elle m'a evité une bonne heure de crise de nerfs.
cs_GRenard Messages postés 1662 Date d'inscription lundi 16 septembre 2002 Statut Membre Dernière intervention 30 juillet 2008 1
5 févr. 2005 à 23:15
intval permet de passer une chaine de caractères en type integer... (entier).
Pourquoi faire ca ? ca se fait tout seul tu vas me dire ! mais c'est mieux de programmer ainsi de de définir ses types correctement.

Pour la vitesse de mySQL je ne prouve rien... il est plus lent tout simplement, je ne dis pas que c'est 4x plus lent ! Parce que sur un autre ordi, ca pourrait être seulement 2x ou 6x on sait pas...
RDave Messages postés 30 Date d'inscription vendredi 9 avril 2004 Statut Membre Dernière intervention 19 novembre 2007
5 févr. 2005 à 21:00
ah ouais...

aurais-tu gagné mon estime =)

je teste, à première vue ca à l'air de jouer.. par contre je pige pas à quoi sert intval ?

merci pour ta fontion en tout cas, si elle fonctionne bien je la mets dans ma source.

pour le benchmark, intéressant, tu prouve que mysql est 4x plus lent que php pour une fonction date... ETONNANT
je ferai aussi mes tests, d'ailleurs à l'occaz avec oracle aussi

@ plus
cs_GRenard Messages postés 1662 Date d'inscription lundi 16 septembre 2002 Statut Membre Dernière intervention 30 juillet 2008 1
5 févr. 2005 à 14:35
Ok regarde bien tit gars, moi je n'ai pas toujours que ca à faire programmer et trouver des choses qui existent déjà en plus ! Si tu cherches bien sur php.net bah tu trouves la solution facile à ton problème...
Ensuite, pour te faire plaisir, je l'ai fait ton benchmark... Je veux juste rajouter par contre que avec mySQL si tu n'est pas sur le même serveur, ca te fait utiliser de la bandwidth pour ton site web (ce qui est généralement compté sur un hébergement pro). (Oh et pour faire des benchmark, j'ai mis des apostrophe plutot que des guillemets à ton truc la...)

Windows, mySQL distant (10000 itérations) :
PHP : 1.75sec
mySQL : 9.05sec

Linux RedHat9, mySQL local (10000 itérations) :
PHP : 1.31sec
mySQL : 1.23sec

Donc, ce qui faut en tirer, c'est que la fonction PHP que j'ai fournie LA est beaucoup plus complète que celle de mySQL... donc ici c'est normal que cela soit un peu plus lent...
Par contre, côté mySQL tu vois bien que si tu n'est pas connecté en local c'est extrèmement plus long. Mais je persiste à dire que php est beaucoup plus rapide que mySQL... car tu vois ici la différence est très minime (même pas 10 centième) et la fonction PHP est plus complète.

J'ai réessayer la même chose avec une fonction nowhere super petite...
Avec ce nouveau code regarde le benchmark que ca me fait :
0.34 secondes

Alors c'est lequel le plus rapide ? cette fonction fait bel et bien ce que tu désirais en plus...


Donc j'espère que ma réponse ne va pas être critiqué dans le sens que je réponds mal, parce que j'ai passé pas mal de temps à faire ca la !



Fonction 1 (de PHP.net) :
<?php

//-----------------------------------------------------------
function date_diff($date_from,$date_to,$unit='d')
/*
Calculates difference from date_from to date_to, taking into account leap years
if date_from > date_to, the number of days is returned negative
date_from and date_to format is: "dd-mm-yyyy"
It can calculate ANY date difference, for example between 21-04-345 and 11-11-3412
This is possible by mapping any date to the "range 0" dates, as this table shows:

INI END RANGE LEAP YEARS
... ... ... ...
01/01/1920 01/01/1939 -3 5
01/01/1940 01/01/1959 -2 5
01/01/1960 01/01/1979 -1 5
01/01/1980 01/01/1999 0 5 * this is the range used for calculations with mktime
01/01/2000 01/01/2019 1 5
01/01/2020 01/01/2039 2 5
01/01/2040 01/01/2059 3 5
01/01/2060 01/01/2079 4 5
... ... ... ...

The difference is calculated in the unit specified by $unit (default is "days")
$unit:
'd' or 'D' = days
'y' or 'Y' = years
*/

{
//get parts of the dates
$date_from_parts = explode('-', $date_from);
$date_to_parts = explode('-', $date_to);
$day_from = $date_from_parts[0];
$mon_from = $date_from_parts[1];
$year_from = $date_from_parts[2];
$day_to = $date_to_parts[0];
$mon_to = $date_to_parts[1];
$year_to = $date_to_parts[2];

//if date_from is newer than date to, invert dates
$sign=1;
if ($year_from>$year_to) $sign=-1;
else if ($year_from==$year_to)
{
if ($mon_from>$mon_to) $sign=-1;
else if ($mon_from==$mon_to)
if ($day_from>$day_to) $sign=-1;
}

if ($sign==-1) {//invert dates
$day_from = $date_to_parts[0];
$mon_from = $date_to_parts[1];
$year_from = $date_to_parts[2];
$day_to = $date_from_parts[0];
$mon_to = $date_from_parts[1];
$year_to = $date_from_parts[2];
}

switch ($unit)
{
case 'd': case 'D': //calculates difference in days
$yearfrom1=$year_from; //actual years
$yearto1=$year_to; //(yearfrom2 and yearto2 are used to calculate inside the range "0")
//checks ini date
if ($yearfrom1<1980)
{//year is under range 0
$deltafrom=-floor((1999-$yearfrom1)/20)*20; //delta t1
$yearfrom2=$yearfrom1-$deltafrom; //year used for calculations
}
else if($yearfrom1>1999)
{//year is over range 0
$deltafrom=floor(($yearfrom1-1980)/20)*20; //delta t1
$yearfrom2=$yearfrom1-$deltafrom; //year used for calculations
}
else {//year is in range 0
$deltafrom=0;
$yearfrom2=$yearfrom1;
}

//checks end date
if ($yearto1<1980) {//year is under range 0
$deltato=-floor((1999-$yearto1)/20)*20; //delta t2
$yearto2=$yearto1-$deltato; //year used for calculations
}
else if($yearto1>1999) {//year is over range 0
$deltato=floor(($yearto1-1980)/20)*20; //delta t2
$yearto2=$yearto1-$deltato; //year used for calculations
}
else {//year is in range 0
$deltato=0;
$yearto2=$yearto1;
}

//Calculates the UNIX Timestamp for both dates (inside range 0)
$ts_from = mktime(0, 0, 0, $mon_from, $day_from, $yearfrom2);
$ts_to = mktime(0, 0, 0, $mon_to, $day_to, $yearto2);
$diff = ($ts_to-$ts_from)/86400;
//adjust ranges
$diff += 7305 * (($deltato-$deltafrom) / 20);
return $sign*$diff;
break;

case 'y': case 'Y': //calculates difference in years
$diff=$year_to-$year_from;
$adjust=0;
if ($mon_from>$mon_to) $adjust=-1;
else if ($mon_from==$mon_to)
if ($day_from>$day_to) $adjust=-1;

return $sign*($diff+$adjust);
break;
}
}
?>

Fonction 2 (celle qui s'adapte à ton besoin) :
function datediff($a,$b){
$date1 = intval(substr($a,0,4))*12+intval(substr($a,4,2));
$date2 = intval(substr($b,0,4))*12+intval(substr($b,4,2));
return $date1-$date2;

}
datediff('200402','200312');
RDave Messages postés 30 Date d'inscription vendredi 9 avril 2004 Statut Membre Dernière intervention 19 novembre 2007
5 févr. 2005 à 13:27
Je dis pas que c'est pas faisable en php, juste que ca a l'air (et finallement c'est !) plus compliqué que d'utiliser la fct toute fairte de mysql.

Je suis certain que c'est faisable en php, je crois d'ailleurs que je suis sur la bonne voie...
en tout cas, et c'est bien ce qui m'intéresse sur ce coup-là, c'est plus facile en php ou mysql ? je suis meme partant pour benchmarker les 2 solutions, quand y en aura, et voir qui va le plus vite =)

Je continue sur la fct php et ne manquerai pas de mettre à jour la source si une solution se profile !

Grenard : on cause on cause, mais j'attends tjr ta proposition !

malalam : vois pas une fct php est plus pratique qu'une utilisant mysql ? je me pencherai sur ta fonction dès que j'ai le temps !
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
5 févr. 2005 à 10:29
Heu oui tu as raison 5 ce serait faux lol. Mais bon, je vais pas la rester ici (je l'ai faite au bureau), mais elle marchait chez moi.
J'etais juste etonne que tu dises qu'on ne peut pas faire ca en PHP. Reprends cette fonction, debugge la, ou relis la doc php sur les fonctions de date, parce que a mon avis, tu te plantes : c'est tres faisable en PHP. Une fonctione PHP serait plus logique, et plus pratique.
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
5 févr. 2005 à 10:02
Bah le 1er est juste, du 31 decembre au 1er mai (c'est comme ca que je l'ai ecrite). Le second je sais, c'est normal, ca ne fonctionne pas si on inverse les dates. Mais le but n'etait pas de donner un truc efficace, j'ai ecrit ca en 2mn juste pour montrer que si, c'est faisable en PHP. D'autant plus que les fonctions sur les dates, je ne les connais pas franchement bien...

En fait, ta fonction est pratique, et ce serait pas mal que tu te penches sur une version PHP, parce que je suis d'accord avec GRenard. MySql, c'est une base de donnees. Ses capacites de calcul sont la pour que tu t'en serves sur tes bases. Mais une fonction telle que la tienne devrait etre ecrite en PHP uniquement, c'est plus logique, et franchement plus pratique...
cs_GRenard Messages postés 1662 Date d'inscription lundi 16 septembre 2002 Statut Membre Dernière intervention 30 juillet 2008 1
5 févr. 2005 à 03:48
mySQL est pas fait pour ca ! Il est fait pour te sortir des datas dans une base de données.. pas pour te faire des calculs !

Ensuite, il ne faut pas mettre normalement date($mois_b), et date .. pour chaque... juste mettre la variable...
Ca ne fonctionne pas si tu mets 31 pour un et 1 pour l'autre.
Et pour finir, ta date 1 dois être supérieur à la date 2, sinon ca bug ...
De plus, en placant 31, si jamais tu tombes sur un mois de 30 jours ou moins, eh bien ca te fait 1 mois de décalage en plus ! cherche encore ;)
RDave Messages postés 30 Date d'inscription vendredi 9 avril 2004 Statut Membre Dernière intervention 19 novembre 2007
4 févr. 2005 à 23:45
Yes malalam, merci pour ta fonction ! Là au moins ya qqch à regarder !
Pourtant, j'ai survolé la fonction et fait 2-3 essais, à priori ca marche pas !

echo strftime("resultat : %m", calculMois(5,2004,12,2003));

--> resultat : 05 !!!

alors que

echo strftime("resultat : %m", calculMois(3,2004,4,2005));

--> resultat : 10 !!!...

Je regarderai ca de plus prés un de ces jours !

Grenard, je dis pas que l'ordinateur est rapide, juste que le temps de connection à mysql, si fonctionne en localhost est minime, et je vois pas pourquoi un fonction mysql prendrait plus de temps qu'une en php !?!
cs_GRenard Messages postés 1662 Date d'inscription lundi 16 septembre 2002 Statut Membre Dernière intervention 30 juillet 2008 1
4 févr. 2005 à 15:29
Le temps est minime partout si on prend le principe que l'ordinateur est ultra rapide... mais je persiste à dire que php est beaucoup plus rapide que mySQL pour effectuer des fonctions dans ce style.
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
4 févr. 2005 à 14:27
<?php
function calculMois($mois_a,$an_a,$mois_b,$an_b) {
return $result=mktime(0,0,0,date($mois_a),0,date($an_a))-mktime(0,0,0,date($mois_b),31,date($an_b));
}
echo strftime("resultat : %m", calculMois(6,2004,6,2003));
?>
RDave Messages postés 30 Date d'inscription vendredi 9 avril 2004 Statut Membre Dernière intervention 19 novembre 2007
3 févr. 2005 à 21:48
ben je veux bien connaitre la fonction php qui fait ca !

sinon je comprends pas ta question, à la mysql tu lui demande, selon l'exemple :" combien de mois y-a-t-il entre février 2004 et décembre 2003 ?" la réponse est 2.
Maintenant c'est à toi de remplacer les dates par des variables php, au format YYYYMM et d'en faire une fonction ! Si t'en est pas capable...

Et pour mysql, en comptant que la base soit sur le meme serveur que le php, j'imagine que la perte de temps est minime, voir négligeable pour l'utilisateur.

J'attends ta fonction php avec plaisir et suis voltontier preneur de meilleure solution =) !
cs_GRenard Messages postés 1662 Date d'inscription lundi 16 septembre 2002 Statut Membre Dernière intervention 30 juillet 2008 1
2 févr. 2005 à 16:24
Très mauvais d'utiliser des fonctions par mysql... surtout quand PHP peut te les donner PLUS rapidement ! Surtout que la à la base de données, tu lui demandes quoi ? aucune vraie requête, donc c'est très mauvais faire ca.
Rejoignez-nous