a slightly more compact way of getting the month shift
<?php
function MonthShifter (DateTime $aDate,$months){
$dateA = clone($aDate);
$dateB = clone($aDate);
$plusMonths = clone($dateA->modify($months . ' Month'));
if($dateB != $dateA->modify($months*-1 . ' Month')){
$result = $plusMonths->modify('last day of last month');
} elseif($aDate == $dateB->modify('last day of this month')){
$result = $plusMonths->modify('last day of this month');
} else {
$result = $plusMonths;
}
return $result;
}
$x = new DateTime('2017-01-30');
echo( $x->format('Y-m-d')." past end of feb, but not dec<br>");
echo('b ' . MonthShifter($x,1)->format(('Y-m-d'))."<br>");
echo('c ' . MonthShifter($x,-1)->format(('Y-m-d'))."<br>");
$x = new DateTime('2017-01-15');
echo("<br>" . $x->format('Y-m-d')." middle of the month <br>");
echo('d ' . MonthShifter($x,1)->format(('Y-m-d'))."<br>");
echo('e ' . MonthShifter($x,-1)->format(('Y-m-d'))."<br>");
$x = new DateTime('2017-02-28');
echo("<br>" . $x->format('Y-m-d')." end of Feb<br>");
echo('f ' . MonthShifter($x,1)->format(('Y-m-d'))."<br>");
echo('g ' . MonthShifter($x,-1)->format(('Y-m-d'))."<br>");
$x = new DateTime('2017-01-31');
echo("<br>" . $x->format('Y-m-d')." end of Jan<br>");
echo('h ' . MonthShifter($x,1)->format(('Y-m-d'))."<br>");
echo('i ' . MonthShifter($x,-1)->format(('Y-m-d'))."<br>");
$x = new DateTime('2017-01-31');
echo("<br>" . $x->format('Y-m-d')." end of Jan +/- 1 years diff, leap year respected<br>");
echo('j ' . MonthShifter($x,13)->format(('Y-m-d'))."<br>");
echo('k ' . MonthShifter($x,-11)->format(('Y-m-d'))."<br>");
2017-01-30 past end of feb, but not dec
b 2017-02-28
c 2016-12-30
2017-01-15 middle of the month
d 2017-02-15
e 2016-12-15
2017-02-28end of Feb
f 2017-03-31
g 2017-01-31
2017-01-31end of Jan
h 2017-02-28
i 2016-12-31
2017-01-31end of Jan +/- 1 years diff, leap year respected
j 2018-02-28
k 2016-02-29