Calculer le nombre de mois entre deux dates en PHP?

Sans utiliser la fonction date_diff de PHP 5.3 (j'utilise PHP 5.2.17), existe-t-il un moyen simple et précis de le faire? 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 déterminer le nombre de mois d'une personne.

21
demandé sur cronoklee 2012-11-16 16:47:47

8 réponses

$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 pouvez inclure les jours quelque part aussi, selon que vous voulez dire mois entiers ou non. J'espère que vous obtenez l'idée.

63
répondu deceze 2012-11-16 12:52:17

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;
}
13
répondu pollux1er 2014-09-05 11:24:52

Comme ceci:

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

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

echo $months;

Si vous voulez inclure days to, 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
répondu Adam 2012-11-16 13:17:10

J'ai récemment eu besoin de calculer l'âge en mois allant de prénatal à 5 ans (60 + mois).

Aucune des réponses ci-dessus n'a fonctionné pour moi. Le premier que j'ai essayé, qui est essentiellement un liner 1 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, évidemment la réponse devrait être 0 car la marque du mois (2011-12-04) n'a pas encore été atteinte, mais le code renvoie 1.

La deuxième méthode que j'ai essayé, 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, quand 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
répondu gattsbr 2016-07-06 15:58:08

Suivez la réponse de @ deceze (j'ai upvoted 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 sur l'inclusion du 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 que 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 d'un.

0
répondu Logan Wayne 2014-11-25 06:27:42

Que diriez-vous de ceci:

$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
répondu manix 2015-01-24 23:17:24

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
répondu Khuat Huu Vinh 2015-10-09 04:18:55

Voici ma solution. Ce ne sont que des années de contrôles et des mois de dates. Donc, si une date est '31.10.15' et autre '02.11.15' retourne 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
répondu Evgeny 2015-12-29 13:42:30