@register.filter
def naturaltime(value):
 if (not isinstance(value, date)):
  return value
 now = datetime.now((utc if is_aware(value) else None))
 if (value < now):
  delta = (now - value)
  if (delta.days != 0):
   return (pgettext('naturaltime', '%(delta)s ago') % {'delta': defaultfilters.timesince(value, now)})
  elif (delta.seconds == 0):
   return _('now')
  elif (delta.seconds < 60):
   return (ungettext('a second ago', '%(count)s\xc2\xa0seconds ago', delta.seconds) % {'count': delta.seconds})
  elif ((delta.seconds // 60) < 60):
   count = (delta.seconds // 60)
   return (ungettext('a minute ago', '%(count)s\xc2\xa0minutes ago', count) % {'count': count})
  else:
   count = ((delta.seconds // 60) // 60)
   return (ungettext('an hour ago', '%(count)s\xc2\xa0hours ago', count) % {'count': count})
 else:
  delta = (value - now)
  if (delta.days != 0):
   return (pgettext('naturaltime', '%(delta)s from now') % {'delta': defaultfilters.timeuntil(value, now)})
  elif (delta.seconds == 0):
   return _('now')
  elif (delta.seconds < 60):
   return (ungettext('a second from now', '%(count)s\xc2\xa0seconds from now', delta.seconds) % {'count': delta.seconds})
  elif ((delta.seconds // 60) < 60):
   count = (delta.seconds // 60)
   return (ungettext('a minute from now', '%(count)s\xc2\xa0minutes from now', count) % {'count': count})
  else:
   count = ((delta.seconds // 60) // 60)
   return (ungettext('an hour from now', '%(count)s\xc2\xa0hours from now', count) % {'count': count})

@ register . filter def naturaltime ( value ) : if ( not isinstance ( value , date ) ) : return value now = datetime . now ( ( utc if is_aware ( value ) else None ) ) if ( value < now ) : delta = ( now - value ) if ( delta . days != 0 ) : return ( pgettext ( 'naturaltime' , '%(delta)s ago' ) % { 'delta' : defaultfilters . timesince ( value , now ) } ) elif ( delta . seconds == 0 ) : return _ ( 'now' ) elif ( delta . seconds < 60 ) : return ( ungettext ( 'a second ago' , '%(count)s\xc2\xa0seconds ago' , delta . seconds ) % { 'count' : delta . seconds } ) elif ( ( delta . seconds // 60 ) < 60 ) : count = ( delta . seconds // 60 ) return ( ungettext ( 'a minute ago' , '%(count)s\xc2\xa0minutes ago' , count ) % { 'count' : count } ) else : count = ( ( delta . seconds // 60 ) // 60 ) return ( ungettext ( 'an hour ago' , '%(count)s\xc2\xa0hours ago' , count ) % { 'count' : count } ) else : delta = ( value - now ) if ( delta . days != 0 ) : return ( pgettext ( 'naturaltime' , '%(delta)s from now' ) % { 'delta' : defaultfilters . timeuntil ( value , now ) } ) elif ( delta . seconds == 0 ) : return _ ( 'now' ) elif ( delta . seconds < 60 ) : return ( ungettext ( 'a second from now' , '%(count)s\xc2\xa0seconds from now' , delta . seconds ) % { 'count' : delta . seconds } ) elif ( ( delta . seconds // 60 ) < 60 ) : count = ( delta . seconds // 60 ) return ( ungettext ( 'a minute from now' , '%(count)s\xc2\xa0minutes from now' , count ) % { 'count' : count } ) else : count = ( ( delta . seconds // 60 ) // 60 ) return ( ungettext ( 'an hour from now' , '%(count)s\xc2\xa0hours from now' , count ) % { 'count' : count } )
heavily based on djangos django .