Рассчитать количество месяцев между двумя датами в PHP?
Без использования функции PHP 5.3 date_diff (я использую PHP 5.2.17), есть ли простой и точный способ сделать это? Я думаю о чем-то вроде кода ниже, но я не знаю, как учитывать високосные годы:
$days = ceil(abs( strtotime('2000-01-25') - strtotime('2010-02-20') ) / 86400);
$months = ???;
Я пытаюсь определить, сколько месяцев человеку.
8 answers
$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']);
}