<?php
/**
* Return the next month date given a date and month increment
*
* 2010-01-31 +1 month = 2010-02-28 not 2010-03-03
*
* @todo Need to do weekdays and holiday accounting
* @param string $date Date to base from in Y-m-d format
* @param integer $increment Number of months to increment
* @return string Date after increment
*/
function nextMonth($date, $increment)
{
// Grab the first day of month of the passed in date
$firstOfDateMonth = \DateTime::createFromFormat('Y-m-d', $date)->modify('first day of this month');
// Grab the last day of month of the passed in date
$thirtyFirstOfDateMonth = \DateTime::createFromFormat('Y-m-d', $date)->modify('last day of this month');
// Just get the number of the last day
$thirtyFirstOfDateMonthNum = $thirtyFirstOfDateMonth->format('d');
unset($thirtyFirstOfDateMonth);
// Using the first day of month of the passed in date add month increment and get last day of that month
$thirtyFirstOfNextMonth = $firstOfDateMonth;
unset($firstOfDateMonth);
$thirtyFirstOfNextMonth->add(new \DateInterval('P' . (int) $increment . 'M'))->modify('last day of this month');
// Just get the number of the last day
$thirtyFirstOfNextMonthNum = $thirtyFirstOfNextMonth->format('d');
// Turn the passed in date into a DateTime object
$dayOfDateMonth = \DateTime::createFromFormat('Y-m-d', $date);
// Just get the number of the day
$dayOfDateMonthNum = $dayOfDateMonth->format('d');
// Using the passed in date add month increment and assume correct so far
$dt = $dayOfDateMonth;
unset($dayOfDateMonth);
$dt->add(new \DateInterval('P' . (int) $increment . 'M'));
// If the last day of next month < last day of month from passed date && last day of next month < passed date day number
if ($thirtyFirstOfNextMonthNum < $thirtyFirstOfDateMonthNum && $thirtyFirstOfNextMonthNum < $dayOfDateMonthNum) {
// PHP has gone over the date we want so use last day of next month
$dt = $thirtyFirstOfNextMonth;
}
unset($thirtyFirstOfNextMonth);
return $dt->format('Y-m-d');
}
echo nextMonth('2009-12-31', 2),"\n";
echo nextMonth('2010-01-31', 1),"\n";
echo nextMonth('2010-01-05', 1),"\n";
echo nextMonth('2010-12-05', 1),"\n";
echo nextMonth('2010-01-31', 13),"\n";
echo nextMonth('2010-01-31', 3),"\n";
echo nextMonth('2010-01-31', 0),"\n";
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 16
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 18
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 26
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 31
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 38
Fatal error: Call to undefined method DateTime::createFromFormat() in /in/sqghi on line 16
Process exited with code 255.
Output for 5.2.0 - 5.2.9
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 16
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 18
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 26
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 31
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 38
Fatal error: Call to undefined method DateTime::createfromformat() in /in/sqghi on line 16
Process exited with code 255.
Output for 5.0.0 - 5.0.5, 5.1.0 - 5.1.6
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 16
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 18
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 26
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 31
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 38
Fatal error: Class 'DateTime' not found in /in/sqghi on line 16
Process exited with code 255.
Output for 4.4.2 - 4.4.9
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 16
Parse error: syntax error, unexpected T_OBJECT_OPERATOR in /in/sqghi on line 16
Process exited with code 255.
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 16
Parse error: parse error, unexpected T_OBJECT_OPERATOR in /in/sqghi on line 16
Process exited with code 255.
Output for 4.3.2 - 4.3.4
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /in/sqghi on line 16
Parse error: parse error in /in/sqghi on line 16
Process exited with code 255.