Opened 3 years ago

Closed 2 years ago

#18202 closed Bug (wontfix)

inconsistent humanize naturaltime

Reported by: oradoe Owned by: nobody
Component: contrib.humanize Version: 1.4
Severity: Normal Keywords: naturaltime, humanize
Cc: Triage Stage: Design decision needed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

Currently, if delta is less than a day, we have 1 level of difference:
4 minutes ago. (not 4 minutes, some seconds ago)
2 hours ago. (not 2 hours, some minutes ago)

Else, we have 2 levels of difference:
2 days, 14 hours ago. (not 2 days ago)
3 weeks, 3 days ago. (not 3 weeks ago)

Expected (now): consistent of only 1 level of difference.
Expected(near future): parameter for level of difference.

my workaround:

author = 'truongsinh'
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.encoding import force_unicode
from django.utils.formats import number_format
from django.utils.translation import pgettext, ungettext, ugettext as _
from django.utils.timezone import is_aware, utc

register = template.Library()

@register.filter
def naturaltime(value):

"""

For date and time values shows how many seconds, minutes or hours ago
compared to current timestamp returns representing string.
"""

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:

return pgettext(

'naturaltime', '{delta:s} ago'

).format(delta = defaultfilters.timesince(value).split(',')[0])

elif not delta.seconds:

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:

return pgettext(

'naturaltime', '%(delta)s from now'

) % {'delta': defaultfilters.timeuntil(value).split(',')[0]}

elif not delta.seconds:

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}

Change History (3)

comment:1 Changed 3 years ago by aviraldg

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

The current behaviour makes perfect sense to me. Can't see why you'd want to change it.

comment:2 Changed 3 years ago by pyriku

I think that is not a bad solution add a new parameter to the filter that allow the user specify how much levels of deep he wants in each case. Anyway, the default behavior should remain the same. As I see it, the result could be something like:

{{date|naturaltime}} == "2 hours ago"
{{date|naturaltime 1}} == "2 hours ago"
{{date|naturaltime 2}} == "2 hours, 20 minutes ago"

comment:3 Changed 2 years ago by aaugustin

  • Resolution set to wontfix
  • Status changed from new to closed

I don't see a compelling argument for changing the current behavior, and adding a parameter sounds vastly overkill compared to the goals of |naturaltime.

If you have more advanced formatting needs, I recommend writing a custom filter.

Note: See TracTickets for help on using tickets.
Back to Top