Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #12771 -- Added naturaltime filter to humanize contrib app. Tha…

…nks, phinpho, djansoft and xtrqt.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16071 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit ea248f0107eb3bed5a4a0fb65d6065e5691bea0a 1 parent 8b58874
@jezdez jezdez authored
View
36 django/contrib/humanize/templatetags/humanize.py
@@ -2,7 +2,7 @@
from django.utils.encoding import force_unicode
from django import template
from django.template import defaultfilters
-from datetime import date
+from datetime import date, datetime
import re
register = template.Library()
@@ -83,7 +83,7 @@ def naturalday(value, arg=None):
present day returns representing string. Otherwise, returns a string
formatted according to settings.DATE_FORMAT.
"""
- try:
+ try:
value = date(value.year, value.month, value.day)
except AttributeError:
# Passed value wasn't a date object
@@ -100,3 +100,35 @@ def naturalday(value, arg=None):
return _(u'yesterday')
return defaultfilters.date(value, arg)
register.filter(naturalday)
+
+def naturaltime(value, arg=None):
+ """
+ For date and time values shows how many seconds, minutes or hours ago compared to
+ current timestamp returns representing string. Otherwise, returns a string
+ formatted according to settings.DATE_FORMAT
+ """
+ try:
+ value = datetime(value.year, value.month, value.day, value.hour, value.minute, value.second)
+ except AttributeError:
+ return value
+ except ValueError:
+ return value
+
+ delta = datetime.now() - value
+ if delta.days != 0:
+ value = date(value.year, value.month, value.day)
+ return naturalday(value, arg)
+ elif delta.seconds == 0:
+ return _(u'now')
+ elif delta.seconds < 60:
+ return _(u'%s seconds ago' % (delta.seconds))
+ elif delta.seconds / 60 < 2:
+ return _(r'a minute ago')
+ elif delta.seconds / 60 < 60:
+ return _(u'%s minutes ago' % (delta.seconds/60))
+ elif delta.seconds / 60 / 60 < 2:
+ return _(u'an hour ago')
+ elif delta.seconds / 60 / 60 < 24:
+ return _(u'%s hours ago' % (delta.seconds/60/60))
+ return naturalday(value, arg)
+register.filter(naturaltime)
View
25 docs/ref/contrib/humanize.txt
@@ -82,6 +82,31 @@ Examples (when 'today' is 17 Feb 2007):
* Any other day is formatted according to given argument or the
:setting:`DATE_FORMAT` setting if no argument is given.
+.. templatefilter:: naturaltime
+
+naturaltime
+-----------
+
+.. versionadded:: 1.4
+
+For date and time values shows how many seconds, minutes or hours ago compared
+to current timestamp returns representing string. Otherwise, it behaves like
+:tfilter:`naturaldate`, so it can also take string argument for date formating.
+
+**Argument:** Date formatting string as described in the :tfilter:`date` tag.
+
+Examples (when 'now' is 17 Feb 2007 16:30:00):
+
+ * ``17 Feb 2007 16:30:00`` becomes ``now``.
+ * ``17 Feb 2007 16:29:31`` becomes ``29 seconds ago``.
+ * ``17 Feb 2007 16:29:00`` becomes ``a minute ago``.
+ * ``17 Feb 2007 16:25:35`` becomes ``4 minutes ago``.
+ * ``17 Feb 2007 15:30:29`` becomes ``an hours ago``.
+ * ``17 Feb 2007 13:31:29`` becomes ``2 hours ago``.
+ * ``16 Feb 2007 13:31:29`` becomes ``yesterday``.
+ * Any other day is formatted according to given argument or the
+ :setting:`DATE_FORMAT` setting if no argument is given.
+
.. templatefilter:: ordinal
ordinal
View
28 tests/regressiontests/humanize/tests.py
@@ -1,4 +1,4 @@
-from datetime import timedelta, date
+from datetime import timedelta, date, datetime
from django.template import Template, Context, add_to_builtins
from django.utils import unittest
@@ -72,6 +72,32 @@ def test_naturalday(self):
someday_result, u"I'm not a date value", None)
self.humanize_tester(test_list, result_list, 'naturalday')
+ def test_naturaltime(self):
+ from django.template import defaultfilters
+ now = datetime.now()
+ seconds_ago = now - timedelta(seconds=30)
+ a_minute_ago = now - timedelta(minutes=1, seconds=30)
+ minutes_ago = now - timedelta(minutes=2)
+ an_hour_ago = now - timedelta(hours=1, minutes=30, seconds=30)
+ hours_ago = now - timedelta(hours=23, minutes=50, seconds=50)
+
+ test_list = (now, a_minute_ago, an_hour_ago)
+ result_list = (_(u'now'), _(u'a minute ago'), _(u'an hour ago'))
+ self.humanize_tester(test_list, result_list, 'naturaltime')
+
+ t = Template('{{ seconds_ago|%s }}' % 'naturaltime')
+ rendered = t.render(Context(locals())).strip()
+ self.assertTrue(u' seconds ago' in rendered)
+
+ t = Template('{{ minutes_ago|%s }}' % 'naturaltime')
+ rendered = t.render(Context(locals())).strip()
+ self.assertTrue(u' minutes ago' in rendered)
+
+ t = Template('{{ hours_ago|%s }}' % 'naturaltime')
+ rendered = t.render(Context(locals())).strip()
+ self.assertTrue(u' hours ago' in rendered)
+
+
if __name__ == '__main__':
unittest.main()

0 comments on commit ea248f0

Please sign in to comment.
Something went wrong with that request. Please try again.