Drupal - How can I use 'xx time ago' as date format?
There are two ways to tackle this.
One is to just use the field formatters. If you have a DateTime field, just goto Manage Display, and change the Format to Time ago. Then click the gear, and pick some options. These are cache aware that will bubble up through the page, but you may end up with short cache lifetimes in some situations.
The other is to use a template_preprocess_node()
. This is preferable when you have a timestamp that isn't a field. Then you use the date formatter service to render out the timestamp in timeago format. It is preferable to use the formatDiff() versions rather than formatInterval() (while not formally deprecated, it is discouraged).
function MYTHEME_preprocess_node(&$variables) {
/** @var \Drupal\Core\Datetime\DateFormatterInterface $formatter */
$date_formatter = \Drupal::service('date.formatter');
$request_time = \Drupal::time()->getRequestTime();
$variables['foo'] = $date_formatter->formatDiff($request_time - 12345, $request_time, [
'granularity' => 3,
'return_as_object' => TRUE,
])->toRenderable();
}
When you specify 'return_as_object' => TRUE
with the formatDiff() functions, a FormattedDateDiff
object gets returned, which contains the formatted string as well as a mostly accurate [#cache]['max-age']
entry in a render array to make this work with Drupal 8's new caching system. Then you can just use {{ foo }}
in your Twig template; the render engine will do the right thing with the render array instead of a plain string.
Also read the docs on DateFormatterInterface
for the formatTimeDiffSince()
and formatTimeDiffUntil()
variants, and for the $options you can pass in
.
The easiest approach is to prepare it in ỳourtheme_preprocess_node() and then just print it in the twig template.
However, with D8's render caching, trying to do a time ago output on the server side can not work, unless you disable caching. It will be calculated on the first request and then never change again.
Instead, you want to send the time in an easy to parse markup, and then use JS to display it as a time ago format. See how d.o does that for comment dates: https://www.drupal.org/node/2704717 (it also includes functionality to switch between relative and absolute dates with a double click).
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Datetime%21DateFormatter.php/function/DateFormatter%3A%3AformatTimeDiffSince/8.2.x
$this->date->formatTimeDiffSince($time_stamp);
or
\Drupal::service('date.formatter')->formatTimeDiffSince($time_stamp);