Рассчитать количество месяцев между двумя датами в PHP?
Без использования PHP 5.3 функция date_diff (я использую PHP 5.2.17), есть ли простой и точный способ сделать это? Я думаю о чем-то вроде кода ниже, но я не знаю, как учитывать високосные годы:
$days = ceil(abs( strtotime('2000-01-25') - strtotime('2010-02-20') ) / 86400);
$months = ???;
Я пытаюсь определить количество месяцев, в течение которых человек находится.
Ответы
Ответ 1
$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);
Возможно, вы захотите также включить туда дни, в зависимости от того, имеете ли вы целые месяцы или нет. Надеюсь, вы поняли эту идею.
Ответ 2
Это простой метод, который я написал в своем классе для подсчета количества месяцев, участвующих в двух датах:
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;
}
Ответ 3
Вот так:
$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
Ответ 4
Мне недавно нужно было рассчитывать возраст в месяцах от пренатального до 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--;
}
}
}
Ответ 5
Следуйте за ответом @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
на единицу.
Ответ 6
Как насчет этого:
$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);
Ответ 7
моя функция для решения проблемы
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;
}
}
Ответ 8
Вот мое решение. Он проверяет только годы и месяцы. Итак, если одна дата равна "31.10.15", а другая - "022.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']);
}
Ответ 9
Вот моя чистая функция для этой проблемы, которая улучшается после ответа на deceze.
/**
* Calculates number of months between two dates. Format can be `Y-m-d` or `Y-m`. 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));
}
Ответ 10
$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);
Если месяц переключился с января на февраль, код, приведенный выше, вернет вам $ diff = 1. Но если вы хотите рассмотреть следующий месяц только через 30 дней, добавьте строки кода ниже и выше.
$day1 = date('d', $ts1);
$day2 = date('d', $ts2);
if($day2 < $day1){ $diff = $diff - 1; }
Ответ 11
Вот мое решение. Он проверяет годы и месяцы дат и находит разницу.
$date1 = '2000-01-25';
$date2 = '2010-02-20';
$d1=new DateTime($date2);
$d2=new DateTime($date1);
$Months = $d2->diff($d1);
$howeverManyMonths = (($Months->y) * 12) + ($Months->m);