'Find difference between two datetimes and format at Y-m-d H:i:s
I'm trying to get the difference between two datetimes and return it as a datetime
. I've found examples using diff
but I can't seem to get it right.
$timein = date("Y-m-d H:i:s");
$timeout = date("Y-m-d 20:00:00");
$totaltime = $timein->diff($timeout);
However $totaltime
logs 0000-00-00 00:00:00
to my DB. Is this because I'm not formatting my totaltime variable?
Solution 1:[1]
I'm not sure what format you're looking for in your difference but here's how to do it using DateTime
$datetime1 = new DateTime();
$datetime2 = new DateTime('2011-01-03 17:13:00');
$interval = $datetime1->diff($datetime2);
$elapsed = $interval->format('%y years %m months %a days %h hours %i minutes %s seconds');
echo $elapsed;
Solution 2:[2]
You can simply use datetime diff and format for calculating difference.
<?php
$datetime1 = new DateTime('2009-10-11 12:12:00');
$datetime2 = new DateTime('2009-10-13 10:12:00');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%Y-%m-%d %H:%i:%s');
?>
For more information OF DATETIME format, refer: here
You can change the interval format in the way,you want.
Here is the working example
P.S. These features( diff() and format()) work with >=PHP 5.3.0 only
Solution 3:[3]
John Conde does all the right procedures in his method but doesn't satisfy the final step in your question which is to format the result to your specifications. printf()
or sprintf()
(depending on your usage) is an elegant way to format the integers with the desired leading zeros -- the DateTime class's format()
method does not allow leading zeros to be applied.
The demo below will display the raw difference, expose the trouble with trying to immediately format the raw difference, and present the correctly formatted result.
Code: (Demo)
$datetime1 = new DateTime('2017-04-26 18:13:06');
$datetime2 = new DateTime('2011-01-17 17:13:00'); // change the millennium to see output difference
$diff = $datetime1->diff($datetime2);
// this will get you very close, but it will not pad the digits to conform with your expected format
echo "Raw Difference: " . $diff->format('%y years %m months %d days %h hours %i minutes %s seconds') . "\n";
// Notice the impact when you change $datetime2's millennium from '1' to '2'
echo "Invalid format: " . $diff->format('%Y-%m-%d %H:%i:%s') . "\n"; // only H does it right
// isolated datetime diff values
$details = array_intersect_key((array)$diff,array_flip(['y','m','d','h','i','s']));
echo '$diff = ' . var_export($details, true) . "\n";
// now all components of datetime are properly padded
printf(
"Valid format: %04d-%02d-%02d %02d:%02d:%02d",
$diff->y,
$diff->m,
$diff->d,
$diff->h,
$diff->i,
$diff->s
);
Output:
Raw Difference: 6 years 3 months 9 days 1 hours 0 minutes 6 seconds
Invalid format: 06-3-9 01:0:6
$diff = array (
'y' => 6,
'm' => 3,
'd' => 9,
'h' => 1,
'i' => 0,
's' => 6,
)
Valid format: 0006-03-09 01:00:06
Solution 4:[4]
The code below will show difference for found values only, i.e., if years = 0, then it will not show years.
$diffs = [
'years' => 'y',
'months' => 'm',
'days' => 'd',
'hours' => 'h',
'minutes' => 'i',
'seconds' => 's'
];
$interval = $timeout->diff($timein);
$diffArr = [];
foreach ($diffs as $k => $v) {
$d = $interval->format('%' . $v);
if ($d > 0) {
$diffArr[] = $d . ' ' . $k;
}
}
$diffStr = implode(', ', $diffArr);
echo 'Difference: ' . ($diffStr == '' ? '0' : $diffStr) . PHP_EOL;
Solution 5:[5]
Sorry my previous answer was wrong. If you are trying to take total elapsed time between time and timeout in the Y-m-d H:i:s
format, take diff between timeout and time in using DateTime
object and format it as '%y-%m-%d %H:%i:%s'.
Solution 6:[6]
I collected many topics to make universal function with many outputs (years, months, days, hours, minutes, seconds) with string or parse to int and direction +- if you need to know what side is direction of the difference.
Use example:
$date1='2016-05-27 02:00:00';
$format='Y-m-d H:i:s';
echo timeDifference($date1, $format, '2017-08-30 00:01:59', $format);
#1 years 3 months 2 days 22 hours 1 minutes 59 seconds (string)
echo timeDifference($date1, $format, '2017-08-30 00:01:59', $format,false, '%a days %h hours');
#459 days 22 hours (string)
echo timeDifference('2016-05-27 00:00:00', $format, '2017-08-30 00:01:59', $format,true, '%d days -> %H:%I:%S', true);
#-3 days -> 00:01:59 (string)
echo timeDifference($date1, $format, '2016-05-27 00:05:51', $format, false, 'seconds');
#9 (string)
echo timeDifference($date1, $format, '2016-05-27 07:00:00', $format, false, 'hours');
#5 (string)
echo timeDifference($date1, $format, '2016-05-27 07:00:00', $format, true, 'hours');
#-5 (string)
echo timeDifference($date1, $format, '2016-05-27 07:00:00', $format, true, 'hours',true);
#-5 (int)
Function
function timeDifference($date1_pm_checked, $date1_format,$date2, $date2_format, $plus_minus=false, $return='all', $parseInt=false)
{
$strtotime1=strtotime($date1_pm_checked);
$strtotime2=strtotime($date2);
$date1 = new DateTime(date($date1_format, $strtotime1));
$date2 = new DateTime(date($date2_format, $strtotime2));
$interval=$date1->diff($date2);
$plus_minus=(empty($plus_minus)) ? '' : ( ($strtotime1 > $strtotime2) ? '+' : '-'); # +/-/no_sign before value
switch($return)
{
case 'y';
case 'year';
case 'years';
$elapsed = $interval->format($plus_minus.'%y');
break;
case 'm';
case 'month';
case 'months';
$elapsed = $interval->format($plus_minus.'%m');
break;
case 'a';
case 'day';
case 'days';
$elapsed = $interval->format($plus_minus.'%a');
break;
case 'd';
$elapsed = $interval->format($plus_minus.'%d');
break;
case 'h';
case 'hour';
case 'hours';
$elapsed = $interval->format($plus_minus.'%h');
break;
case 'i';
case 'minute';
case 'minutes';
$elapsed = $interval->format($plus_minus.'%i');
break;
case 's';
case 'second';
case 'seconds';
$elapsed = $interval->format($plus_minus.'%s');
break;
case 'all':
$parseInt=false;
$elapsed = $plus_minus.$interval->format('%y years %m months %d days %h hours %i minutes %s seconds');
break;
default:
$parseInt=false;
$elapsed = $plus_minus.$interval->format($return);
}
if($parseInt)
return (int) $elapsed;
else
return $elapsed;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mickmackusa |
Solution 2 | heena Jethva |
Solution 3 | |
Solution 4 | wesamly |
Solution 5 | Dhia Djobbi |
Solution 6 | Lesenus |