Без использования функции 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)); }