I'm totalling up time like so.
$totalTimeDiff = new DateTime("#0");
foreach($dbrecords as $row)
{
$timeDiff = date_diff( ... two datetimes from my database ... )
$totalTimeDiff->add($timeDiff);
}
So $totalTimeDiff is a DateTime object with the sum of all of the time differences added together (so a sum of all of the durations). How can I get the total time in seconds?
Why not keep it simple?
$totalseconds=0;
foreach($dbrecords as $row)
$totalseconds+=(UNIX_TIMESTAMP(second_datetime)-UNIX_TIMESTAMP(first_datetime));
use strtotime function
echo strtotime('01:00:00') - strtotime('TODAY');
$totalTimeDiff->format('U');
Taking moonwave99's advice, I used DateInterval (can't remember why I went with DateTime for that in the first place, possibly a workaround for something at another stage of the project) and computed the seconds by adding each value to the total after converting it to seconds (converting hours and minutes to seconds and summing them up). I did this by using the DateInterval class's seconds property as well as the following function to convert a DateInterval to seconds (Note: only accounted for days, hours, minutes, and seconds for my specific case as there's no chance the amount will exceed one month):
function convertDateIntervalToSeconds($dateInterval)
{
$days = $dateInterval->d * 24 * 60 * 60;
$hours = $dateInterval->h * 60 * 60;
$minutes = $dateInterval->i * 60;
$seconds = $dateInterval->s;
return $hours + $minutes + $seconds;
}
Related
so, I substract two dates:
$d = $start->diff($end);
and now I want to get the date in seconds (not the second parameter). I know it can be done with a native Php function - but it only works above 1970. I know I have to somehow operate with format() method, but I dont get it...
You could access the public properties of the DateInterval class and do some math on it:
$seconds = $d->s + ($d->i * 60) + ($d->h * 3600) + ($d->d * 86400) + ($d->m * 2592000); // and so on
but once we get into the months there will be variance by +/- 2 days unless we stick to an arbitrary definition of a month as 2592000 secs (30 days).
You can also use the difference of the two UNIX timestamps from the DateTime objects (but you will end up having problems with the dates being less than year of 1970):
$seconds = $end->getTimestamp() - $start->getTimestamp();
The following seems to work, although I feel there should be a better way.
$dateIntrvl = $start->diff($end);
$days = $dateIntrvl->format('%a');
$hours = $dateIntrvl->format('%h');
$mins = $dateIntrvl->format('%i');
$secs = $dateIntrvl->format('%s');
$totalSeconds = ($days * 24 * 60 * 60) + ($hours * 60 * 60) + ($mins * 60) + $secs;
And yes, it seems to be working for dates earlier than 1970.
How about using a class DateTime / DateTimeImmutable to create current DateTime instance, then add your DateInterval $d by using the add() method, and then using the getTimestamp() method.
(new \DateTimeImmutable())->add($d)->getTimestamp()
To get number of seconds from now, just subtract time().
(new \DateTimeImmutable())->add($d)->getTimestamp() - \time()
I have a time calculations problem in getting average.
I have this summed up call time 06:03:05 and I want to get an average with 175 calls.
date_default_timezone_set('America/Chicago');
$ts = strtotime("06:03:05");
echo date("H:i:s", $ts/175);
I get:
12:26:25
I'm not even sure why I come up with this very huge time average. Am I doing this right? Please help.
The problem there is that your strtotime call, not having a date component, is defaulting to the current date. So the $ts is a much much larger number than just the sum of the time parts; it includes the date parts as well.
I would avoid using the time functions like that. It's simple enough to calculate the number of seconds based on the hours, minutes and seconds. Once you have that, you can use date() to echo the formatted time like you do there.
Try something more like this:
function getTimeAverage($hours, $minutes, $seconds, $division) {
$seconds += ($hours * 3600) + ($minutes * 60);
return $seconds / $division;
}
$average = getTimeAverage(6, 3, 5, 175);
echo gmdate("H:i:s", $average);
One easy way which only works up to 24 hours. Else take Atlis approach and search also for a way to convert seconds to date.
$time = '06:03:05';
$seconds = strtotime("1970-01-01 $time UTC");
$average = $seconds/175;
echo gmdate('H:i:s', $average);
I am trying to get the PHP "DateInterval" value in "total minutes" value. How to get it? Seems like simple format("%i minutes") not working?
Here is the sample code:
$test = new \DateTime("48 hours");
$interval = $test->diff(new \DateTime());
Now if I try to get the interval in total days, its fine:
echo $interval->format('%a total days');
It is showing 2 days as output, which is totally fine. What I am trying to get if to get the value in "total minutes", so I tried:
echo $interval->format('%i total minutes');
Which is not working. Any help appreciated to get my desired output.
abs((new \DateTime("48 hours"))->getTimestamp() - (new \DateTime)->getTimestamp()) / 60
That's the easiest way to get the difference in minutes between two DateTime instances.
If you are stuck in a position where all you have is the DateInterval, and you (like me) discover that there seems to be no way to get the total minutes, seconds or whatever of the interval, the solution is to create a DateTime at zero time, add the interval to it, and then get the resulting timestamp:
$timeInterval = //the DateInterval you have;
$intervalInSeconds = (new DateTime())->setTimeStamp(0)->add($timeInterval)->getTimeStamp();
$intervalInMinutes = $intervalInSeconds/60; // and so on
I wrote two functions that just calculates the totalTime from a DateInterval.
Accuracy can be increased by considering years and months.
function getTotalMinutes(DateInterval $int){
return ($int->d * 24 * 60) + ($int->h * 60) + $int->i;
}
function getTotalHours(DateInterval $int){
return ($int->d * 24) + $int->h + $int->i / 60;
}
Here is the excepted answer as a method in PHP7.2 style:
public static function getMinutesDifference(\DateTime $a, \DateTime $b): int
{
return abs($a->getTimestamp() - $b->getTimestamp()) / 60;
}
That works perfectly.
function calculateMinutes(DateInterval $int){
$days = $int->format('%a');
return ($days * 24 * 60) + ($int->h * 60) + $int->i;
}
This question is about minutes but if you want to recalculate every carry over points (like I needed to) you can use this solution suggested by #glavic in the comments on the php.net man page (simplified and turned into a function):
private function calculateCarryOverPoints(\DateInterval $dateInterval): \DateInterval
{
$from = new \DateTime;
$to = clone $from;
// Add time of dateInterval to empty DateTime object
$to = $to->add($dateInterval);
// Calculate difference between zero DateTime and DateTime with added DateInterval time
// Which returns a DateInterval object $diff with correct carry over points (days, hours, minutes, seconds etc.)
return $from->diff($to);
}
$datetime1 = date_create('2009-10-11');
$datetime2 = date_create('2009-10-13');
$interval = date_diff($datetime1, $datetime2);
How do i convert the above $interval to seconds in php
Another way to get the number of seconds in an interval is to add it to the zero date, and get the timestamp of that date:
$seconds = date_create('#0')->add($interval)->getTimestamp();
This method will handle intervals created via the DateInterval contructor more or less correctly, whereas shiplu's answer will ignore years, months and days for such intervals. However, shiplu's answer is more accurate for intervals that were created by subtracting two dates. For intervals consisting only of hours, minutes and seconds, both methods will get the correct answer.
There is a function format for this. But it wont return the number of seconds. To get number of seconds you use this technique
$seconds = abs($datetime1->getTimestamp()-$datetime2->getTimestamp());
If you really want to use $interval you need to calculate it.
$seconds = $interval->days*86400 + $interval->h*3600
+ $interval->i*60 + $interval->s;
Here
86400 is the number of seconds in a day
3600 is the number of seconds in an hour
60 is the number of seconds in a minute
I would only add to shiplu's answer:
function dateIntervalToSeconds($interval)
{
$seconds = $interval->days*86400 + $interval->h*3600
+ $interval->i*60 + $interval->s;
return $interval->invert == 1 ? $seconds*(-1) : $seconds;
}
To handle negative intervals.
Note that - contrary to Brilliand's answer - The code above will consider correctly years, months and dates. Because $interval->days is an absolute value ($interval->d is relative to the month).
EDIT: this function is still not correct, as pointed out by #Brilliand. A counter-example is
new DateInterval('P4M3DT2H');
It doesn't handle months well.
I need to find how much time is between to time values (their difference) which are over 24:00:00.
For example: how can I calculate the difference between 42:00:00 and 37:30:00?
Using strtotime, strptotime, etc is useless since they cannot go over 23:59:59 ....
$a_split = explode(":", "42:00:00");
$b_split = explode(":", "37:30:00");
$a_stamp = mktime($a_split[0], $a_split[1], $a_split[2]);
$b_stamp = mktime($b_split[0], $b_split[1], $b_split[2]);
if($a_stamp > $b_stamp)
{
$diff = $a_stamp - $b_stamp;
}else{
$diff = $b_stamp - $a_stamp;
}
echo "difference in time (seconds): " . $diff;
then use date() to convert seconds to HH:MM:SS if you want.
Date/Time variables and functions are not appropriate here as you're not storing time, but instead a time span of (I assume) hours, minutes, and seconds.
Likely your best solution is going to be to split each time span into their integer components, convert to a single unit (for instance, seconds), subtract them from each other, then re-build an output time span that fits with your application.
I havent tested this, but this might do what you want:
function timediff($time1, $time2) {
list($h,$m,$s) = explode(":",$time1);
$t1 = $h * 3600 + $m * 60 + $s;
list($h2,$m2,$s2) = explode(":",$time2);
$seconds = ($h2 * 3600 + $m2 * 60 + $s2) - $t1;
return sprintf("%02d:%02d:%02d",floor($seconds/3600),floor($seconds/60)%60,$seconds % 60);
}