User-friendly time format in Python?
Solution 1
The code was originally published on a blog post "Python Pretty Date function" (http://evaisse.com/post/93417709/python-pretty-date-function)
It is reproduced here as the blog account has been suspended and the page is no longer available.
def pretty_date(time=False):
"""
Get a datetime object or a int() Epoch timestamp and return a
pretty string like 'an hour ago', 'Yesterday', '3 months ago',
'just now', etc
"""
from datetime import datetime
now = datetime.now()
if type(time) is int:
diff = now - datetime.fromtimestamp(time)
elif isinstance(time, datetime):
diff = now - time
elif not time:
diff = 0
second_diff = diff.seconds
day_diff = diff.days
if day_diff < 0:
return ''
if day_diff == 0:
if second_diff < 10:
return "just now"
if second_diff < 60:
return str(second_diff) + " seconds ago"
if second_diff < 120:
return "a minute ago"
if second_diff < 3600:
return str(second_diff // 60) + " minutes ago"
if second_diff < 7200:
return "an hour ago"
if second_diff < 86400:
return str(second_diff // 3600) + " hours ago"
if day_diff == 1:
return "Yesterday"
if day_diff < 7:
return str(day_diff) + " days ago"
if day_diff < 31:
return str(day_diff // 7) + " weeks ago"
if day_diff < 365:
return str(day_diff // 30) + " months ago"
return str(day_diff // 365) + " years ago"
Solution 2
If you happen to be using Django, then new in version 1.4 is the naturaltime
template filter.
To use it, first add 'django.contrib.humanize'
to your INSTALLED_APPS
setting in settings.py, and {% load humanize %}
into the template you're using the filter in.
Then, in your template, if you have a datetime variable my_date
, you can print its distance from the present by using {{ my_date|naturaltime }}
, which will be rendered as something like 4 minutes ago
.
Other new things in Django 1.4.
Documentation for naturaltime
and other filters in the django.contrib.humanize
set.
Solution 3
In looking for the same thing with the additional requirement that it handle future dates, I found this: http://pypi.python.org/pypi/py-pretty/1
Example code (from site):
from datetime import datetime, timedelta
now = datetime.now()
hrago = now - timedelta(hours=1)
yesterday = now - timedelta(days=1)
tomorrow = now + timedelta(days=1)
dayafter = now + timedelta(days=2)
import pretty
print pretty.date(now) # 'now'
print pretty.date(hrago) # 'an hour ago'
print pretty.date(hrago, short=True) # '1h ago'
print pretty.date(hrago, asdays=True) # 'today'
print pretty.date(yesterday, short=True) # 'yest'
print pretty.date(tomorrow) # 'tomorrow'
Solution 4
You can also do that with arrow package
From github page:
>>> import arrow >>> utc = arrow.utcnow() >>> utc = utc.shift(hours=-1) >>> utc.humanize() 'an hour ago'
Solution 5
There is humanize
package:
>>> from datetime import datetime, timedelta
>>> import humanize # $ pip install humanize
>>> humanize.naturaltime(datetime.now() - timedelta(days=1))
'a day ago'
>>> humanize.naturaltime(datetime.now() - timedelta(hours=2))
'2 hours ago'
It supports localization l10n, internationalization i18n:
>>> _ = humanize.i18n.activate('ru_RU')
>>> print humanize.naturaltime(datetime.now() - timedelta(days=1))
день назад
>>> print humanize.naturaltime(datetime.now() - timedelta(hours=2))
2 часа назад
flybywire
Updated on July 05, 2022Comments
-
flybywire almost 2 years
Python: I need to show file modification times in the "1 day ago", "two hours ago", format.
Is there something ready to do that? It should be in English.
-
flybywire over 14 yearsthat is tailored to my exact needs. Thanks!
-
Chris Dail over 14 yearsThe link no longer exists and is giving a Forbidden. Need a permlink here or the content to be moved into this post.
-
Jed Smith over 14 years@Chris: Thanks for the heads up, and it was still in Google Cache so I snagged it.
-
wenbert over 13 yearsThis does not work for me. I get this error: local variable 'diff' referenced before assignment why?
-
Karl Bartel over 12 yearsUnfortunately py-pretty does not seem to allow i18n.
-
Jonathan almost 11 yearsI threw this up to the cheeseshop: (pypi.python.org/pypi/human_dates/0.1.0) and github.com/jtushman/human_dates
-
Jon z over 10 yearsIt would be nice if the time units were not pluralized for single counts, for example '1 week ago' rather than '1 weeks ago'
-
aqs over 9 yearsIs adding it to INSTALLED_APPS really necessary? It worked without that for me, although I used the filter inside python, not the template
-
Zeeshan Anjum over 8 yearsUnboundLocalError: local variable 'diff' referenced before assignment
-
Olivier Pons about 8 yearsWhat is the point of the code
diff = now - now
. Cant we do insteaddiff = 0
-
TaiwanGrapefruitTea over 7 years@Jonathan I tried human_dates 0.2.0 and got: 2.76986301369863 years ago . I found a version in django at github.com/django/django/blob/master/django/utils/timesince.py which gives me: 2 years, 9 months
-
swdev about 7 yearsNice solution. Keeping it simple allows more reuse. E.g can use suffix for relative time
value + " ago"
or durationvalue + " left"
-
Ayrat about 6 years@wenbert because in python 3 mtime is of type
float
, not of typeint
. In the first if, changeint
tofloat
. -
Lucas Werkmeister about 5 yearsNote that
humanize
does not support timezone-aware datetimes; you’ll have to convert those via into naive ones (in the local timezone) withdt.astimezone().replace(tzinfo=None)
. -
Trect about 4 yearsCan I use this inside view
-
WinEunuuchs2Unix almost 4 yearsThe link appears broken again, not 404 but rather a sales page in foreign language.