This is an improvement of @jenspj's answer
<?php
$d = new DateTime('2007-12-31');
function addMonths($date, $months)
{
$years = floor(abs($months / 12));
$leap = 29 <= $date->format('d');
$m = 12 * (0 <= $months?1:-1);
for ($a = 1;$a < $years;++$a) {
$date = addMonths($date, $m);
}
$months -= ($a - 1) * $m;
$init = clone $date;
if (0 != $months) {
$modifier = $months . ' months';
$date->modify($modifier);
if ($date->format('m') % 12 != (12 + $months + $init->format('m')) % 12) {
$day = $date->format('d');
$init->modify("-{$day} days");
}
$init->modify($modifier);
}
$y = $init->format('Y');
if ($leap && ($y % 4) == 0 && ($y % 100) != 0 && 28 == $init->format('d')) {
$init->modify('+1 day');
}
return $init;
}
function addYears($date, $years)
{
return addMonths($date, 12 * $years);
}
echo $d->format('F j,Y') . ' N<br />';
$d = addMonths($d, +1);
echo $d->format('F j,Y') . ' +1M<br />';
$d = addMonths($d, +1);
echo $d->format('F j,Y') . ' +1M<br />';
$d = addYears($d, +60);
echo $d->format('F j,Y') . ' +60Y<br />';
$d = addYears($d, -59);
echo $d->format('F j,Y') . ' -59Y<br />';