Fixed #15921 -- Refined naturaltime filter added in r16071 to use timesince and timeuntil filters as fallbacks instead of date filter.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16233 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2011-05-17 10:16:12 +00:00
parent 9ad005ec1c
commit 578a31fea3
5 changed files with 177 additions and 85 deletions

View File

@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-05-07 21:53+0200\n"
"POT-Creation-Date: 2011-05-16 17:30+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
@ -12,133 +12,166 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: templatetags/humanize.py:21
#: templatetags/humanize.py:25
msgid "th"
msgstr ""
#: templatetags/humanize.py:21
#: templatetags/humanize.py:25
msgid "st"
msgstr ""
#: templatetags/humanize.py:21
#: templatetags/humanize.py:25
msgid "nd"
msgstr ""
#: templatetags/humanize.py:21
#: templatetags/humanize.py:25
msgid "rd"
msgstr ""
#: templatetags/humanize.py:74
#: templatetags/humanize.py:78
#, python-format
msgid "%(value).1f million"
msgid_plural "%(value).1f million"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:75
#: templatetags/humanize.py:79
#, python-format
msgid "%(value)s million"
msgid_plural "%(value)s million"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:80
#: templatetags/humanize.py:84
#, python-format
msgid "%(value).1f billion"
msgid_plural "%(value).1f billion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:81
#: templatetags/humanize.py:85
#, python-format
msgid "%(value)s billion"
msgid_plural "%(value)s billion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:86
#: templatetags/humanize.py:90
#, python-format
msgid "%(value).1f trillion"
msgid_plural "%(value).1f trillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:87
#: templatetags/humanize.py:91
#, python-format
msgid "%(value)s trillion"
msgid_plural "%(value)s trillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:104
#: templatetags/humanize.py:108
msgid "one"
msgstr ""
#: templatetags/humanize.py:104
#: templatetags/humanize.py:108
msgid "two"
msgstr ""
#: templatetags/humanize.py:104
#: templatetags/humanize.py:108
msgid "three"
msgstr ""
#: templatetags/humanize.py:104
#: templatetags/humanize.py:108
msgid "four"
msgstr ""
#: templatetags/humanize.py:104
#: templatetags/humanize.py:108
msgid "five"
msgstr ""
#: templatetags/humanize.py:104
#: templatetags/humanize.py:108
msgid "six"
msgstr ""
#: templatetags/humanize.py:104
#: templatetags/humanize.py:108
msgid "seven"
msgstr ""
#: templatetags/humanize.py:104
#: templatetags/humanize.py:108
msgid "eight"
msgstr ""
#: templatetags/humanize.py:104
#: templatetags/humanize.py:108
msgid "nine"
msgstr ""
#: templatetags/humanize.py:127
#: templatetags/humanize.py:131
msgid "today"
msgstr ""
#: templatetags/humanize.py:129
#: templatetags/humanize.py:133
msgid "tomorrow"
msgstr ""
#: templatetags/humanize.py:131
#: templatetags/humanize.py:135
msgid "yesterday"
msgstr ""
#: templatetags/humanize.py:153
#: templatetags/humanize.py:160
#, python-format
msgctxt "naturaltime"
msgid "%(delta)s ago"
msgstr ""
#: templatetags/humanize.py:163 templatetags/humanize.py:185
msgid "now"
msgstr ""
#: templatetags/humanize.py:155
#: templatetags/humanize.py:166
#, python-format
msgid "%s seconds ago"
msgid_plural "%s seconds ago"
msgid "a second ago"
msgid_plural "%(count)s seconds ago"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:157
#: templatetags/humanize.py:171
#, python-format
msgid "a minute ago"
msgid_plural "%s minutes ago"
msgid_plural "%(count)s minutes ago"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:159
#: templatetags/humanize.py:176
#, python-format
msgid "an hour ago"
msgid_plural "%s hours ago"
msgid_plural "%(count)s hours ago"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:182
#, python-format
msgctxt "naturaltime"
msgid "%(delta)s from now"
msgstr ""
#: templatetags/humanize.py:188
#, python-format
msgid "a second from now"
msgid_plural "%(count)s seconds from now"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:193
#, python-format
msgid "a minute from now"
msgid_plural "%(count)s minutes from now"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:198
#, python-format
msgid "an hour from now"
msgid_plural "%(count)s hours from now"
msgstr[0] ""
msgstr[1] ""

View File

@ -1,11 +1,15 @@
from django.utils.translation import ungettext, ugettext as _
import re
from datetime import date, datetime, timedelta
from django import template
from django.conf import settings
from django.template import defaultfilters
from django.utils.datetime_safe import datetime, date
from django.utils.encoding import force_unicode
from django.utils.formats import number_format
from django import template
from django.template import defaultfilters
from django.conf import settings
from datetime import date, datetime
import re
from django.utils.translation import pgettext, ungettext, ugettext as _
from django.utils.tzinfo import LocalTimezone
register = template.Library()
@ -132,11 +136,10 @@ def naturalday(value, arg=None):
return defaultfilters.date(value, arg)
@register.filter
def naturaltime(value, arg=None):
def naturaltime(value):
"""
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
For date and time values shows how many seconds, minutes or hours ago
compared to current timestamp returns representing string.
"""
try:
value = datetime(value.year, value.month, value.day, value.hour, value.minute, value.second)
@ -145,16 +148,52 @@ def naturaltime(value, arg=None):
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 ungettext(u'%s seconds ago', u'%s seconds ago', delta.seconds)
elif delta.seconds / 60 < 60:
return ungettext(u'a minute ago', u'%s minutes ago', delta.seconds/60)
elif delta.seconds / 60 / 60 < 24:
return ungettext(u'an hour ago', u'%s hours ago', delta.seconds/60/60)
return naturalday(value, arg)
if getattr(value, 'tzinfo', None):
now = datetime.now(LocalTimezone(value))
else:
now = datetime.now()
now = now - timedelta(0, 0, now.microsecond)
if value < now:
delta = now - value
if delta.days != 0:
return pgettext(
'naturaltime', '%(delta)s ago'
) % {'delta': defaultfilters.timesince(value)}
elif delta.seconds == 0:
return _(u'now')
elif delta.seconds < 60:
return ungettext(
u'a second ago', u'%(count)s seconds ago', delta.seconds
) % {'count': delta.seconds}
elif delta.seconds / 60 < 60:
count = delta.seconds / 60
return ungettext(
u'a minute ago', u'%(count)s minutes ago', count
) % {'count': count}
else:
count = delta.seconds / 60 / 60
return ungettext(
u'an hour ago', u'%(count)s hours ago', count
) % {'count': count}
else:
delta = value - now
if delta.days != 0:
return pgettext(
'naturaltime', '%(delta)s from now'
) % {'delta': defaultfilters.timeuntil(value)}
elif delta.seconds == 0:
return _(u'now')
elif delta.seconds < 60:
return ungettext(
u'a second from now', u'%(count)s seconds from now', delta.seconds
) % {'count': delta.seconds}
elif delta.seconds / 60 < 60:
count = delta.seconds / 60
return ungettext(
u'a minute from now', u'%(count)s minutes from now', count
) % {'count': count}
else:
count = delta.seconds / 60 / 60
return ungettext(
u'an hour from now', u'%(count)s hours from now', count
) % {'count': count}

View File

@ -104,9 +104,8 @@ naturaltime
For datetime values, returns a string representing how many seconds,
minutes or hours ago it was -- falling back to a longer date format if the
value is more than a day old.
**Argument:** Date formatting string as described in the :tfilter:`date` tag.
value is more than a day old. In case the datetime value is in the future
the return value will automatically use an appropriate phrase.
Examples (when 'now' is 17 Feb 2007 16:30:00):
@ -116,9 +115,13 @@ Examples (when 'now' is 17 Feb 2007 16:30:00):
* ``17 Feb 2007 16:25:35`` becomes ``4 minutes ago``.
* ``17 Feb 2007 15:30:29`` becomes ``an hour 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.
* ``16 Feb 2007 13:31:29`` becomes ``1 day ago``.
* ``17 Feb 2007 16:30:30`` becomes ``29 seconds from now``.
* ``17 Feb 2007 16:31:00`` becomes ``a minute from now``.
* ``17 Feb 2007 16:34:35`` becomes ``4 minutes from now``.
* ``17 Feb 2007 16:30:29`` becomes ``an hour from now``.
* ``17 Feb 2007 18:31:29`` becomes ``2 hours from now``.
* ``18 Feb 2007 16:31:29`` becomes ``1 day from now``.
.. templatefilter:: ordinal

View File

@ -89,31 +89,6 @@ class HumanizeTests(TestCase):
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)
def test_naturalday_tz(self):
from django.contrib.humanize.templatetags.humanize import naturalday
@ -130,3 +105,45 @@ class HumanizeTests(TestCase):
# As 24h of difference they will never be the same
self.assertNotEqual(naturalday_one, naturalday_two)
def test_naturaltime(self):
now = datetime.now()
test_list = [
now,
now - timedelta(seconds=1),
now - timedelta(seconds=30),
now - timedelta(minutes=1, seconds=30),
now - timedelta(minutes=2),
now - timedelta(hours=1, minutes=30, seconds=30),
now - timedelta(hours=23, minutes=50, seconds=50),
now - timedelta(days=1),
now - timedelta(days=500),
now + timedelta(seconds=1),
now + timedelta(seconds=30),
now + timedelta(minutes=1, seconds=30),
now + timedelta(minutes=2),
now + timedelta(hours=1, minutes=30, seconds=30),
now + timedelta(hours=23, minutes=50, seconds=50),
now + timedelta(days=1),
now + timedelta(days=500),
]
result_list = [
'now',
'a second ago',
'30 seconds ago',
'a minute ago',
'2 minutes ago',
'an hour ago',
'23 hours ago',
'1 day ago',
'1 year, 4 months ago',
'a second from now',
'30 seconds from now',
'a minute from now',
'2 minutes from now',
'an hour from now',
'23 hours from now',
'1 day from now',
'1 year, 4 months from now',
]
self.humanize_tester(test_list, result_list, 'naturaltime')