gotchaphpModerate
Display the relative time difference between two dates
Viewed 0 times
thedatestimedifferencetwobetweendisplayrelative
Problem
Goal: To create a function that returns the relative time difference between two given timestamps, using the DateTime class.
Current approach:
As you can see, the function works fine. I'm currently using a couple of
Current approach:
function time_elapsed($date1, $date2) {
$dt1 = new DateTime($date1);
$dt2 = new DateTime($date2);
$diff = $dt1->diff($dt2);
$ret = $diff->format('%y years, %m months, %a days, %h hours, %i minutes, %S seconds');
$ret = str_replace(
array('0 years,',' 0 months,',' 0 days,',' 0 hours,', ' 0 minutes,'),
'',
$ret
);
$ret = str_replace(
array('1 years, ',' 1 months, ',' 1 days, ',' 1 hours, ',' 1 minutes'),
array('1 year, ','1 month, ',' 1 day, ',' 1 hour, ',' 1 minute'),
$ret
);
return $ret;
}As you can see, the function works fine. I'm currently using a couple of
str_replace() calls to remove the unnecessary parts from the formatted string, but I don't think that's a very good approach. I'm sure what I have written can be cleaned up and improved, using a different approach, perhaps.Solution
-
I guess you have a bug here:
prints total number of days:
Using
-
Another approach is iterating through of an array of units:
(In production code I'd use constants instead of
I guess you have a bug here:
$ret = $diff->format('%y years, %m months, %a days, %h hours, %i minutes, %S seconds');%a should be %d. With %atime_elapsed("2012-07-08 11:14:15.889342", "2014-09-10 13:15:17.889342");prints total number of days:
2 years, 2 months, 794 days, 2 hours, 1 minute, 02 secondsUsing
%d changes 794 days to 2 days.-
Another approach is iterating through of an array of units:
function time_elapsed2($start, $end) {
$start = new DateTime($start);
$end = new DateTime($end);
$interval = $end->diff($start);
$units = array(
"%y" => sp("year", "years"),
"%m" => sp("month", "months"),
"%d" => sp("day", "days"),
"%h" => sp("hour", "hours"),
"%i" => sp("minute", "minutes"),
"%s" => sp("second", "seconds")
);
$result = array();
foreach ($units as $format_char => $names) {
$formatted_value = $interval->format($format_char);
if ($formatted_value == "0") {
continue;
}
$result[] = get_formatted_string($formatted_value, $names);
}
return implode(", ", $result);
}
function sp($singular, $plural) {
return array("singular" => $singular, "plural" => $plural);
}
function get_formatted_string($formatted_value, $names) {
$result = $formatted_value . " ";
if ($formatted_value == "1") {
$result .= $names["singular"];
} else {
$result .= $names["plural"];
}
return $result;
}(In production code I'd use constants instead of
singular and plural.) The array also helps if you want to translate your page to other languages.Code Snippets
$ret = $diff->format('%y years, %m months, %a days, %h hours, %i minutes, %S seconds');time_elapsed("2012-07-08 11:14:15.889342", "2014-09-10 13:15:17.889342");2 years, 2 months, 794 days, 2 hours, 1 minute, 02 secondsfunction time_elapsed2($start, $end) {
$start = new DateTime($start);
$end = new DateTime($end);
$interval = $end->diff($start);
$units = array(
"%y" => sp("year", "years"),
"%m" => sp("month", "months"),
"%d" => sp("day", "days"),
"%h" => sp("hour", "hours"),
"%i" => sp("minute", "minutes"),
"%s" => sp("second", "seconds")
);
$result = array();
foreach ($units as $format_char => $names) {
$formatted_value = $interval->format($format_char);
if ($formatted_value == "0") {
continue;
}
$result[] = get_formatted_string($formatted_value, $names);
}
return implode(", ", $result);
}
function sp($singular, $plural) {
return array("singular" => $singular, "plural" => $plural);
}
function get_formatted_string($formatted_value, $names) {
$result = $formatted_value . " ";
if ($formatted_value == "1") {
$result .= $names["singular"];
} else {
$result .= $names["plural"];
}
return $result;
}Context
StackExchange Code Review Q#38154, answer score: 10
Revisions (0)
No revisions yet.