How to get the timestamp + X minutes with DateTime and DateInterval - php

I want to get the timestamp in 15 minutes from now.
I don't want to use strtotime, I want to use DateTime and DateInterval.
I'm doing:
$now = new DateTime('now');
$in_15_m = $now->add(new DateInterval('PT15M'));
echo 'Now:' . $now->format('Y-m-d\TH:i:s\Z');
echo 'In 15 min': . $in_15_m->format('Y-m-d\TH:i:s\Z');
But both printed lines contain the same date.
How can I achieve this?
The arguments for DateInterval aren't really clear in the docs, though I think I am using it the correct way.
Thanks.

The DateTime::add method modifies the DateTime object in place. It also returns the modified object for use in method chaining, but the original object is still modified.
You can use DateTimeImmutable instead:
$now = new DateTimeImmutable('now');
$in_15_m = $now->add(new DateInterval('PT15M'));
echo 'Now:' . $now->format('Y-m-d\TH:i:s\Z');
echo "\n+15m:" . $in_15_m->format('Y-m-d\TH:i:s\Z');
Or, alternatively, use two objects:
$now = new DateTime('now');
$in_15_m = (new DateTime('now'))->add(new DateInterval('PT15M'));
echo 'Now:' . $now->format('Y-m-d\TH:i:s\Z');
echo "\n+15m:" . $in_15_m->format('Y-m-d\TH:i:s\Z');

Related

How to correctly add a date and a time (string) in PHP?

What is the "cleanest" way to add a date and a time string in PHP?
Albeit having read that DateTime::add expects a DateInterval, I tried
$date = new \DateTime('17.03.2016');
$time = new \DateTime('20:20');
$result = $date->add($time);
Which was no good and returned nothing to $result.
To make a DateInterval from '20:20', I only found very complex solutions...
Maybe I should use timestamps?
$date = strtotime($datestring);
$timeObj = new \DateTime($timestring);
// quirk to only get time in seconds from string date
$time = $timeObj->format('H') * 3600 + $timeObj->format('i') * 60 + $timeObj->format('s');
$datetime = $date+$time;
$result = new \DateTime;
$result->setTimestamp($datetime);
In my case, this returns the desired result, with the correct timezone offset. But what do you think, is this robust? Is there a better way?
If you want to add 20 hours and 20 minutes to a DateTime:
$date = new \DateTime('17.03.2016');
$date->add($new \DateInterval('PT20H20M'));
You do not need to get the result of add(), calling add() on a DateTime object will change it. The return value of add() is the DateTime object itself so you can chain methods.
See DateInterval::__construct to see how to set the intervals.
DateTime (and DateTimeImmutable) has a modify method which you could leverage to modify the time by adding 20 hours and 20 minutes.
Updated
I've included examples for both DateTime and DateTimeImmutable as per the comment made, you don't need to assign the outcome of modify to a variable because it mutates the original object. Whereas DateTimeImmutable creates a new instance and doesn't mutate the original object.
DateTime
<?php
$start = new DateTimeImmutable('2018-10-23 00:00:00');
echo $start->modify('+20 hours +20 minutes')->format('Y-m-d H:i:s');
// 2018-10-23 20:20:00
Using DateTime: https://3v4l.org/6eon8
DateTimeImmutable
<?php
$start = new DateTimeImmutable('2018-10-23 00:00:00');
$datetime = $start->modify('+20 hours +20 minutes');
var_dump($start->format('Y-m-d H:i:s'));
var_dump($datetime->format('Y-m-d H:i:s'));
Output
string(19) "2018-10-23 00:00:00"
string(19) "2018-10-23 20:20:00"
Using DateTimeImmutable: https://3v4l.org/oRehh

time calculation issue with format php

I'm having trouble calculating the number of hours worked.
We start with a time which starts as a string in this case ($time).
Then we change the time to 00:00:00 and store the result as a new variable ($newtime).
Then we need to calculate the difference between $time and $newtime but there is a formatting issue which I do not fully understand. Would anyone help?
$time = "2017-09-01 11:00:00"; //must start as a string like this
$newtime = new DateTime($time);
$newtime->setTime(00, 00,00); //change time to 00:00:00
$worktime = round((strtotime($time) - $newtime)/3600, 2);
echo "Hours Worked: " . $worktime . "<br>";
You're subtracting a timestamp with a DateTime object, so it tries to convert the DateTime object to an int, which it can't. You need to get the timestamp for the DateTime object, to subtract two ints:
<?php
$time = "2017-09-01 11:00:00"; //must start as a string like this
$newtime = new DateTime($time);
$newtime->setTime(00, 00,00); //change time to 00:00:00
$worktime = round((strtotime($time) - $newtime->getTimestamp())/3600, 2); // notice the $newtime->getTimestamp() call
echo "Hours Worked: " . $worktime . "<br>";
Demo
DateTime::getTimestamp() reference
You are mixing types (trying to cast object to int)... And maybe you didn't realize about the error you are making because you have disabled errors.
Please use, the method that Datetime class brings to you:
http://php.net/manual/es/datetime.gettimestamp.php
You can do it in both ways:
$newtime->getTimestamp()
or by using this:
date_timestamp_get($newtime)
As this:
$time = "2017-09-01 11:00:00"; //must start as a string like this
$newtime = new DateTime($time);
$newtime->setTime(00, 00,00); //change time to 00:00:00
$worktime = round((strtotime($time) - date_timestamp_get($newtime))/3600, 2);
echo "Hours Worked: " . $worktime . "<br>";
Please, be free of using this: http://sandbox.onlinephpfunctions.com/code/f78c993f709a67ac2770d78bb809e68e3a679707

How to retrieve the number of days from a PHP date interval?

I am trying to retrieve the number of days for a PHP interval. When I run the following piece of code on http://sandbox.onlinephpfunctions.com/:
$duration = new \DateInterval('P1Y');
echo $duration->format('%a');
echo "Done";
I get:
(unknown)Done
What am I doing wrong?
The '%a' will return the number of days only when you take a time difference otherwise it will return unknown.
You can use '%d' to get the days but it will also return 0 in the case of new \DateInterval('P1Y') as it does not convert years to days.
One easy way to get the number of days is to create a DateTime at zero time, add the interval to it, and then get the resulting timestamp:
<?php
$duration = new \DateInterval('P1Y');
$intervalInSeconds = (new DateTime())->setTimeStamp(0)->add($duration)->getTimeStamp();
$intervalInDays = $intervalInSeconds/86400;
echo $intervalInDays;
echo " Done";
The problem is here:
$duration->format('%a');
As the manual says, "Total number of days as a result of a DateTime::diff() or (unknown) otherwise".
You need a valid dateInterval object returned by DateTime's diff() method to make the "a" parameter work with DateInterval::format() function:
$now = new DateTime(date('Y-m-d H:i:s'));
$duration = (new DateTime("+1 year"))->diff($now);
echo $duration->format('%a');
Looks like if the DateInterval object is not created by DateTime::diff(), it won't work.
Hope it helps.
You have to create the interval with real dates:
<?php
$interval = date_diff(new DateTime, new DateTime('+1 year'));
echo $interval->format('%a'), PHP_EOL; // 365
if you want something aware of the year or month context, use this, february will return 28 days, leap years will have their additional day
function interval2days($day, $interval) {
$date = clone $day;
$start = $date->getTimeStamp();
$end = $date->add($interval)->getTimeStamp();
return ($end-$start)/86400;
}

Change seconds duration to ISO 8601 format

How can I convert
00:00:46.70
to
T0M46S
I try
$date = new DateTime($time); echo $date->format('\P\TG\Hi\M');
but it gives me something like this:
PT0H00M
Note I want duration... not date!
There is no native function, but you can do it with native object DateTime : calculate the duration from midnight to your time.
<?php
$time = new DateTime('00:00:46.70');
$midnight = new DateTime('00:00:00.00');
$period = $midnight->diff($time);
echo $period->format('T%iM%SS'); //output T0M46S
print_r($period);
Here is a php sandbox to test it
Carbon has the solution
function secondsToISO8601Format(int $seconds): string
{
return Carbon\CarbonInterval::seconds($seconds)->cascade()->spec();
}

Carbon subtracting Datetime from Carbon::now()

I want to use this Carbon function:
Carbon::now()->subDays(5)->diffForHumans()
And I need to create the correct integer.
I am loading a string with a Datetime, which I want to subtract in Laravel like this:
$datetime = $score->created_at;
Then I save the current Time into a variable
$now = Carbon::now()->toDateTimeString();
This is what I get:
echo $now . '<br>'; // 2014-07-13 22:53:03
echo $datetime; // 2014-07-12 14:32:17
But when I want to subtract one from another I get the following error:
echo $now - $datetime;
Object of class Carbon\Carbon could not be converted to int
Any help here would be greatly apreciated.
I know it's a bit late, but this works:
$score->created_at->diffForHumans(\Carbon\Carbon::now())
If you want to change the date format just use the format function
$now = Carbon::now();
$score->created_at->diffForHumans($now)->format('Y-m-d');

Categories