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. Django Settings Assignment Expressions aka Walrus Operator example by webology 3 weeks, 3 days ago
  2. codigo alto nivel by MrRocklion 2 months, 3 weeks ago
  3. Load template from specific app by Krzysiek555 3 months, 1 week ago
  4. PostgreSQL JSON subqueries by dolamroth 3 months, 1 week ago
  5. "Magic Link" Management Command by webology 8 months, 2 weeks 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.