After testing tons of solutions, putting all in a unit test, this is what I come out with:
/**
* 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);
}
For example it will return (test cases from the unit test):
- 01.11.2013 - 30.11.2013 - 1 month
- 01.01.2013 - 31.12.2013 - 12 months
- 31.01.2011 - 28.02.2011 - 1 month
- 01.09.2009 - 01.05.2010 - 8 months
- 01.01.2013 - 31.03.2013 - 3 months
- 15.02.2013 - 15.04.2013 - 2 months
- 01.02.1985 - 31.12.2013 - 347 months
Notice: Because of the rounding it does with the days, even a half of a month will be rounded, which may lead to issue if you use it with some cases. So DO NOT USE it for such cases, it will cause you issues.
For example:
- 02.11.2013 - 31.12.2013 will return 2, not 1 (as expected).