Humanizing the time difference ( in django )

django.contrib.humanize is a set of Django template filters that adds human touch to data. It provides naturalday filter that formats date to ‘yesterday’, ‘today’ or ‘tomorrow’ when applicable.

A similar requirement which the humanize pacakge does not address is to display time difference with this human touch. so here is a snippet that does so.

from django import template

register = template.Library()

MOMENT = 120 # duration in seconds within which the time difference
                # will be rendered as 'a moment ago'

@register.filter
def naturalTimeDifference(value):
    """
Finds the difference between the datetime value given and now()
and returns appropriate humanize form
"""
    
    from datetime import datetime

    if isinstance(value, datetime):
        delta = datetime.now() - value
        if delta.days > 6:
            return value.strftime("%b %d") # May 15
        if delta.days > 1:
            return value.strftime("%A") # Wednesday
        elif delta.days == 1:
            return 'yesterday' # yesterday
        elif delta.seconds > 3600:
            return str(delta.seconds / 3600 ) + ' hours ago' # 3 hours ago
        elif delta.seconds > MOMENT:
            return str(delta.seconds/60) + ' minutes ago' # 29 minutes ago
        else:
            return 'a moment ago' # a moment ago
        return defaultfilters.date(value)
    else:
        return str(value)

This entry was posted in Codeprix and tagged , , , . Bookmark the permalink.

2 Responses to Humanizing the time difference ( in django )

  1. Hi Anand,

    Thanks for sharing naturalTimeDifference(). I made two changes to improve your code, feel free to share with others. First, if the filter is passed a datetime.timedelta object it uses that instead of calculating datetime.now() – value. Second, with one additional conditional it now says “1 hour ago” for (7200 > delta.seconds >= 3600) and “N hours ago” for delta >= 7200. Small changes for a grammatically correct result.

    Here is the updated filter code:

    def naturalTimeDifference(value):
    “”"
    Finds the difference between the datetime value given and now()
    and returns appropriate humanize form
    “”"

    from datetime import datetime, timedelta

    if isinstance(value, timedelta):
    delta = value
    elif isinstance(value, datetime):
    delta = datetime.now() – value
    else:
    delta = None

    if delta:
    if delta.days > 6:
    return value.strftime(“%b %d”) # May 15
    if delta.days > 1:
    return value.strftime(“%A”) # Wednesday
    elif delta.days == 1:
    return ‘yesterday’ # yesterday
    elif delta.seconds >= 7200:
    return str(delta.seconds / 3600 ) + ‘ hours ago’ # 3 hours ago
    elif delta.seconds >= 3600:
    return ’1 hour ago’ # 1 hour ago
    elif delta.seconds > MOMENT:
    return str(delta.seconds/60) + ‘ minutes ago’ # 29 minutes ago
    else:
    return ‘a moment ago’ # a moment ago
    return defaultfilters.date(value)
    else:
    return str(value)

  2. Thomas Gak Deluen says:

    Hi, now with Django 1.4 and time zone support you need to replace
    datetime.utcnow() - value
    with

    delta = timezone.now() - value

    where ‘timezone’ is imported with

    from django.utils import timezone

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>