Made a different fixed version using the month not the day
<?php
function modifyMonth(DateTime $date, string $modificator): DateTime {
$destMonth = $date->format('m') + $date->format('Y') * 12 + ($modificator);
$date->modify("$modificator months");
while ($date->format('m') + $date->format('Y') * 12 > $destMonth)
$date->modify('-1 day');
return $date;
}
?>
Testing :
<?php
$dates = [
['2020/02/29', '+1', '2020/03/29'],
['2020/02/29 12:34', '-1', '2020/01/29 12:34'],
['2020/03/29 01:01', '+1', '2020/04/29 01:01'],
['2020/03/29', '-1', '2020/02/29'],
['2020/03/30', '+1', '2020/04/30'],
['2020/03/30 23:58', '-1', '2020/02/29 23:58'],
['2020/03/31', '+1', '2020/04/30'],
['2020/03/31', '-1', '2020/02/29'],
['2020/03/31', '+2', '2020/05/31'],
['2020/03/31 00:01', '-2', '2020/01/31 00:01'],
['2020/03/01', '+1', '2020/04/01'],
['2020/03/01', '-1', '2020/02/01'],
['2020/02/01', '+1', '2020/03/01'],
['2020/02/01', '-1', '2020/01/01'],
['2020/04/01', '+1', '2020/05/01'],
['2020/04/01 22:22', '-1', '2020/03/01 22:22'],
['2020/12/31', '+2', '2021/02/28'],
['2020/01/31', '-2', '2019/11/30'],
];
foreach ($dates as $date) {
$test = new DateTime($date[0]);
modifyMonth($test, $date[1]);
if ($test != new DateTime($date[2]))
echo $date[0] . " " . $date[1] . " != " . $test->format('c') . "\n";
}
?>
Testing prints no error