How do I remove 3 months from a date? - php

Assume the date is:
$date = "2011-08-28";
It need to calculate 3 months previous to $date - how can that be done?

$new_timestamp = strtotime('-3 months', strtotime($date));
You can then use the new timestamp with the php date() function to display the new date how you wish, for example:
echo date("Y-m-d",$new_timestamp);

For me this way is much better because the code is more readable.
$datetime = Datetime::createFromFormat('Y-m-d', "2011-08-28");
$datetime->modify('-3 months');
echo $datetime->format('Y-m-d');
edit: I'm an idiot. You could do the above as follows
$datetime = new Datetime("2011-08-28");
$datetime->modify('-3 months');
echo $datetime->format('Y-m-d');

edit: As pointed out by calumbrodie, you can use the sub method instead of inverting the interval and adding it to the date object
I was trying to do something similar to the original question. I needed to subtract 1 day from a DateTime object. I know the other solutions work, but here's another way I liked better. I used this function:
function getPreviousDay($dateObject){
$interval = new DateInterval('P1D');
$dateObject->sub($interval);
return $dateObject;
}
$dateObject is a DateTime object that can have any date you wan't, but as I wanted the current date, I wrote:
$dateObject = new DateTime('now');
What my function does, is subtract 1 day from the date it receives, but you can modify it so it subtracts 3 months modifying the DateInterval constructor like this:
$interval = new DateInterval('P3M');
$dateObject->sub($interval);
return $dateObject;
You can find the explanation on the string format used in the DateInterval constructor here
DateInterval constructor documentation
There you'll se that letter 'P' (period) is mandatory, the you use an int to specify period length and then specify the period type, in the case of months 'M'. It looks as if there was an error in the documentation, it says that "M" is used for months and minutes, but it actually works for months. If you need to use minutes, you must specify "PTM", for example "PT3M" for 3 minutes, outside the table it says you must use the "T" identifier for time intervals.
edit:
To give a complete example, you have to use this format for a full date time interval:
$format = 'P1Y2M4DT2H1M40S';
This will represent an interval of 1 year, 2 months, 4 days, 2 hours,1 minute and 40 seconds
Hope this helps someone

<?php
$threemonthsago = mktime(0, 0, 0, date("m")-3, date("d"), date("Y"));
?>

<?php
$date = date_create('2000-01-01');
date_add($date, date_interval_create_from_date_string('10 days'));
echo date_format($date, 'Y-m-d');
?>

Related

How can I create a zero DateTime with php?

I need to create an empty date with DateTime(). So, all zeros. The time should be displayed in that way: 0000:00:0:00:00.
What I have tried:
$date = new DateTime("2019-05-09 12:07");
$date->setTime(0, 0);
$date->setDate(0, 0, 0);
echo $date->format("Y:W:j:H:i");
That outputs
-0001:49:30:00:00
instead of 0000:00:0:00:00
What could I do to achieve a zero datetime?
More an explanation of what is going wrong than how to achieve what you are after - even if it is possible.
From a date point of view - 0 is invalid for both the month and day. In the manual it has the example
Example #2 Values exceeding ranges are added to their parent values
So if you have greater than the number of days in a month, it will make it the next month
In your case it is almost the opposite, having a number less than the start of the month. So 0 as the month and day, it will act as -1, so if you formatted it as
echo $date->format("Y:m:d:H:i");
the output is
-0001:11:30:00:00
So as you can see, the day and month are 0-1 (11 and 30) and this has overflowed into the year with -1.
No, You cannot make a datetime 0000:00:0:00:00 from DateTime()
php > echo (new DateTime("0000-00-00 00:00:00"))->format("Y-W-j H:i");
-0001-49-30 00:00
php > echo (new DateTime())->setISODate(0,0,0)->setTime(0,0,0,0)->format("Y-W-j H:i");
-0001-52-26 00:00
Surely Not..!
although you can create any Date with PHP helper function (that uses DateTime class behind) any of you desire date with Zeor Time only
$date = date_create('now'); // or any '1970-01-01'
$date = date_format($date, 'Y-m-d 00:00:00');
// or
$date = date('Y-m-d 00:00:00', strtotime('2021-12-21'));
// or
$date = date('Y-m-d 00:00:00');
output: "2021-12-21 00:00:00"
you can initialize the time with current time and take difference of the current time after. its a trick you can perfom to get (0000-00-00 00:00:00).
$currentTime = new DateTime('NOW');
$diff = $currentTime->diff(new DateTime('NOW'));
echo $diff->format("%Y-%m-%d %H %i %s");
that will give you 0000-00-00 00:00:00

What's the best way of adding a time interval in PHP?

I want to add time to an existing date. I have 2 string variables:
$date = "2013-01-05 10:55:15";
$interval = "50:25:10";
I want to calculate the final date "2013-01-07 13:20:25". The hours in time can be bigger than 23, meaning that this interval can be greater than a whole day.
What's the best way to do this ?
Use DateTime API:
$date = new DateTime("2013-01-05 10:55:15");
$date->add(new DateInterval("PT50H25M10S"));
then you can convert it back to string with the same date format you would use with date() function, if you want to:
$string = $date->format("Y-m-d H:i:s");
For more information about the DateInterval definition, visit this page:
DateInterval
The format starts with the letter P, for "period." Each duration
period is represented by an integer value followed by a period
designator. If the duration contains time elements, that portion of
the specification is preceded by the letter T.
Here are some simple examples. Two days is P2D. Two seconds is PT2S.
Six years and five minutes is P6YT5M.
so in this case PT50H25M10S means 50 hours, 25 minutes, and 10 seconds
Note that DateInterval is available only since PHP 5.3, if you have to use lower version, you could use something like this:
$time = strtotime("2013-01-05 10:55:15");
$time += 55*60*60 + 25*60 + 10;
$newDate = date("Y-m-d H:i:s");
This is a little tricky.
Normally what you would do here if it was a static period, or was a single period type, is something along the lines of:
$date = "2013-01-05 10:55:15";
$time = new DateTime($date);
$time->add(new DateInterval('PT5M'));
This would add 5 minutes to the datetime. However I doubt you can pass the whole interval in. So what you'll probably have to do is split the interval by : and then add each part of the interval (I assume it is dynamic?) to the date separately. So first hours, then minutes, then seconds
For more on this, see here: http://www.php.net/manual/en/datetime.add.php
You could first explode the interval and then get the hours, minutes, seconds, and then use DateTime's add() to add the interval, like so:
$interval = '50:25:10';
$datestring = '2013-01-05 10:55:15';
list($hours, $minutes, $seconds) = explode(':', $interval);
$date = new DateTime($datestring);
$date->add(new DateInterval('PT'.$hours.'H'.$minutes.'M'.$seconds.'S'));
echo $date->format('Y-m-d H:i:s');
Demo!
Use a DateInterval and DateTime->add():
$date = new DateTime("2013-01-05 10:55:15");
$date->add(new DateInterval("PT50H25M10S"));
In case anyone needs based on answers above, I made my function like this:
public function addTime($date, $time) {
$atime = explode(":", $time);
$_date = date_create_from_format("Y-m-d H:i:s", $date);
$_date->add(new DateInterval("PT" . intval($atime[0])."H".intval($atime[1])."M".intval($atime[2])."S"));
return $_date->format("Y-m-d H:i:s");
}
hope it helps someone

Removing exactly one month from a date

It seems that you can't use strotime if you need reliable and accurate date manipulation. For example, if the month has 31 days, then it appears that strtotime simply minuses 30 days, not a whole month.
So, for example, if $event["EndDate"] is equal to "2013-10-31 00:00:01", the following code:
echo date("Y/n/j", strtotime('-1 month', strtotime($event["EndDate"]));
Ouputs: 2013/10/1 instead of 2013/09/30.
QUESTION: Now how I know how NOT to do it, is there another, more accurate, way to make PHP subtract (or add) exactly a whole month, and not just 30 days?
The main issue is that 2013/09/31 does not exist so a better approach would be to use first day or last day of the previous month.
$date = new DateTime("2013-10-31 00:00:01");
$date->modify("last day last month");
echo $date->format("Y/n/j"); // 2013/9/30
When date is 2013-10-15
$date = new DateTime("2013-10-15 00:00:01");
$day = $date->format("d");
$year = $date->format("Y");
$date->modify("last day last month");
$month = $date->format("m");
if (checkdate($month, $day, $year)) {
$date->setDate($year, $month, $day);
}
echo $date->format("Y/n/j"); // 2013-9-15
You say:-
It seems that you can't use strotime if you need reliable and accurate date manipulation
You can, you just need to know how it behaves. Your question prompted me to run a couple of tests.
PHP does not merely subtract 30 days from the date when subtracting a month, although it appears that it does from the single case you are looking at. In fact my test here suggests that it adds 31 days to the start of the previous month (the result of 3rd March suggests this to me) in this case.
$thirtyOnedayMonths = array(
1, 3, 5, 7, 8, 10, 12
);
$oneMonth = new \DateInterval('P1M');
$format = 'Y-m-d';
foreach($thirtyOnedayMonths as $month){
$date = new \DateTime("2013-{$month}-31 00:00:01");
var_dump($date->format($format));
$date->sub($oneMonth);
var_dump($date->format($format));
}
There are 31 days between 2013-11-12 and 2013-10-12 and PHP calculates the month subtraction correctly as can be seen here.
$date = new \DateTime('2013-11-12 00:00:01');
var_dump($date);
$interval = new DateInterval('P1M');
$date->sub($interval);
var_dump($date);
In your particular case 2013-10-31 - 1 month is 2013-09-31 which does not exist. Any date/time function needs to return a valid date, which 2013-09-31 is not.
In this case PHP, as I stated above, seems to add 31 days to the start of the previous month to arrive at a valid date.
Once you know the expected behaviour, you can program accordingly. If the current behaviour does not fit your use case then you could extend the DateTime class to provide behaviour that works for you.
I have assumed that strtotime and DateTime::sub() behave the same, this test suggests they do.
$thirtyOnedayMonths = array(
1, 3, 5, 7, 8, 10, 12
);
$format = 'Y-m-d';
foreach($thirtyOnedayMonths as $month){
$date = date($format, strtotime('-1 month', strtotime("2013-{$month}-31 00:00:01")));
var_dump($date);
}

add day to current date

add a day to date, so I can store tomorrow's date in a variable.
$tomorrow = date("Y-m-d")+86400;
I forgot.
date returns a string, whereas you want to be adding 86400 seconds to the timestamp. I think you're looking for this:
$tomorrow = date("Y-m-d", time() + 86400);
I'd encourage you to explore the PHP 5.3 DateTime class. It makes dates and times far easier to work with:
$tomorrow = new DateTime('tomorrow');
// e.g. echo 2010-10-13
echo $tomorrow->format('d-m-Y');
Furthermore, you can use the + 1 day syntax with any date:
$xmasDay = new DateTime('2010-12-24 + 1 day');
echo $xmasDay->format('Y-m-d'); // 2010-12-25
date() returns a string, so adding an integer to it is no good.
First build your tomorrow timestamp, using strtotime to be not only clean but more accurate (see Pekka's comment):
$tomorrow_timestamp = strtotime("+ 1 day");
Then, use it as the second argument for your date call:
$tomorrow_date = date("Y-m-d", $tomorrow_timestamp);
Or, if you're in a super-compact mood, that can all be pushed down into
$tomorrow = date("Y-m-d", strtotime("+ 1 day"));
Nice and obvious:
$tomorrow = strtotime('tomorrow');
You can use the add method datetime class.
Eg, you want to add one day to current date and time.
$today = new DateTime();
$today->add(new DateInterval('P1D'));
Further reference php datetime add
Hope this helps.
I find mktime() most useful for this sort of thing. E.g.:
$tomorrow=date("Y-m-d", mktime(0, 0, 0, date("m"), date("d")+1, date("Y")));

php get future date time

I don't know how to explain this correctly but just some sample for you guys so that you can really get what Im trying to say.
Today is April 09, 2010
7 days from now is April 16,2010
Im looking for a php code, which can give me the exact date giving the number of days interval prior to the current date.
I've been looking for a thread which can solve or even give a hint on how to solve this one but I found none.
If you are using PHP >= 5.2, I strongly suggest you use the new DateTime object, which makes working with dates a lot easier:
<?php
$date = new DateTime("2006-12-12");
$date->modify("+7 day");
echo $date->format("Y-m-d");
?>
Take a look here - http://php.net/manual/en/function.strtotime.php
<?php
// This is what you need for future date from now.
echo date('Y-m-d H:i:s', strtotime("+7 day"));
// This is what you need for future date from specific date.
echo date('Y-m-d H:i:s', strtotime('01/01/2010 +7 day'));
?>
The accepted answer is not wrong but not the best solution:
The DateTime class takes an optional string in the constructor, which can define the same logic as the modify method.
<?php
$date = new DateTime("+7 day");
For example:
<?php
namespace DateTimeExample;
$now = new \DateTime("now");
$inOneWeek = new \DateTime("+7 day");
printf("Now it's the %s", $now->format('Y-m-d'));
printf("In one week it's the %s", $inOneWeek->format('Y-m-d'));
For a list of available relative formats (for the DateTime constructor) take a look at http://php.net/manual/de/datetime.formats.relative.php
If you are using PHP >= 5.3, this could be an option.
<?php
$date = new DateTime( "2006-12-12" );
$date->add( new DateInterval( "P7D" ) );
?>
You will have to look into strtotime(). I'd imagine your final code would look something like this:
$future_date = "April 16,2010";
$seconds = strtotime($future_date) - time();
$days = $seconds /(60 * 60* 24);
echo $days; //Returns "6.0212962962963"
You can use mktime with date. (http://php.net/manual/en/function.date.php)
Date gives you the current date. This is better than simply adding/subtracting to a timestamp since it can take into account daylight savings time.
<?php
# this gets you 7 days earlier than the current date
$lastWeek = mktime(0, 0, 0, date("m") , date("d")-7, date("Y"));
# now pretty-print it out (eg, prints April 2, 2010.)
echo date("F j, Y.", $lastWeek), "\n";
?>

Categories