summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2018-06-03 10:33:38 +0200
committerClaude Paroz <claude@2xlibre.net>2018-06-08 18:00:17 +0200
commit56611a96df7172ab9a5e3b2ac19dc3fb83add722 (patch)
tree2b021f573e7164577efd2f44a2e546d00745998c
parente0d0fc0b14ccade00b30a7fbdb1c720ddd83bb71 (diff)
Refactored naturaltime to use a class-based formatter
-rw-r--r--django/contrib/humanize/templatetags/humanize.py161
1 files changed, 86 insertions, 75 deletions
diff --git a/django/contrib/humanize/templatetags/humanize.py b/django/contrib/humanize/templatetags/humanize.py
index 838d669834..6095813b06 100644
--- a/django/contrib/humanize/templatetags/humanize.py
+++ b/django/contrib/humanize/templatetags/humanize.py
@@ -9,7 +9,8 @@ from django.utils.formats import number_format
from django.utils.safestring import mark_safe
from django.utils.timezone import is_aware, utc
from django.utils.translation import (
- gettext as _, ngettext, npgettext_lazy, pgettext,
+ gettext as _, gettext_lazy, ngettext, ngettext_lazy, npgettext_lazy,
+ pgettext,
)
register = template.Library()
@@ -214,79 +215,89 @@ def naturaltime(value):
For date and time values show how many seconds, minutes, or hours ago
compared to current timestamp return representing string.
"""
- if not isinstance(value, date): # datetime is a subclass of date
- return value
+ return NaturalTimeFormatter.string_for(value)
- now = datetime.now(utc if is_aware(value) else None)
- if value < now:
- delta = now - value
- if delta.days != 0:
- # Translators: delta will contain a string like '2 months' or '1 month, 2 weeks'
- return _('%(delta)s ago') % {'delta': defaultfilters.timesince(value, now, time_strings={
- # Translators: 'naturaltime-past' strings will be included in
- # '%(delta)s ago'
- 'year': npgettext_lazy('naturaltime-past', '%d year', '%d years'),
- 'month': npgettext_lazy('naturaltime-past', '%d month', '%d months'),
- 'week': npgettext_lazy('naturaltime-past', '%d week', '%d weeks'),
- 'day': npgettext_lazy('naturaltime-past', '%d day', '%d days'),
- 'hour': npgettext_lazy('naturaltime-past', '%d hour', '%d hours'),
- 'minute': npgettext_lazy('naturaltime-past', '%d minute', '%d minutes')
- })}
- elif delta.seconds == 0:
- return _('now')
- elif delta.seconds < 60:
- return ngettext(
- # Translators: please keep a non-breaking space (U+00A0)
- # between count and time unit.
- 'a second ago', '%(count)s seconds ago', delta.seconds
- ) % {'count': delta.seconds}
- elif delta.seconds // 60 < 60:
- count = delta.seconds // 60
- return ngettext(
- # Translators: please keep a non-breaking space (U+00A0)
- # between count and time unit.
- 'a minute ago', '%(count)s minutes ago', count
- ) % {'count': count}
- else:
- count = delta.seconds // 60 // 60
- return ngettext(
- # Translators: please keep a non-breaking space (U+00A0)
- # between count and time unit.
- 'an hour ago', '%(count)s hours ago', count
- ) % {'count': count}
- else:
- delta = value - now
- if delta.days != 0:
- # Translators: delta will contain a string like '2 months' or '1 month, 2 weeks'
- return _('%(delta)s from now') % {'delta': defaultfilters.timeuntil(value, now, time_strings={
- # Translators: 'naturaltime-future' strings will be included in
- # '%(delta)s from now'
- 'year': npgettext_lazy('naturaltime-future', '%d year', '%d years'),
- 'month': npgettext_lazy('naturaltime-future', '%d month', '%d months'),
- 'week': npgettext_lazy('naturaltime-future', '%d week', '%d weeks'),
- 'day': npgettext_lazy('naturaltime-future', '%d day', '%d days'),
- 'hour': npgettext_lazy('naturaltime-future', '%d hour', '%d hours'),
- 'minute': npgettext_lazy('naturaltime-future', '%d minute', '%d minutes')
- })}
- elif delta.seconds == 0:
- return _('now')
- elif delta.seconds < 60:
- return ngettext(
- # Translators: please keep a non-breaking space (U+00A0)
- # between count and time unit.
- 'a second from now', '%(count)s seconds from now', delta.seconds
- ) % {'count': delta.seconds}
- elif delta.seconds // 60 < 60:
- count = delta.seconds // 60
- return ngettext(
- # Translators: please keep a non-breaking space (U+00A0)
- # between count and time unit.
- 'a minute from now', '%(count)s minutes from now', count
- ) % {'count': count}
+
+class NaturalTimeFormatter:
+ time_strings = {
+ # Translators: delta will contain a string like '2 months' or '1 month, 2 weeks'
+ 'past-day': gettext_lazy('%(delta)s ago'),
+ # Translators: please keep a non-breaking space (U+00A0) between count
+ # and time unit.
+ 'past-hour': ngettext_lazy('an hour ago', '%(count)s hours ago', 'count'),
+ # Translators: please keep a non-breaking space (U+00A0) between count
+ # and time unit.
+ 'past-minute': ngettext_lazy('a minute ago', '%(count)s minutes ago', 'count'),
+ # Translators: please keep a non-breaking space (U+00A0) between count
+ # and time unit.
+ 'past-second': ngettext_lazy('a second ago', '%(count)s seconds ago', 'count'),
+ 'now': gettext_lazy('now'),
+ # Translators: please keep a non-breaking space (U+00A0) between count
+ # and time unit.
+ 'future-second': ngettext_lazy('a second from now', '%(count)s seconds from now', 'count'),
+ # Translators: please keep a non-breaking space (U+00A0) between count
+ # and time unit.
+ 'future-minute': ngettext_lazy('a minute from now', '%(count)s minutes from now', 'count'),
+ # Translators: please keep a non-breaking space (U+00A0) between count
+ # and time unit.
+ 'future-hour': ngettext_lazy('an hour from now', '%(count)s hours from now', 'count'),
+ # Translators: delta will contain a string like '2 months' or '1 month, 2 weeks'
+ 'future-day': gettext_lazy('%(delta)s from now'),
+ }
+ past_substrings = {
+ # Translators: 'naturaltime-past' strings will be included in '%(delta)s ago'
+ 'year': npgettext_lazy('naturaltime-past', '%d year', '%d years'),
+ 'month': npgettext_lazy('naturaltime-past', '%d month', '%d months'),
+ 'week': npgettext_lazy('naturaltime-past', '%d week', '%d weeks'),
+ 'day': npgettext_lazy('naturaltime-past', '%d day', '%d days'),
+ 'hour': npgettext_lazy('naturaltime-past', '%d hour', '%d hours'),
+ 'minute': npgettext_lazy('naturaltime-past', '%d minute', '%d minutes'),
+ }
+ future_substrings = {
+ # Translators: 'naturaltime-future' strings will be included in '%(delta)s from now'
+ 'year': npgettext_lazy('naturaltime-future', '%d year', '%d years'),
+ 'month': npgettext_lazy('naturaltime-future', '%d month', '%d months'),
+ 'week': npgettext_lazy('naturaltime-future', '%d week', '%d weeks'),
+ 'day': npgettext_lazy('naturaltime-future', '%d day', '%d days'),
+ 'hour': npgettext_lazy('naturaltime-future', '%d hour', '%d hours'),
+ 'minute': npgettext_lazy('naturaltime-future', '%d minute', '%d minutes'),
+ }
+
+ @classmethod
+ def string_for(cls, value):
+ if not isinstance(value, date): # datetime is a subclass of date
+ return value
+
+ now = datetime.now(utc if is_aware(value) else None)
+ if value < now:
+ delta = now - value
+ if delta.days != 0:
+ return cls.time_strings['past-day'] % {
+ 'delta': defaultfilters.timesince(value, now, time_strings=cls.past_substrings),
+ }
+ elif delta.seconds == 0:
+ return cls.time_strings['now']
+ elif delta.seconds < 60:
+ return cls.time_strings['past-second'] % {'count': delta.seconds}
+ elif delta.seconds // 60 < 60:
+ count = delta.seconds // 60
+ return cls.time_strings['past-minute'] % {'count': count}
+ else:
+ count = delta.seconds // 60 // 60
+ return cls.time_strings['past-hour'] % {'count': count}
else:
- count = delta.seconds // 60 // 60
- return ngettext(
- # Translators: please keep a non-breaking space (U+00A0)
- # between count and time unit.
- 'an hour from now', '%(count)s hours from now', count
- ) % {'count': count}
+ delta = value - now
+ if delta.days != 0:
+ return cls.time_strings['future-day'] % {
+ 'delta': defaultfilters.timeuntil(value, now, time_strings=cls.future_substrings),
+ }
+ elif delta.seconds == 0:
+ return cls.time_strings['now']
+ elif delta.seconds < 60:
+ return cls.time_strings['future-second'] % {'count': delta.seconds}
+ elif delta.seconds // 60 < 60:
+ count = delta.seconds // 60
+ return cls.time_strings['future-minute'] % {'count': count}
+ else:
+ count = delta.seconds // 60 // 60
+ return cls.time_strings['future-hour'] % {'count': count}