<p>Chiming in with a solution made from reading the above solution and comments. I also wrapped it in a macro.</p>

<pre><code>{% macro timeAgo(entry) %}

    {% set dateOneHourAgo = now.modify('- 1 hour') %}

    {% set elapsedMinutes = entry.myDateField.diff(now).m %}

    {% if not (entry.myDateField &lt; dateOneHourAgo) %}

        {{ entry.myDateField.diff(now) | duration | split('and') | first }} ago

    {% else %}

        {{ entry.myDateField.diff(now) | duration | split(',') | first }} ago

    {% endif %}

{% endmacro %}
</code></pre>

CC BY-SA 4.0
2019-11-28T15:06:21.860Z
Better late than never. This will help me out in the near future! Thanks!
mateostabio
CC BY-SA 4.0
2019-10-14T09:22:36.077Z
2019-10-14T09:22:36.077Z
Amos Whitewolf
<p>It looks as though Craft 3’s <a href="https://docs.craftcms.com/v3/dev/filters.html#duration" rel="nofollow noreferrer">built-in <code>duration</code> Twig filter</a> might help:</p>

<pre><code>Posted {{ entry.myDateField.diff(now) | duration }} ago.
</code></pre>

<p>With a bit of additional logic, you can make this more useful, after an Entry leaves a specified window:</p>

<pre><code>{% 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 &lt; dateOneYearAgo %}
    {# Posted longer ago than one year... #}
    Posted on {{ entry.myDateField | date('M j, Y') %}
{% elseif entry.myDateField &lt; 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 &lt; 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 %}
</code></pre>

<p>The <code>if</code> statements compare the date objects, and returns <code>true</code> if <code>entry.myDateField</code> is earlier than the date one year ago (<code>- 1 year</code>), one month ago (<code>-1 month</code>), etc.</p>

<p><code>now.modify(…)</code> is a convenient and human-readable way of getting a date relative to the current time—you can pass this method any <a href="https://secure.php.net/manual/en/datetime.formats.relative.php" rel="nofollow noreferrer">relative date</a> string.</p>

<p>The ternary statements (like <code>{{ elapsedDays != 1 ? 's' : '' }}</code>) are just a crummy way of properly pluralizing the units of time—I'd recommend using the <a href="https://github.com/nystudio107/craft-typogrify" rel="nofollow noreferrer">Typogrify</a> plugin, instead, as it offers some more declarative ways to handling this— say, <code>{{ 'month' | pluralize(elapsedDays) }}</code>.</p>

<blockquote>
  <p>Note: I've omitted special circumstances for things like “yesterday,” as these constraints can be layered in as new <code>else if</code> 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 <code>duration</code> filter.</p>
</blockquote>

CC BY-SA 4.0
2018-11-07T21:39:23.530Z
[DateTimeHelper::secondsToHumanTimeDuration](https://github.com/craftcms/cms/blob/develop/src/helpers/DateTimeHelper.php#L385) and [DateTimeHelper::humanDurationFromInterval()](https://github.com/craftcms/cms/blob/develop/src/helpers/DateTimeHelper.php#L604) might be handy, too.
Brad Bell
CC BY-SA 4.0
2018-11-09T21:34:08.030Z
Alright, so I gave it a try, and I'm not sure what you did with now.modify, can you explain?
Also I tried both examples you have up there but always got back a very full date like this : Posted 21 days, 22 hours, and 49 minutes ago.
Is there a way to simplify it and to keep only the first element which in this case would be "21 days"? Thanks
mateostabio
CC BY-SA 4.0
2018-11-10T04:50:47.937Z
Didn't know this about the output of the `duration` filter! Based on the source, it looks like it'd be safe to just pick the first segment off of the returned value, split on the commas that join the units, i.e. `{{ entry.myDateField.diff(now) | duration | split(',') | first }}`
August Miller
CC BY-SA 4.0
2018-11-13T22:31:42.813Z
@AugustMiller Thanks a lot! I'm almost there. It is now spiting out `3 days` but there seems to be an issue when its not a full day, it spits out 2 hours and 24 minutes. Is there a way to also remove the following: `and 24 minutes` ? Thank you!
mateostabio
CC BY-SA 4.0
2018-11-14T18:29:59.407Z
I think you might be in the territory of just needing a couple more conditionals, rather than trying to parse + modify output—I'll update the answer to reflect another layer of scrutiny when deciding what output "style" to use.
August Miller
CC BY-SA 4.0
2018-11-07T19:49:48.343Z
2018-11-14T19:00:00.187Z
2018-11-14T19:00:00.187Z
August Miller
<p>Is there anyway to get my date formats looking like Facebook? I'd like to get my articles to have this as a date format: "5 min ago", "yesterday", "3 days ago", "4 months ago" and then once it reaches a full year ago, make it have a date format like "Dec 5, 2016".</p>

<p>If anyone has gotten this working, would you mind sharing with me(and the world) your code on how to achieve this in Twig?</p>

<p>Thanks in advance!</p>

<datetime><postdate><format>
Entry Post Date Format time since - X days ago
# Entry Post Date Format time since - X days ago

(Asked by: username_0 on 2018-11-07)

Is there anyway to get my date formats looking like Facebook? I'd like to get my articles to have this as a date format: "5 min ago", "yesterday", "3 days ago", "4 months ago" and then once it reaches a full year ago, make it have a date format like "Dec 5, 2016".

If anyone has gotten this working, would you mind sharing with me(and the world) your code on how to achieve this in Twig?

Thanks in advance!

**Tags:** datetime, postdate, format

---

## 2 answers

### Answer by username_1 on 2019-10-14. Score: 3 | Accepted answer

Chiming in with a solution made from reading the above solution and comments. I also wrapped it in a macro.
{% macro timeAgo(entry) %}

    {% set dateOneHourAgo = now.modify('- 1 hour') %}

    {% set elapsedMinutes = entry.myDateField.diff(now).m %}

    {% if not (entry.myDateField < dateOneHourAgo) %}

        {{ entry.myDateField.diff(now) | duration | split('and') | first }} ago

    {% else %}

        {{ entry.myDateField.diff(now) | duration | split(',') | first }} ago

    {% endif %}

{% endmacro %}

> **Comments:**
> **username_0**: Better late than never. This will help me out in the near future! Thanks!  

---

### Answer by username_2 on 2018-11-07. Score: 4

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.

> **Comments:**
> **username_3**: [DateTimeHelper::secondsToHumanTimeDuration](https://github.com/craftcms/cms/blob/develop/src/helpers/DateTimeHelper.php#L385) and [DateTimeHelper::humanDurationFromInterval()](https://github.com/craftcms/cms/blob/develop/src/helpers/DateTimeHelper.php#L604) might be handy, too.  
> **username_0**: Alright, so I gave it a try, and I'm not sure what you did with now.modify, can you explain? Also I tried both examples you have up there but always got back a very full date like this : Posted 21 days, 22 hours, and 49 minutes ago. Is there a way to simplify it and to keep only the first element which in this case would be "21 days"? Thanks  
> **username_2**: Didn't know this about the output of the `duration` filter! Based on the source, it looks like it'd be safe to just pick the first segment off of the returned value, split on the commas that join the units, i.e. `{{ entry.myDateField.diff(now) | duration | split(',') | first }}`  
> **username_0**: @AugustMiller Thanks a lot! I'm almost there. It is now spiting out `3 days` but there seems to be an issue when its not a full day, it spits out 2 hours and 24 minutes. Is there a way to also remove the following: `and 24 minutes` ? Thank you!  
> **username_2**: I think you might be in the territory of just needing a couple more conditionals, rather than trying to parse + modify output—I'll update the answer to reflect another layer of scrutiny when deciding what output "style" to use.  

---

