После тестирования множества решений, сдачи всех в модульное тестирование, вот что я получаю:
/**
* Calculate the difference in months between two dates (v1 / 18.11.2013)
*
* @param \DateTime $date1
* @param \DateTime $date2
* @return int
*/
public static function diffInMonths(\DateTime $date1, \DateTime $date2)
{
$diff = $date1->diff($date2);
$months = $diff->y * 12 + $diff->m + $diff->d / 30;
return (int) round($months);
}
Например, он вернется (контрольные примеры из модульного теста):
- 01.11.2013 - 30.11.2013 - 1 месяц
- 01.01.2013 - 31.12.2013 - 12 месяцев
- 31.01.2011 - 28.02.2011 - 1 месяц
- 01.09.2009 - 01.05.2010 - 8 месяцев
- 01.01.2013 - 31.03.2013 - 3 месяца
- 15.02.2013 - 15.04.2013 - 2 месяца
- 01.02.1985 - 31.12.2013 - 347 месяцев
Примечание. Из-за округления со днями округляется даже половина месяца, что может привести к проблемам, если вы используете его в некоторых случаях. Поэтому НЕ ИСПОЛЬЗУЙТЕ его в таких случаях, это вызовет у вас проблемы.
Например:
- 02.11.2013 - 31.12.2013 вернет 2, а не 1 (как и ожидалось).