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
indate()
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
Pdo SQLite Could Not Find Driver... PHP File Not Processing
How to Run a .Sh File from PHP
Is HTMLspecialchars Enough to Prevent an SQL Injection on a Variable Enclosed in Single Quotes
How to Select Multiple Rows from MySQL with One Query and Use Them in PHP
Pdo Returning Incorrect, But Duplicate, Data. Key's Not in Database
Leverage Browser Caching, How on Apache or .Htaccess
Best Way to Store Passwords in MySQL Database
Can PHP Detect If Its Run from a Cron Job or from the Command Line
Domxpath - Get Href Attribute and Text Value of an a Element
PHP Regex to Get String Inside Href Tag
Disable Browser Cache in PHP or JavaScript in a Flash Application
Merge Two Multidimensional Arrays and Reindex All Subarrays
File_Get_HTML Displays Fatal Error Call to Undefined Function
MySQL Encryption/Storing Sensitive Data,
Better Way to Check Variable for Null or Empty String
PHP Best Practices for User Authentication and Password Security