It looks as though Craft 3’s built-in duration
Twig filter might help:
Posted {{ entry.myDateField.diff(now) | duration }} ago.
With a bit of additional logic, you can make this more useful, after an Entry leaves a specified window:
{% set dateOneYearAgo = now.modify('- 1 year') %}
{% set dateOneMonthAgo = now.modify('- 1 month') %}
{% set dateOneDayAgo = now.modify('- 1 day') %}
{% set elapsedMonths = entry.myDateField.diff(now).m %}
{% set elapsedDays = entry.myDateField.diff(now).d %}
{% if entry.myDateField < dateOneYearAgo %}
{# Posted longer ago than one year... #}
Posted on {{ entry.myDateField | date('M j, Y') %}
{% elseif entry.myDateField < dateOneMonthAgo %}
{# Posted longer ago than one month (but more recently than one year, as we caught that, above)... #}
Posted {{ elapsedMonths }} month{{ elapsedMonths != 1 ? 's' : '' }} ago
{% elseif entry.myDateField < dateOneDayAgo %}
{# Posted longer ago than one day (but, as above, more recently than a month ago)... #}
Posted {{ elapsedDays }} day{{ elapsedDays != 1 ? 's' : '' }} ago
{% else %}
Posted {{ entry.myDateField.diff(now) | duration }} ago.
{% endif %}
The if
statements compare the date objects, and returns true
if entry.myDateField
is earlier than the date one year ago (- 1 year
), one month ago (-1 month
), etc.
now.modify(…)
is a convenient and human-readable way of getting a date relative to the current time—you can pass this method any relative date string.
The ternary statements (like {{ elapsedDays != 1 ? 's' : '' }}
) are just a crummy way of properly pluralizing the units of time—I'd recommend using the Typogrify plugin, instead, as it offers some more declarative ways to handling this— say, {{ 'month' | pluralize(elapsedDays) }}
.
Note: I've omitted special circumstances for things like “yesterday,” as these constraints can be layered in as new else if
statements—just be sure to put the tightest constraints at the top, so that it matches your priorities (i.e. a test for “last week” should come after a test for “yesterday”). Anything you don't care about can fall through to the default duration
filter.