public function DateFormatter::formatDiff in Drupal 10
Same name and namespace in other branches
- 8 core/lib/Drupal/Core/Datetime/DateFormatter.php \Drupal\Core\Datetime\DateFormatter::formatDiff()
- 9 core/lib/Drupal/Core/Datetime/DateFormatter.php \Drupal\Core\Datetime\DateFormatter::formatDiff()
File
- core/
lib/ Drupal/ Core/ Datetime/ DateFormatter.php, line 202
Class
- DateFormatter
- Provides a service to handle various date related functionality.
Namespace
Drupal\Core\DatetimeCode
public function formatDiff($from, $to, $options = []) {
$options += [
'granularity' => 2,
'langcode' => NULL,
'strict' => TRUE,
'return_as_object' => FALSE,
];
if ($options['strict'] && $from > $to) {
$string = $this
->t('0 seconds');
if ($options['return_as_object']) {
return new FormattedDateDiff($string, 0);
}
return $string;
}
$date_time_from = new \DateTime();
$date_time_from
->setTimestamp($from);
$date_time_to = new \DateTime();
$date_time_to
->setTimestamp($to);
$interval = $date_time_to
->diff($date_time_from);
$granularity = $options['granularity'];
$output = '';
// We loop over the keys provided by \DateInterval explicitly. Since we
// don't take the "invert" property into account, the resulting output value
// will always be positive.
$max_age = 1.0E+99;
foreach ([
'y',
'm',
'd',
'h',
'i',
's',
] as $value) {
if ($interval->{$value} > 0) {
// Switch over the keys to call formatPlural() explicitly with literal
// strings for all different possibilities.
switch ($value) {
case 'y':
$interval_output = $this
->formatPlural($interval->y, '1 year', '@count years', [], [
'langcode' => $options['langcode'],
]);
$max_age = min($max_age, 365 * 86400);
break;
case 'm':
$interval_output = $this
->formatPlural($interval->m, '1 month', '@count months', [], [
'langcode' => $options['langcode'],
]);
$max_age = min($max_age, 30 * 86400);
break;
case 'd':
// \DateInterval doesn't support weeks, so we need to calculate them
// ourselves.
$interval_output = '';
$days = $interval->d;
$weeks = floor($days / 7);
if ($weeks) {
$interval_output .= $this
->formatPlural($weeks, '1 week', '@count weeks', [], [
'langcode' => $options['langcode'],
]);
$days -= $weeks * 7;
$granularity--;
$max_age = min($max_age, 7 * 86400);
}
if ((!$output || $weeks > 0) && $granularity > 0 && $days > 0) {
$interval_output .= ($interval_output ? ' ' : '') . $this
->formatPlural($days, '1 day', '@count days', [], [
'langcode' => $options['langcode'],
]);
$max_age = min($max_age, 86400);
}
else {
// If we did not output days, set the granularity to 0 so that we
// will not output hours and get things like "1 week 1 hour".
$granularity = 0;
}
break;
case 'h':
$interval_output = $this
->formatPlural($interval->h, '1 hour', '@count hours', [], [
'langcode' => $options['langcode'],
]);
$max_age = min($max_age, 3600);
break;
case 'i':
$interval_output = $this
->formatPlural($interval->i, '1 minute', '@count minutes', [], [
'langcode' => $options['langcode'],
]);
$max_age = min($max_age, 60);
break;
case 's':
$interval_output = $this
->formatPlural($interval->s, '1 second', '@count seconds', [], [
'langcode' => $options['langcode'],
]);
$max_age = min($max_age, 1);
break;
}
$output .= ($output && $interval_output ? ' ' : '') . $interval_output;
$granularity--;
}
elseif ($output) {
// Break if there was previous output but not any output at this level,
// to avoid skipping levels and getting output like "1 year 1 second".
break;
}
if ($granularity <= 0) {
break;
}
}
if (empty($output)) {
$output = $this
->t('0 seconds');
$max_age = 0;
}
if ($options['return_as_object']) {
return new FormattedDateDiff($output, $max_age);
}
return $output;
}