Refactored naturaltime to use a class-based formatter

This commit is contained in:
Claude Paroz 2018-06-03 10:33:38 +02:00
parent e0d0fc0b14
commit 56611a96df
1 changed files with 86 additions and 75 deletions

View File

@ -9,7 +9,8 @@ from django.utils.formats import number_format
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.timezone import is_aware, utc from django.utils.timezone import is_aware, utc
from django.utils.translation import ( from django.utils.translation import (
gettext as _, ngettext, npgettext_lazy, pgettext, gettext as _, gettext_lazy, ngettext, ngettext_lazy, npgettext_lazy,
pgettext,
) )
register = template.Library() register = template.Library()
@ -214,6 +215,56 @@ def naturaltime(value):
For date and time values show how many seconds, minutes, or hours ago For date and time values show how many seconds, minutes, or hours ago
compared to current timestamp return representing string. compared to current timestamp return representing string.
""" """
return NaturalTimeFormatter.string_for(value)
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 if not isinstance(value, date): # datetime is a subclass of date
return value return value
@ -221,72 +272,32 @@ def naturaltime(value):
if value < now: if value < now:
delta = now - value delta = now - value
if delta.days != 0: if delta.days != 0:
# Translators: delta will contain a string like '2 months' or '1 month, 2 weeks' return cls.time_strings['past-day'] % {
return _('%(delta)s ago') % {'delta': defaultfilters.timesince(value, now, time_strings={ 'delta': defaultfilters.timesince(value, now, time_strings=cls.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')
})}
elif delta.seconds == 0: elif delta.seconds == 0:
return _('now') return cls.time_strings['now']
elif delta.seconds < 60: elif delta.seconds < 60:
return ngettext( return cls.time_strings['past-second'] % {'count': delta.seconds}
# 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: elif delta.seconds // 60 < 60:
count = delta.seconds // 60 count = delta.seconds // 60
return ngettext( return cls.time_strings['past-minute'] % {'count': count}
# 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: else:
count = delta.seconds // 60 // 60 count = delta.seconds // 60 // 60
return ngettext( return cls.time_strings['past-hour'] % {'count': count}
# 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: else:
delta = value - now delta = value - now
if delta.days != 0: if delta.days != 0:
# Translators: delta will contain a string like '2 months' or '1 month, 2 weeks' return cls.time_strings['future-day'] % {
return _('%(delta)s from now') % {'delta': defaultfilters.timeuntil(value, now, time_strings={ 'delta': defaultfilters.timeuntil(value, now, time_strings=cls.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')
})}
elif delta.seconds == 0: elif delta.seconds == 0:
return _('now') return cls.time_strings['now']
elif delta.seconds < 60: elif delta.seconds < 60:
return ngettext( return cls.time_strings['future-second'] % {'count': delta.seconds}
# 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: elif delta.seconds // 60 < 60:
count = delta.seconds // 60 count = delta.seconds // 60
return ngettext( return cls.time_strings['future-minute'] % {'count': count}
# 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}
else: else:
count = delta.seconds // 60 // 60 count = delta.seconds // 60 // 60
return ngettext( return cls.time_strings['future-hour'] % {'count': count}
# 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}