Need to add months in PHP?

I needed too do this today (yes, adding weeks could make this unnecessary).  If you find the need to do this, here’s the function I wrote to return a DateTime object, with optional timestamp.


function add_months_to_date( $number_months, $keep_time = true, $date = null ) {
	if ( !is_numeric( $number_months ) || intval( $number_months ) < 1 ) {
		return null;
	}
	
	// Process the $date parameter
	try {
		$date = new DateTime( $date );
	}
	// On any error, default to today
	catch ( Exception $e ) {
		$date = new DateTime();
	}
	
	// Get date values for the current month
	$day = intval( $date->format( 'd' ) );
	$month = intval( $date->format( 'm' ) );
	$year = intval( $date->format( 'Y' ) );

	// Find the future date month and year
	$added_months = $number_months % 12;
	$added_years = floor( $number_months / 12 );
	$future_month = ( $month + $added_months ) % 12;
	$future_year = $year + $added_years + floor( ( $month + $added_months ) / 12 );
	
	// Build future date format, with optional timestamp
	$date_format = '%s-%s-01';
	if ( $keep_time ) {
		$date_format = sprintf( '%s %s', $date_format, $date->format( 'H:i:s' ) );
	}
	
	// Find the last day of the future month
	$future_date = new DateTime( sprintf( $date_format, $future_year, $future_month ) );
	$last_day = $future_date->format( 't' );
	
	// Set out of range dates to the last day of the future month
	if ( $last_day < $day ) {
		$day = $last_day;	
	}
	
	// Set the correct day of the future month and return
	return $future_date->setDate( $future_year, $future_month, $day );
}