public function DateFormatter::formatDiff

public DateFormatter::formatDiff($from, $to, $options = array())

Formats a time interval between two timestamps.

Parameters

int $from: A UNIX timestamp, defining the from date and time.

int $to: A UNIX timestamp, defining the to date and time.

array $options: (optional) An associative array with additional options. The following keys can be used:

  • granularity: An integer value that signals how many different units to display in the string. Defaults to 2.
  • langcode: The language code for the language used to format the date. Defaults to NULL, which results in the user interface language for the page being used.
  • strict: A Boolean value indicating whether or not the $from timestamp can be after the $to timestamp. If TRUE (default) and $from is after $to, the result string will be "0 seconds". If FALSE and $from is after $to, the result string will be the formatted time difference.
  • return_as_object: A Boolean value whether to return a FormattedDateDiff object.

Return value

string|\Drupal\Core\Datetime\FormattedDateDiff A translated string representation of the interval. This interval is always positive.

Overrides DateFormatterInterface::formatDiff

See also

\Drupal\Core\Datetime\DateFormatterInterface::formatInterval()

\Drupal\Core\Datetime\DateFormatterInterface::formatTimeDiffSince()

\Drupal\Core\Datetime\DateFormatterInterface::formatTimeDiffUntil()

File

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

Class

DateFormatter
Provides a service to handle various date related functionality.

Namespace

Drupal\Core\Datetime

Code

public function formatDiff($from, $to, $options = array()) {

  $options += array(
    '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 = 1e99;
  foreach (array('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', array(), array('langcode' => $options['langcode']));
          $max_age = min($max_age, 365 * 86400);
          break;

        case 'm':
          $interval_output = $this->formatPlural($interval->m, '1 month', '@count months', array(), array('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', array(), array('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', array(), array('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', array(), array('langcode' => $options['langcode']));
          $max_age = min($max_age, 3600);
          break;

        case 'i':
          $interval_output = $this->formatPlural($interval->i, '1 minute', '@count minutes', array(), array('langcode' => $options['langcode']));
          $max_age = min($max_age, 60);
          break;

        case 's':
          $interval_output = $this->formatPlural($interval->s, '1 second', '@count seconds', array(), array('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;
}

© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.
https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Datetime!DateFormatter.php/function/DateFormatter::formatDiff/8.1.x