PHP Strtotime +1 Month Behaviour

PHP strtotime +1 month behaviour

Here's the algorithm you can use. It should be simple enough to implement yourself.

  • Have the original date and the +1 month date in variables
  • Extract the month part of both variables
  • If the difference is greater than 1 month (or if the original is December and the other is not January) change the latter variable to the last day of the next month. You can use for example t in date() to get the last day: date( 't.m.Y' )

Behaviour of strtotime(+1 month) and December/next year

strtotime('+1 month') add the 1 month in current month, for example

if current date is 2018-06-28 then

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

Output is :

2018-07-28

If you want first date of month then use :

echo date('Y-m-01', strtotime('+1 month')); // +1 month (Jun to July)

or

echo date('Y-m-01'); // Return Current Month

If current month is December and you add 1 month with strtotime('+1 month') then your date will be in next year

PHP Strtotime -1month -2month

It might be related to bug #44073

You could try with something like this :

echo date("M", strtotime("-3 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", strtotime("-2 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", strtotime("-1 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", time()) . "\n";

(Solution found in the comments section of strtotime ; direct link)

And the output :

Apr
May
Jun
Jul

Kind of "cheating" with the date format and month's name and all that...

Why does PHP date('m', strtotime('-1 months')) not work correctly for today? 07/31

Here's a cleaner test case that doesn't expire:

<?php
$origin = mktime(18, 0, 0, 7, 31, 2015);
var_dump( date('r', $origin), date('r', strtotime('-1 months', $origin)) );
string(31) "Fri, 31 Jul 2015 18:00:00 +0200" 
string(31) "Wed, 01 Jul 2015 18:00:00 +0200"

I'm pretty sure it's a documentation issue, because the manual clearly states this (emphasis mine):

Relative month values are calculated based on the length of months
that they pass through. An example would be "+2 month 2011-11-30",
which would produce "2012-01-30". This is due to November being 30
days in length, and December being 31 days in length, producing a
total of 61 days.

... and it's wrong.

PHP bug tracker has tons of dupes about this. They're all closed as not a bug. Here's a relevant comment from 2009 that explains it:

I agree that this is an annoying behaviour.

Also, the implementation is problematic. Basically if you use '+1
month' it takes the month number, adds 1 and parses result as a new
date
.

If you use '+1 month' on the first of the month, it sets the date to
the next first of the month.

This behaviour gives the impression, that php considers the length of
a month, which is not true.

But if you use '+1 month' on the last day of a month, the result is
unexpected
as 2009-05-31 becomes 2009-06-31 which is an invalid date
and then interpreted as 2009-07-01.

This should at least be mentioned in the documentation.

`strtotime` bug when using + 1 month from January

You're trying to add one month to the date 2013-01-31. It should give 31th Feburary 2013, but since the date doesn't exist, it moves on to the next valid month (which is March).

You can use the following work-around:

$current = date('n', strtotime("first day of next month",strtotime($start)));

Using DateTime class:

$date = new DateTime('2013-01-31');
$date->modify('first day of next month');
echo $date->format('n');

This will correctly output 2.

Demo!

Strange behaviour of my code with strtotime

By the way, the way to solve the problem is to not use / as the date separator, if - or . is used like 08.04.2011 or 08-04-2011, then the European method will be assumed to be in use.

If you can only receive dates in 08/04/2011 format, then a simple str_replace will take care of it:

$date = "08/04/2011";
$date = str_replace('/','.',$date); //08.04.2011
echo date('Y-m-d',strtotime($date)); //2011-04-08

How many days does 1 month represent in PHP?

From your examples, it looks like it's subtracting 1 from the month part, and then correcting for illegal dates. Your second example:

2011-03-30 - 1 month = 2011-02-30. This date does not exist, as February 2011 had only 28 days. 30 - 28 = 2, so it puts it as the 2nd day of the following month.

However, I have not found documentation about this.

Either way, assuming I'm right, the answer to your question is no, "1 month" does not have a (constant) equivalent in days, it depends on the input.

Decrease month by one in strtotime?

To decrease by 1 month using strtotime() you literally tell it to decrease by one month:

strtotime($date . ' - 1 month');

Assuming, of course, that $date is a format strtotime() understands.



Related Topics



Leave a reply



Submit