Same name and namespace in other branches
  1. 8.9.x core/lib/Drupal/Core/Datetime/DateFormatter.php \Drupal\Core\Datetime\DateFormatter::formatDiff()
  2. 9 core/lib/Drupal/Core/Datetime/DateFormatter.php \Drupal\Core\Datetime\DateFormatter::formatDiff()
2 calls to DateFormatter::formatDiff()
DateFormatter::formatTimeDiffSince in core/lib/Drupal/Core/Datetime/DateFormatter.php
DateFormatter::formatTimeDiffUntil in core/lib/Drupal/Core/Datetime/DateFormatter.php

File

core/lib/Drupal/Core/Datetime/DateFormatter.php, line 203

Class

DateFormatter
Provides a service to handle various date related functionality.

Namespace

Drupal\Core\Datetime

Code

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, '@count year', '@count years', [], [
            'langcode' => $options['langcode'],
          ]);
          $max_age = min($max_age, 365 * 86400);
          break;
        case 'm':
          $interval_output = $this
            ->formatPlural($interval->m, '@count 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, '@count 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, '@count 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 "@count week @count hour".
            $granularity = 0;
          }
          break;
        case 'h':
          $interval_output = $this
            ->formatPlural($interval->h, '@count hour', '@count hours', [], [
            'langcode' => $options['langcode'],
          ]);
          $max_age = min($max_age, 3600);
          break;
        case 'i':
          $interval_output = $this
            ->formatPlural($interval->i, '@count minute', '@count minutes', [], [
            'langcode' => $options['langcode'],
          ]);
          $max_age = min($max_age, 60);
          break;
        case 's':
          $interval_output = $this
            ->formatPlural($interval->s, '@count 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 "@count year @count 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;
}