Accurate method to add months in PHP 5.1?
Asked Answered
S

7

7

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?

Sochi answered 1/6, 2011 at 20:17 Comment(5)
Have you set the correct locale?Tom
If you want better coverage in PHP, the php.net/datetime class would be something to venture down.Eruption
This questions accepted answer looks like it should solve your problem: #5760762His
This is 100% correct, it is adding 1 month, but there are only 30 days in June therefore the 31st day is August 1st. Concise answer in a question I asked a while back: #3602905Pricecutting
The DateTime object is PHP 5.2, I specifically asked for a PHP 5.1 solution. My locale is set to the correct timezone.Sochi
S
5

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.

Surf answered 1/6, 2011 at 20:25 Comment(1)
Thanks, I never knew that was available. Glad I followed this questionSinh
P
2

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_month++;

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

    if($next_month == 12)
    {
        $next_year++;
    }

    if(date('d', $timestamp) <= date('t', mktime(0, 0, 0, $next_month, 1, $next_year)))
    {
        return date('Y-m-d',strtotime( '+1 month', $timestamp));
    }
    else
    {
        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.

Pricecutting answered 1/6, 2011 at 21:16 Comment(0)
M
1

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).

Minerva answered 1/6, 2011 at 20:25 Comment(1)
If I had to choose a side of MySQl, Sql Server, Javascript, etc vs. PHP in who is correct, I would not choose PHP in this case.Sochi
C
1

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

Commorancy answered 1/6, 2011 at 20:31 Comment(2)
What about February? Jan 31st + 30 days puts you into March, skipping February entirely.Minerva
This has a similar same issue, but adding 30 days instead of 31Sochi
F
1

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.

Froth answered 1/6, 2011 at 20:39 Comment(0)
R
1

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
Roseola answered 16/5, 2018 at 11:34 Comment(0)
S
0
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.

Sukiyaki answered 6/5, 2015 at 12:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.