text: from __future__ import unicode_literals
  
  import calendar
  import datetime
  
  from django.utils.html import avoid_wrapping
  from django.utils.timezone import is_aware, utc
  from django.utils.translation import ugettext, ungettext_lazy
  
  TIMESINCE_CHUNKS = (
      (60 * 60 * 24 * 365, ungettext_lazy('%d year', '%d years')),
      (60 * 60 * 24 * 30, ungettext_lazy('%d month', '%d months')),
      (60 * 60 * 24 * 7, ungettext_lazy('%d week', '%d weeks')),
      (60 * 60 * 24, ungettext_lazy('%d day', '%d days')),
      (60 * 60, ungettext_lazy('%d hour', '%d hours')),
      (60, ungettext_lazy('%d minute', '%d minutes'))
  )
  
  
  def timesince(d, now=None, reversed=False):
      """
      Takes two datetime objects and returns the time between d and now
      as a nicely formatted string, e.g. "10 minutes".  If d occurs after now,
      then "0 minutes" is returned.
  
      Units used are years, months, weeks, days, hours, and minutes.
      Seconds and microseconds are ignored.  Up to two adjacent units will be
      displayed.  For example, "2 weeks, 3 days" and "1 year, 3 months" are
      possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not.
  
      Adapted from
      http://web.archive.org/web/20060617175230/http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
      """
      # Convert datetime.date to datetime.datetime for comparison.
      if not isinstance(d, datetime.datetime):
          d = datetime.datetime(d.year, d.month, d.day)
      if now and not isinstance(now, datetime.datetime):
          now = datetime.datetime(now.year, now.month, now.day)
  
      if not now:
          now = datetime.datetime.now(utc if is_aware(d) else None)
  
      if reversed:
          d, now = now, d
      delta = now - d
  
      # Deal with leapyears by subtracing the number of leapdays
      leapdays = calendar.leapdays(d.year, now.year)
      if leapdays != 0 and calendar.isleap(d.year):
          leapdays -= 1
      delta -= datetime.timedelta(leapdays)
  
      # ignore microseconds
      since = delta.days * 24 * 60 * 60 + delta.seconds
      if since <= 0:
          # d is in the future compared to now, stop processing.
          return avoid_wrapping(ugettext('0 minutes'))
      for i, (seconds, name) in enumerate(TIMESINCE_CHUNKS):
          count = since // seconds
          if count != 0:
              break
      result = avoid_wrapping(name % count)
      if i + 1 < len(TIMESINCE_CHUNKS):
          # Now get the second item
          seconds2, name2 = TIMESINCE_CHUNKS[i + 1]
          count2 = (since - (seconds * count)) // seconds2
          if count2 != 0:
              result += ugettext(', ') + avoid_wrapping(name2 % count2)
      return result
  
  
  def timeuntil(d, now=None):
      """
      Like timesince, but returns a string measuring the time until
      the given time.
      """
      return timesince(d, now, reversed=True)
  