Home » Php » strtotime – Accurate method to add months in PHP 5.1?

strtotime – Accurate method to add months in PHP 5.1?

Posted by: admin July 12, 2020 Leave a comment


Yesterday I ran into an issue with PHP’s strtotime not properly adding a month. On ‘2011-05-31’ I ran:

date('Y-m-d',strtotime( '+1 month', strtotime('now')));

Which returns ‘2011-07-01’ when I am expecting ‘2011-06-30’.

MySQL doesn’t have any issue doing this.

I’d rather not reinvent the wheel with this, as it is fairly easy to make mistakes with date calculations from my experience.

Does anyone have a reliable and tested solution for this for PHP 5.1?

How to&Answers:

It certainly is possible in PHP: Check the strtotime manual, especially this comment.

If you have a MySQL connection available, SELECT DATE_ADD( '2011-05-31', INTERVAL 1 MONTH ) would be less redundant since the (correct) functionality is already implemented without you having to implement it yourself.


Since this seems to be a fairly confusing topic here is some information on it:

You are actually getting an accurate result it is literally increasing the month by 1, the day remains 31, therefore the date is 2011-06-31. If you do echo date('Y-m-d', strtotime('2011-06-31')); you’ll see it displays 2011-07-01.

Here is one method of making this work as “expected” in PHP 5.1 (and before)

function next_month($timestamp)
    $next_month = date('m', $timestamp);

    $next_year = date('Y', $timestamp);

    if($next_month == 12)

    if(date('d', $timestamp) <= date('t', mktime(0, 0, 0, $next_month, 1, $next_year)))
        return date('Y-m-d',strtotime( '+1 month', $timestamp));
        return date('Y-m-d', mktime(0, 0, 0, $next_month, date('t', mktime(0, 0, 0, $next_month, 1, $next_year)), $next_year));

echo next_month(strtotime('2011-05-31'));

echo next_month(strtotime('2011-05-01'));

This is modified code from a library I wrote a while ago — I’ve never found an elegant solution.

For PHP 5.3+

Refer to PHP DateTime::modify adding and subtracting months for a detailed Q/A on this topic.


You could argue that PHP is doing the right thing, and MySQL the wrong one:

MySQL is clamping the value down back to the last valid date that fits into the year/month definition. PHP is adjust upwards, moving forward to the first proper date that matches the specified day (31-30 = 1 day past, so 2011-06-30 + 1 day = 2011-07-01).


Adding +2592000 seconds (60 × 60 × 24 × 30) works the desired way for me.


You could compare the result of strtotime( 'last day of +1 month', strtotime('now')) with strtotime( '+1 month', strtotime('now')), and use whichever one is earlier.


Try using:

$date = date_create("1900-01-01"); // Your start date
$new_date = date_add($date, date_interval_create_from_date_string('1 month')); // Your end date


For other Months : date('Y-m-t',strtotime("2015-05-31T23:59:59 -3 days +1 month"));
Output           : 2015-06-30

For Feb          : date('Y-m-t',strtotime("2015-01-31T23:59:59 -3 days +1 month"));
Output           : 2015-02-28

That will resolve your issue.