Рассчитать количество месяцев между двумя датами в PHP?

Без использования функции date_diff PHP 5.3 (я использую PHP 5.2.17), есть ли простой и точный способ сделать это? Я думаю о чем-то вроде кода ниже, но я не знаю, как учитывать високосные годы:

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

Я пытаюсь выяснить, сколько месяцев прошло.

 $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); 

Возможно, вы захотите также включить туда дни, в зависимости от того, имеете ли вы целые месяцы или нет. Надеюсь, вы поняли эту идею.

Это простой метод, который я написал в своем классе для подсчета количества месяцев, участвующих в двух заданных датах:

 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; } 

Как это:

 $date1 = strtotime('2000-01-25'); $date2 = strtotime('2010-02-20'); $months = 0; while (($date1 = strtotime('+1 MONTH', $date1)) <= $date2) $months++; echo $months; 

Если вы хотите включить дни, используйте следующее:

 $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 

Мне недавно нужно было рассчитывать возраст в месяцах от пренатального до 5 лет (60+ месяцев).

Ни один из ответов выше не работал для меня. Первый, который я пробовал, который в основном представляет собой 1 лайнер для ответа на 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)); . . . 

Это не соответствует установленным датам, очевидно, что ответ должен быть 0, поскольку метка месяца (2011-12-04) еще не достигнута, как всегда код возвращает 1.

Второй метод, который я пробовал, используя код Адама

 $bdate = strtotime('2011-01-03'); $edate = strtotime('2011-02-03'); $age = 0; while (strtotime('+1 MONTH', $bdate) < $edate) { $age++; $bdate = strtotime('+1 MONTH', $bdate); } . . . 

Это не удается и говорит 0 месяцев, когда это должно быть 1.

Что для меня работало, это небольшое расширение этого кода. Я использовал следующее:

 $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--; } } } 

Следуйте за ответом @deceze (я ответил на его ответ). Месяц по-прежнему будет считаться в целом, даже если день первой даты не достиг дня второй даты.

Вот мое простое решение по включению дня:

 $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; } 

Логика заключается в том, что если день второй даты меньше дня первой даты, это уменьшит значение переменной $diff на единицу.

Как насчет этого:

 $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); 

моя функция для решения проблемы

 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; } } 

Вот мое решение. Это только проверки лет и месяцев дат. Таким образом, если одна дата равна '31 .10.15 ', а другая – '02 .11.15', она возвращает 1 месяц.

 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']); } 

Вот моя чистая функция для этой проблемы, которая улучшается после ответа deceze.

 /** * Calculates number of months between two dates. Format can be `Ymd` or `Ym`. Day * part is ignored if given. Order of dates doesn't matter, an absolute number is * returned. * * @param string $date1 * @param string $date2 * * @return int */ function dateDiffInMonths($date1, $date2) { $ts1 = strtotime($date1); $ts2 = strtotime($date2); $year1 = date('Y', $ts1); $year2 = date('Y', $ts2); $month1 = date('n', $ts1); $month2 = date('n', $ts2); return abs((($year2 - $year1) * 12) + ($month2 - $month1)); }