Doctrine2 subtract two datetimes - php

So in my database I got a datetime field, filled with e.g. 2012-09-19 11:20:33.
Now I'm trying to fetch the datetime.
$blabla = $something->getDatetime();
After that I create a new DateTime, which represents the time now
$now = new \DateTime("now");
And after that I want to subtract them like this (but it doesn't work)?
$test1 = strtotime($blabla);
$test2 = strtotime($now);
$diff = $test2 - $test1;
echo $diff;
My aim is to subtract the persisted datetime in the database from the time now...the result should be displayed in seconds...so 2012-09-19 11:22:22 - 2012-09-19 11:20:22 equals 120 (seconds).
I also tried to persist a unix timestamp into my database but unfortunately the field type timestamp doesn't exist.

If you want the answer displayed in seconds, then just subtract the timestamps:-
$blabla = $something->getDatetime();
$now = new DateTime();
$seconds = $now->getTimestamp() - $blabla->getTimestamp();

$blabla = $something->getDatetime();
$now = new \DateTime("now");
$diff = $now->diff($blabla);
Remember that $diff is a DateInterval object en you must use its methods and properties to get to the final desired result.

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

How to substract DateInterval from DateInterval?

I have two intervals:
$intervalFrom = DateInterval('12:00')
$intervalTo = DateInterval('1:30')
Output must be:
DateInterval('10:30')
I try
$newInterval = $intervalFrom->sub($intervalTo);
But It not work
You could create 2 times a DateInterval using PT12H and PT1H30M.
To get a difference, you could use the DateTime diff method.
Create 2 datetimes and pass 2 fixed starting points like "midnight" and for both of them add an interval.
Retrieve the number of hours h and minutes i and use those to create a new DateInterval:
$intervalFrom = new DateInterval('PT12H');
$intervalTo = new DateInterval('PT1H30M');
$d1 = new DateTime("midnight");
$d1->add($intervalFrom);
$d2 = new DateTime("midnight");
$d2->add($intervalTo);
$diff = $d1->diff($d2);
$strResult = sprintf("PT%sH%sM", $diff->h, $diff->i);
$resultDateInterval = new DateInterval($strResult);
Demo

Modify microseconds of a PHP DateTime object

I have a PHP DateTime object with microseconds created as follows:
$time = microtime(true);
$microseconds = sprintf('%06d', ($time - floor($time)) * 1000000);
$dt = new DateTime(date('Y-m-d H:i:s.' . $microseconds, $time));
How can I modify the microseconds value of $dt, without creating a completely new DateTime instance?
You can't.
There are three methods that can modify the value of a DateTime instance: add, sub and modify. We can rule out add and sub immediately because they work in terms of a DateInterval which does not have sub-second precision.
modify accepts a string in one of the standard recognized formats. Of those formats, only the relative ones are of interest here because the other ones work in an absolute manner; and there is no relative format that allows tweaking the msec part (that unit is not recognized).
as of PHP 7.1
DateTime::setTime() supports microseconds.
This seems to have been available since 7.1.0-rc4
$dt = new DateTime('2020-01-01 0:00');
$dt->modify('+500 ms'); // Milliseconds.
$dt->modify('+123456 usec'); // Microseconds.
$dt->modify('+123456 microseconds'); // This works too.
It's mentioned here in the manual.
Manually creating a DateTime object with micro seconds:
$d = new DateTime("15-07-2014 18:30:00.111111");
Getting a DateTime object of the current time with microseconds:
$d = date_format(new DateTime(),'d-m-Y H:i:s').substr((string)microtime(), 1, 8);
Difference between two DateTime objects in microseconds (e.g. returns: 2.218939)
//Returns the difference, in seconds, between two datetime objects including
//the microseconds:
function mdiff($date1, $date2){
$date1sec = strtotime($date1->format('d-m-Y H:i:s.u'));
$date2sec = strtotime($date2->format('d-m-Y H:i:s.u'));
//Absolute val of Date 1 in seconds from (EPOCH Time) - Date 2 in seconds from (EPOCH Time)
$secdiff = abs($date1sec-$date2sec);
//Creates variables for the microseconds of date1 and date2
$micro1 = $date1->format("u");
$micro2 = $date2->format("u");
if (($date1sec<$date2sec && $micro1>$micro2)||($date1sec>$date2sec && $micro1<$micro2)){
$microdiff = abs(1000000 - abs($micro1-$micro2));
$secdiff = $secdiff - 1;
} else {
$microdiff = abs($micro1 - $micro2);
}
//Creates the variable that will hold the seconds (?):
$difference = $secdiff.".".$microdiff;
return $difference;
}
Essentially it finds the difference for the DateTime Objects using strtotime and then adding the extra microseconds on.
Do you need me to create add and sub?
i had a similar problem and ended up having to wrap the whole thing
https://gist.github.com/chandeeland/9817516
For the people only in need to zero-out microseconds (I had to because of database layer) here's the snippet I ended up using:
$format = "Y-m-d H:i:s e";
$now = (new \DateTime())->format($format);
$dateTime = \DateTime::createFromFormat($format, $now);
Note that using $format = 'c', ISO 8601, will not work, as explained here (https://stackoverflow.com/a/10478469/8119317).

Check interval between datetimes in PHP

I have a field in database that has type of datetime in which I add time when user visit a page. When user again comes I want to check the interval between his first visit and current. If it is less or equal to 1 hour then I want to show him some message.
I store time like this
2011-03-04 00:25:01
The thing that I want to ask that how to check the interval in PHP
You could try
SELECT COUNT(#UserID) FROM table WHERE LastVisit > (DateADD(now(),interval -1 Hour))
you can then check the count
Edit: added FROM clause
If you have PHP >= 5.3 you can use DateTime objects and functions:
$visit = DateTime::createFromFormat('Y-m-d H:i:s', '2011-03-04 00:25:01');
$now = new DateTime("now");
$diff = $now->diff($visit);
What you can so is, retrieve the the datetime, store it in a variable.
Create a var with time().
You can then convert the db datetime to a timestring using strtotime()
Subtract the datetime timestring from the new time. That should give you a difference in seconds. You can then manipulate your values and do the relevant checks.
$db = datetime_from_database;
$now = time();
$last = strtotime($db);
$diff = $now - $last; //this is in seconds
You can do something like
$minutes = $diff / 60;
If ($minutes > 60) echo 'more than 1 hour; 60 minutes';
Just work in it.
You can then use the date functions to format the new datetime using the $now and update the database.

How to get millisecond between two dateTime obj?

How to get millisecond between two DateTime objects?
$date = new DateTime();
$date2 = new DateTime("1990-08-07 08:44");
I tried to follow the comment below, but I got an error.
$stime = new DateTime($startTime->format("d-m-Y H:i:s"));
$etime = new DateTime($endTime->format("d-m-Y H:i:s"));
$millisec = $etime->getTimestamp() - $stime->getTimestamp();`
I get the error
Call to undefined method DateTime::getTimestamp()
In the strict sense, you can't.
It's because the smallest unit of time for the DateTime class is a second.
If you need a measurement containing milliseconds then use microtime()
Edit:
On the other hand if you simply want to get the interval in milliseconds between two ISO-8601 datetimes then one possible solution would be
function millisecsBetween($dateOne, $dateTwo, $abs = true) {
$func = $abs ? 'abs' : 'intval';
return $func(strtotime($dateOne) - strtotime($dateTwo)) * 1000;
}
Beware that by default the above function returns absolute difference. If you want to know whether the first date is earlier or not then set the third argument to false.
// Outputs 60000
echo millisecsBetween("2010-10-26 20:30", "2010-10-26 20:31");
// Outputs -60000 indicating that the first argument is an earlier date
echo millisecsBetween("2010-10-26 20:30", "2010-10-26 20:31", false);
On systems where the size of time datatype is 32 bits, such as Windows7 or earlier, millisecsBetween is only good for dates between 1970-01-01 00:00:00 and 2038-01-19 03:14:07 (see Year 2038 problem).
Sorry to digg out an old question, but I've found a way to get the milliseconds timestamp out of a DateTime object:
function dateTimeToMilliseconds(\DateTime $dateTime)
{
$secs = $dateTime->getTimestamp(); // Gets the seconds
$millisecs = $secs*1000; // Converted to milliseconds
$millisecs += $dateTime->format("u")/1000; // Microseconds converted to seconds
return $millisecs;
}
It requires however that your DateTime object contains the microseconds (u in the format):
$date_str = "20:46:00.588";
$date = DateTime::createFromFormat("H:i:s.u", $date_str);
This is working only since PHP 5.2 hence the microseconds support to DateTime has been added then.
With this function, your code would become the following :
$date_str = "1990-08-07 20:46:00.588";
$date1 = DateTime::createFromFormat("Y-m-d H:i:s.u", $date_str);
$msNow = (int)microtime(true)*1000;
echo $msNow - dateTimeToMilliseconds($date1);
DateTime supports microseconds since 5.2.2. This is mentioned in the documentation for the date function, but bears repeating here. You can create a DateTime with fractional seconds and retrieve that value using the 'u' format string.
<?php
// Instantiate a DateTime with microseconds.
$d = new DateTime('2011-01-01T15:03:01.012345Z');
// Output the microseconds.
echo $d->format('u'); // 012345
// Output the date with microseconds.
echo $d->format('Y-m-d\TH:i:s.u'); // 2011-01-01T15:03:01.012345
// Unix Format
echo "<br>d2: ". $d->format('U.u');
function get_data_unix_ms($data){
$d = new DateTime($data);
$new_data = $d->format('U.u');
return $new_data;
}
function get_date_diff_ms($date1, $date2)
{
$d1 = new DateTime($date1);
$new_d1 = $d1->format('U.u');
$d2 = new DateTime($date2);
$new_d2 = $d2->format('U.u');
$diff = abs($new_d1 - $new_d2);
return $diff;
}
https://www.php.net/manual/en/class.datetime.php
Here's a function to do that + tests.
https://gist.github.com/vudaltsov/0bb623b9e2817d6ce359eb88cfbf229d
DateTime dates are only stored as whole seconds. If you still need the number of milliseconds between two DateTime dates, then you can use getTimestamp() to get each time in seconds (then get the difference and turn it into milliseconds):
$seconds_diff = $date2.getTimestamp() - $date.getTimestamp()
$milliseconds_diff = $seconds_diff * 1000

Categories