19

When I do this:

{% load humanize %}

{{ video.pub_date|naturaltime|capfirst }}

I get 2 days, 19 hours ago

How can I get just 2 days without the hours. Basically if the video was published in less than a day ago then it should say X hours ago, then it should count in days like X days ago, then in weeks. I just don't want 1 hours 5 minutes ago or 2 days 13 minutes ago. Just the first part.

I looked at the humanize docs but couldn't find what I needed.

Trufa
  • 39,971
  • 43
  • 126
  • 190
Veme
  • 195
  • 1
  • 1
  • 4

4 Answers4

33

Django has a built-in template filter timesince that offers the same output you mentioned above. The following filter just strips the second part after the comma:

from datetime import datetime, timedelta
from django import template
from django.utils.timesince import timesince

register = template.Library()

@register.filter
def age(value):
    now = datetime.now()
    try:
        difference = now - value
    except:
        return value

    if difference <= timedelta(minutes=1):
        return 'just now'
    return '%(time)s ago' % {'time': timesince(value).split(', ')[0]}
Chris Wesseling
  • 6,226
  • 2
  • 36
  • 72
Bernhard Vallant
  • 49,468
  • 20
  • 120
  • 148
3

There is naturaltime in modern django.

Given now is 17 Feb 2007 16:30:00.

It changes 16 Feb 2007 13:31:29 to 1 day, 2 hours ago.

{# some_template.html #}
{% load humanize %}
{{ past_time | naturaltime }}

https://docs.djangoproject.com/en/2.2/ref/contrib/humanize/#naturaltime

Harry Moreno
  • 10,231
  • 7
  • 64
  • 116
  • This doesn't provide X days ago, only 'today', 'yesterday', etc – alias51 Jun 02 '20 at 10:42
  • 1
    I'm just saying its nice to be aware of `naturaltime` built into django. Like `humanize` it computes `16 Feb 2007 13:31:29` -> `1 day, 2 hours ago.` – Harry Moreno Jun 02 '20 at 17:24
2

You should duplicate your django.contrib.humanize.templatetags.humanize.py to myapp.templatetags.myhumanize and modify it to your needs. (I can't find the actual line that returns "x days, y hours ago". Which version of django/humanize are you using?)

Udi
  • 29,222
  • 9
  • 96
  • 129
  • 3
    I would recommend against copying code and modifying it. That could break stuff from newer versions. – Darioush Jun 27 '11 at 16:33
0

You can also now use an ExpressionWrapper or Case/When that will utilize the queryset and database to format it directly.

Example output, in combo with day/days pluralized off the top of my head:

overdue = ExpressionWrapper(timezone.now() - F('due_date'), output_field=fields.DurationField())
objects = Activity.objects.all().order_by('-due_date').annotate(overdue=overdue)
Paul
  • 136
  • 1
  • 3