web-dev-qa-db-fra.com

Calculer le nombre de mois entre deux dates en PHP?

Sans utiliser PHP 5.3's date_diff function (j'utilise PHP 5.2.17), existe-t-il un moyen simple et précis de faire cela? Je pense à quelque chose comme le code ci-dessous, mais je ne sais pas comment rendre compte des années bissextiles:

$days = ceil(abs( strtotime('2000-01-25') - strtotime('2010-02-20') ) / 86400);
$months = ???;

J'essaie de calculer le nombre de mois qu'une personne a.

21
cronoklee
$date1 = '2000-01-25';
$date2 = '2010-02-20';

$ts1 = strtotime($date1);
$ts2 = strtotime($date2);

$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);

$month1 = date('m', $ts1);
$month2 = date('m', $ts2);

$diff = (($year2 - $year1) * 12) + ($month2 - $month1);

Vous voudrez peut-être aussi inclure les jours quelque part, selon que vous voulez dire entier mois ou non. J'espère que vous avez l'idée cependant.

71
deceze

C'est une méthode simple que j'ai écrite dans ma classe pour compter le nombre de mois impliqués en deux dates données:

public function nb_mois($date1, $date2)
{
    $begin = new DateTime( $date1 );
    $end = new DateTime( $date2 );
    $end = $end->modify( '+1 month' );

    $interval = DateInterval::createFromDateString('1 month');

    $period = new DatePeriod($begin, $interval, $end);
    $counter = 0;
    foreach($period as $dt) {
        $counter++;
    }

    return $counter;
}
14
pollux1er

Comme ça:

$date1 = strtotime('2000-01-25');
$date2 = strtotime('2010-02-20');
$months = 0;

while (($date1 = strtotime('+1 MONTH', $date1)) <= $date2)
    $months++;

echo $months;

Si vous souhaitez inclure des jours à, utilisez ceci:

$date1 = strtotime('2000-01-25');
$date2 = strtotime('2010-02-20');

$months = 0;

while (strtotime('+1 MONTH', $date1) < $date2) {
    $months++;
    $date1 = strtotime('+1 MONTH', $date1);
}

echo $months, ' month, ', ($date2 - $date1) / (60*60*24), ' days'; // 120 month, 26 days
2
Adam

J'ai récemment eu besoin de calculer l'âge en mois allant de la période prénatale à 5 ans (60 mois et plus).

Aucune des réponses ci-dessus n'a fonctionné pour moi… .. Le premier que j'ai essayé, qui est fondamentalement une doublure pour la réponse de Deceze

$bdate = strtotime('2011-11-04'); 
$edate = strtotime('2011-12-03');
$age = ((date('Y',$edate) - date('Y',$bdate)) * 12) + (date('m',$edate) - date('m',$bdate));
. . .

Cela échoue avec les dates définies, bien évidemment, la réponse doit être 0, le mois (2011-12-04) n’ayant pas encore été atteint, quel que soit le code retourné 1.

La deuxième méthode que j'ai essayée, en utilisant le code d'Adam

$bdate = strtotime('2011-01-03'); 
$edate = strtotime('2011-02-03');
$age = 0;

while (strtotime('+1 MONTH', $bdate) < $edate) {
    $age++;
    $bdate = strtotime('+1 MONTH', $bdate);
}
. . .

Cela échoue et dit 0 mois, alors qu'il devrait être 1.

Ce qui a fonctionné pour moi, c'est une petite expansion de ce code. Ce que j'ai utilisé est le suivant:

$bdate = strtotime('2011-11-04');
$edate = strtotime('2012-01-04');
$age = 0;

if($edate < $bdate) {
    //prenatal
    $age = -1;
} else {
    //born, count months.
    while($bdate < $edate) {
        $age++;
        $bdate = strtotime('+1 MONTH', $bdate);
        if ($bdate > $edate) {
            $age--;
        }
    }
}
1
gattsbr
$date1 = '2000-01-25';
$date2 = '2010-02-20';

$ts1 = strtotime($date1);
$ts2 = strtotime($date2);

$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);

$month1 = date('m', $ts1);
$month2 = date('m', $ts2);

$diff = (($year2 - $year1) * 12) + ($month2 - $month1);

Si le mois est passé de janvier à février ci-dessus, le code ci-dessus vous renverra le $ diff = 1 Mais si vous souhaitez envisager le mois prochain uniquement après 30 jours, ajoutez les lignes de code ci-dessous ainsi que ci-dessus.

$day1 = date('d', $ts1);
$day2 = date('d', $ts2);

if($day2 < $day1){ $diff = $diff - 1; }
0
Bhuvan Arora

Voici ma solution. Il ne fait que vérifier les années et les mois de dates. Ainsi, si une date est '31 .10.15 'et une autre '02 .11.15' elle renvoie 1 mois.

function get_interval_in_month($from, $to) {
    $month_in_year = 12;
    $date_from = getdate(strtotime($from));
    $date_to = getdate(strtotime($to));
    return ($date_to['year'] - $date_from['year']) * $month_in_year -
        ($month_in_year - $date_to['mon']) +
        ($month_in_year - $date_from['mon']);
}
0
Evgeny

Faites un suivi sur la réponse de @deceze (j'ai voté sur sa réponse). Le mois comptera toujours dans son ensemble même si le jour de la première date n'a pas atteint le jour de la deuxième date.

Voici ma solution simple pour inclure le jour:

$ts1=strtotime($date1);
$ts2=strtotime($date2);

$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);

$month1 = date('m', $ts1);
$month2 = date('m', $ts2);

$day1 = date('d', $ts1); /* I'VE ADDED THE DAY VARIABLE OF DATE1 AND DATE2 */
$day2 = date('d', $ts2);

$diff = (($year2 - $year1) * 12) + ($month2 - $month1);

/* IF THE DAY2 IS LESS THAN DAY1, IT WILL LESSEN THE $diff VALUE BY ONE */

if($day2<$day1){ $diff=$diff-1; }

La logique est la suivante: si le jour de la deuxième date est inférieur au jour de la première date, la valeur de la variable $diff sera réduite de un.

0
Logan Wayne

Que dis-tu de ça:

$d1 = new DateTime("2009-09-01");
$d2 = new DateTime("2010-09-01");
$months = 0;

$d1->add(new \DateInterval('P1M'));
while ($d1 <= $d2){
    $months ++;
    $d1->add(new \DateInterval('P1M'));
}

print_r($months);
0
manix

ma fonction pour résoudre le problème

function diffMonth($from, $to) {

        $fromYear = date("Y", strtotime($from));
        $fromMonth = date("m", strtotime($from));
        $toYear = date("Y", strtotime($to));
        $toMonth = date("m", strtotime($to));
        if ($fromYear == $toYear) {
            return ($toMonth-$fromMonth)+1;
        } else {
            return (12-$fromMonth)+1+$toMonth;
        }

    }
0
Khuat Huu Vinh