I am using
$jsdate = date("Y, m, d", strtotime('-1 month', (strtotime($date))));
to convert my dates from
2011-03-28
to
2011, 02, 28
Problem is this is producing unpredictable results. For example today I got
2011-03-28
converted to
2011, 02, 28 // OK
AND
2011-03-29
to
2011, 03, 01 // not OK!
Does anyone know what's wrong here? I wonder if the calculation is inaccurate because of the -1 month.
Is there a way of simply subtracting 1 from m in ...date("Y, m, d", ...?
MORE INFO:
My data needs to be formatted as JavaScript Date Object in which January is 0, Feb is 1, etc. Therefore there is not a need to specifically subtract 1 month but actually subtract 1 from the month integer. At the end, the resulting string is not supposed to be 1 month earlier, but actually the same date, represented using JS Date Object style. I believe #vprimachenko's answer below is a good solution. I apologize if this wasn't clear in my OP.
Thanks!
you might use
$datee = explode('-',$date);
if($datee[1]-- < 0) {
$datee[1]=12;
$datee[0]--;
}
$jsdate = implode(', ',$datee);
The calculation isn't inaccurate, per se. There is no 2/29/2011. If you change your input to 3/29/2012, you'll see that it returns 2/29/2012, because 2012 is a leap year. The same would happen with using something like 7/31/2011. June only has 30 days, so July 31 minus one month would be July 1 (because June 31 doesn't exist).
You could just extract the month, subtract 1, and remake the date, but that will result in attempting to make dates that don't exist.
If you really need the corresponding day of the prior month, you'll probably need to do an if statement of something along the lines of the following to make the day roll back to the last day of February:
$jsdate = date("Y, m, d", strtotime('-1 month', (strtotime($date))));
if($month == '3') {
$jsdate = date("Y, m, d", strtotime('-1 day', (strtotime($jsdate))));
}
You'll also have to account for the rest of the days in March that February doesn't have, as well as leap years, and do something similar for 31-day months that follow 30-day months.
strtotime might work in an unexpected way but it is logical
strtotime('-1 months',strtotime('2011-03-29') // is 2011-02-29
date('Y-m-d','2011-02-29'); //gets converted to the next real date
Here is one kind of fix
http://www.phpreferencebook.com/tips/fixing-strtotime-1-month/
Related
Code:
$time = strtotime('2020-03-31');
echo date('Y-m-d', strtotime('-1 month', $time));
Expected Result: Any date from Feb 2020
Actual Result: 2020-03-02
Is there any better way to add or subtract a month from a given date?
Months are an awkward interval to work with, because they don't have a fixed length. Should the algorithm assume that by "1 month" you mean "30 days", or "31 days", or should it just try subtracting 1 from the "month" field in the date structure?
The last option is what is happening here: given "2020-03-31", PHP's date library is subtracting 1 from the "03" to give "2020-02-31". Since that's an invalid date (February 2020 had 29 days), it then "normalises" it to a real date - 2 days after the 29th February was the 2nd March.
Probably you want to use a more specific period to subtract, like 30 days - although note that if the initial input is "2020-03-01" that will give you "2020-01-31", not "2020-02-01".
Ultimately, this is a problem with our irregular calendar, rather than with PHP. It's really up to you to define what you mean by "a month before", and use a more specific algorithm that captures that requirement.
You can make code like below
<?php
$time = strtotime('2020-03-1 -32 days');
echo date('M-Y', $time); // output Feb-2020
?>
The above code will return date as you expected
I am using a date() format to return the starting weekday of a month. The code I have below is how I am attempting to achieve this. For the current year (2018) this works as normal. For example This month is august and the starting weekday is a Wednesday so it will return a 3 for Wednesday. (It works so far)
As we advance the year to 2019 it starts to get the starting weekday wrong.
For example January 2019 starts on a Tuesday so it should return 2 but returns 1. (one day out)
This error seems to be cumulative so if we go to 2020 then it is 2 days out etc.
I have tried so hard to format this Date() correctly but to no avail. Is this even the correct way to do this?
Code:
$future_month = 5 /*for January 2019*/
$starting_weekday = date('N',mktime(0, 0, 0, date('m', strtotime('+'.$future_month.' months', strtotime(date('Y-m-01')))), 1));
Many Thanks
Cameron
Your code makes this much more complicated than it needs to be.
$dt = new DateTime('first day of +5 months')
$dt->format('N'); // "2"
This question already has answers here:
PHP: Adding months to a date, while not exceeding the last day of the month
(7 answers)
Closed 9 years ago.
I have a simple variable that adds one month to today:
$endOfCycle = date("Y-m", strtotime("+1 month"));
Today is January 2013, so I would expect to get back 2013-02 but I'm getting 2013-03 instead. I can't figure out why it's jumping to March.
It's jumping to March because today is 29th Jan, and adding a month gives 29th Feb, which doesn't exist, so it's moving to the next valid date.
This will happen on the 31st of a lot of months as well, but is obviously more noticable in the case of January to Feburary because Feb is shorter.
If you're not interested in the day of month and just want it to give the next month, you should specify the input date as the first of the current month. This will always give you the correct answer if you add a month.
For the same reason, if you want to always get the last day of the next month, you should start by calculating the first of the month after the one you want, and subtracting a day.
This should be
$endOfCycle=date('Y-m-d', strtotime("+30 days"));
strtotime
expects to be given a string containing a US English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now, or the current time if now is not supplied.
while
date
Returns a string formatted according to the given format string using the given integer timestamp or the current time if no timestamp is given.
See the manual pages for:
http://www.php.net/manual/en/function.strtotime.php
http://www.php.net/manual/en/function.date.php
You can use this code to get the next month:
$ts = mktime(0, 0, 0, date("n") + 1, 1);
echo date("Y-m-d H:i:s", $ts);
echo date("n", $ts);
Assuming today is 2013-01-31 01:23:45 the above will return:
2013-02-01 00:00:00
2
today is 29th of January, +1 month means 29th of Fabruary, but because February consists of 28 days this year, it overlaps to the next day which is March 1st
instead try
strtotime('next month')
Maybe because its 2013-01-29 so +1 month would be 2013-02-29 which doesn't exist so it would be 2013-03-01
You could try
date('m/d/y h:i a',(strtotime('next month',strtotime(date('m/01/y')))));
from the comments on http://php.net/manual/en/function.strtotime.php
$endOfCycle = date("Y-m", mktime(0, 0, 0, date("m", time())+1 , 15, date("m", time())));
try this:
$endOfCycle = date("Y-m", time()+2592000);
this adds 30 days, not exactly a month tough.
I'm stumped as to why the following PHP strtotime function returns '07' as the month number, rather than '06' when $monthToGet = 'June':
$monthToGet = $_GET['mon'];
$monthAsNumber = date('m', strtotime($monthToGet));
From searching, it appears it may be due to default date parameters (in this case the day and year) as I haven't specified them. Would that be the cause?
Any suggestions appreciated!
TL;DR
You are right
echo date("m", strtotime("June"));
-> 07
However, this does work:
echo date("m", strtotime("1. June 2012"));
-> 06
The problem explained
Today is 31. July 2012 and since you provide only a month, the current day and current year are used to create a valid date.
See the documentation:
NOTE
The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now, or the current time if now is not supplied.
Alternatives
You could use date_parse_from_format() or strptime() to achieve what you want with a slightly different approach.
(Thanks to johannes_ and johann__ for their input)
Fixed with :
$monthToGet = '1 '. $_GET['mon'];
But I still don't get why, since "m" is a valid date format
Today is 31 Jul. So a strtotime with only "June" is interpreted as 31 June => 1 July.
In fact:
echo date("Y-m-d",strtotime("January")); // 2012-01-31
echo date("Y-m-d",strtotime("February")); // 2012-03-02
of course... only today 31 Jul 2012 :) Tomorrow all will works.
You're lucky because you found this bug just today ;)
Being that the current month/year is January 2012, why does the following code return December 2011 and not November 2011?
echo date("F Y", strtotime("-2 months"));
This is on PHP 5.3.0 if it makes a difference.
To get what you are looking for you can use this rather verbose version instead:
echo date("F Y", strtotime("first day of this month - 2 months"));
The problem with your original version is described in detail here: http://derickrethans.nl/obtaining-the-next-month-in-php.html. Quoted below:
Over and over again PHP users complain that next month in PHP's
date-string parser doesn't go to the next month, but instead skips to
the one after next month; like in the following example:
<?php
$d = new DateTime( '2010-01-31' );
$d->modify( 'next month' );
echo $d->format( 'F' ), "\n";
?>
The output of the little script will be March. March obviously doesn't
follow January as February is in between. However, the current
behavior is correct. The following happens internally:
next month increases the month number (originally 1) by one. This
makes the date 2010-02-31. The second month (February) only has 28
days in 2010, so PHP auto-corrects this by just continuing to count
days from February 1st. You then end up at March 3rd. The formatting
strips off the year and day, resulting in the output March. This can
easily be seen when echoing the date with a full date format, which
will output March 3rd, 2010:
This is for adding months, but the same applies in reverse when subtracting months; there was no November 31st, so the strtotime method "corrects" it into December 1st.