Natural/Relative days in Python Natural/Relative days in Python python python

Natural/Relative days in Python


Twitter dates in specific are interesting because they are relative only for the first day. After 24 hours they just show the month and day. After a year they start showing the last two digits of the year. Here's a sample function that does something more akin to Twitter relative dates, though it always shows the year too after 24 hours. It's US locale only, but you can always alter it as needed.

# tested in Python 2.7import datetimedef prettydate(d):    diff = datetime.datetime.utcnow() - d    s = diff.seconds    if diff.days > 7 or diff.days < 0:        return d.strftime('%d %b %y')    elif diff.days == 1:        return '1 day ago'    elif diff.days > 1:        return '{} days ago'.format(diff.days)    elif s <= 1:        return 'just now'    elif s < 60:        return '{} seconds ago'.format(s)    elif s < 120:        return '1 minute ago'    elif s < 3600:        return '{} minutes ago'.format(s/60)    elif s < 7200:        return '1 hour ago'    else:        return '{} hours ago'.format(s/3600)


While not useful to you at this very moment, it may be so for future searchers:The babel module, which deals with all sorts of locale stuff, has a function for doing more or less what you want. Currently it's only in their trunk though, not in the latest public release (version 0.9.4). Once the functionality lands in a release, you could do something like:

from datetime import timedeltafrom babel.dates import format_timedeltadelta = timedelta(days=6)format_timedelta(delta, locale='en_US')u'1 week'

This is taken straight from the babel documentation on time delta formatting. This will at least get you parts of the way. It wont do fuzziness down to the level of "moments ago" and such, but it will do "n minutes" etc. correctly pluralized.

For what it's worth, the babel module also contains functions for formatting dates and times according to locale, Which might be useful when the time delta is large.


There is the humanize package:

>>> import humanize>>> import datetime>>> humanize.naturalday(datetime.datetime.now())'today'>>> humanize.naturalday(datetime.datetime.now() - datetime.timedelta(days=1))'yesterday'>>> humanize.naturalday(datetime.date(2007, 6, 5))'Jun 05'>>> humanize.naturaldate(datetime.date(2007, 6, 5))'Jun 05 2007'>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=1))'a second ago'>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600))'an hour ago'

Examples for your use case:

>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=36000))'10 hours ago'>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=360000))'4 days ago'>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600000))'a month ago'

Further (see link above) it also supports humanization of:

  • integers
  • file sizes
  • floats (to fractional numbers)