Permalink
Browse files

Refactored naturaltime to use a class-based formatter

  • Loading branch information...
claudep committed Jun 3, 2018
1 parent e0d0fc0 commit 56611a96df7172ab9a5e3b2ac19dc3fb83add722
Showing with 86 additions and 75 deletions.
  1. +86 −75 django/contrib/humanize/templatetags/humanize.py
@@ -9,7 +9,8 @@
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}

0 comments on commit 56611a9

Please sign in to comment.