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
Related
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"
i am trying to get the day of week from a timestamp:
an example of the timestamp could be:
2014-09-14 18:28:11
I have tried with the following code:
$date = date("D", strtotime($activity[$i]['timestamp']));
However the result i get here is:
Thu
which should have been sunday?
Also is it possible to get it as a full discription instead of a short version of the day name?
Answer to part two of the question is that you can just use l (lowercase 'L') and it'll output Sunday instead of Sun.
$date = date("l", strtotime($activity[$i]['timestamp']));
As for the first part, it probably output Thursday, 1 January 1970 because it received an error instead of an actual date as argument to strtotime.
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 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/
i'm trying to use the class DateTime (php>=5.3) to calculate difference from 2 date.
The example from the manual is simple and clear, i tried that example and work good.
But if a change the start and end date, there a problem:
$this->start_date = '2011-03-01';
$this->end_date = '2011-03-31';
var_dump($this->start_date, $this->end_date);
$datetime1 = new DateTime($this->start_date);
$datetime2 = new DateTime($this->end_date);
$interval = $datetime2->diff($datetime1);
echo $interval->format('%a total days')."\n";
echo $interval->format('%m month, %d days');
Output is:
30 total days //ok
1 month, 2 days //no! i think it should be 0 month, 30 days
With march don't work very well! :)
Aren't there 28 days in February? It might be picking February for the "month" unit for some reason or other. The PHP documentation for the method seems to suggest this kind of thing could easily be the case. Saying "x Months" isn't overly useful anyway as a month isn't a fixed unit, it could be 28, 29, 30 or 31 days.
Extract from the PHP dateinterval format documentation below.
The DateInterval::format() method does
not recalculate carry over points in
time strings nor in date segments.
This is expected because it is not
possible to overflow values like "32
days" which could be interpreted as
anything from "1 month and 4 days" to
"1 month and 1 day".