Login

Smart i18n date diff (twitter like)

Author:
Batiste
Posted:
March 31, 2009
Language:
Python
Version:
1.0
Score:
9 (after 9 ratings)

This snippet display a human readable date diff. You give it the your date in parameter and the diff with datetime.datetime.now() is returned. The diff must be positive to be more accurate (future dates are not supported)

Usage:

{{ status.created_at|date_diff }}

Will give something like:

less than 1 minute ago
13 minutes ago
1 hour ago
etc.

Based on Fuzzy Date Diff Template Filter

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from django import template
from django.utils.translation import ungettext, ugettext as _
import datetime

@register.filter
def date_diff(d):

    now = datetime.datetime.now()
    today = datetime.datetime(now.year, now.month, now.day)
    delta = now - d
    delta_midnight = today - d
    days = delta.days
    hours = round(delta.seconds / 3600., 0)
    minutes = round(delta.seconds / 60., 0)
    chunks = (
        (365.0, lambda n: ungettext('year', 'years', n)),
        (30.0, lambda n: ungettext('month', 'months', n)),
        (7.0, lambda n : ungettext('week', 'weeks', n)),
        (1.0, lambda n : ungettext('day', 'days', n)),
    )
    
    if days == 0:
        if hours == 0:
            if minutes > 0:
                return ungettext('1 minute ago', \
                    '%(minutes)d minutes ago', minutes) % \
                    {'minutes': minutes}
            else:
                return _("less than 1 minute ago")
        else:
            return ungettext('1 hour ago', '%(hours)d hours ago', hours) \
            % {'hours':hours}

    if delta_midnight.days == 0:
        return _("yesterday at %s") % d.strftime("%H:%M")

    count = 0
    for i, (chunk, name) in enumerate(chunks):
        if days >= chunk:
            count = round((delta_midnight.days + 1)/chunk, 0)
            break

    return _('%(number)d %(type)s ago') % \
        {'number': count, 'type': name(count)}

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

benjaoming (on August 27, 2009):

Nice function! Just a quick note for people using different default languages, adding special unicode characters to the strings: remember to add 'u' - as in u"string". Somehow the translation engine likes to make empty strings without producing error messages. Can be tricky! For instance in Danish:

chunks = (
    (365.0, lambda n: ungettext(u'år', u'år', n)),
    (30.0, lambda n: ungettext(u'måned', u'måneder', n)),
    (7.0, lambda n : ungettext(u'uge', u'uger', n)),
    (1.0, lambda n : ungettext(u'dag', u'dage', n)),
)

#

Please login first before commenting.