app/django/utils/timesince.py
changeset 54 03e267d67478
child 323 ff1a9aa48cfd
equal deleted inserted replaced
53:57b4279d8c4e 54:03e267d67478
       
     1 import datetime
       
     2 import time
       
     3 
       
     4 from django.utils.tzinfo import LocalTimezone
       
     5 from django.utils.translation import ungettext, ugettext
       
     6 
       
     7 def timesince(d, now=None):
       
     8     """
       
     9     Takes two datetime objects and returns the time between d and now
       
    10     as a nicely formatted string, e.g. "10 minutes".  If d occurs after now,
       
    11     then "0 minutes" is returned.
       
    12 
       
    13     Units used are years, months, weeks, days, hours, and minutes.
       
    14     Seconds and microseconds are ignored.  Up to two adjacent units will be
       
    15     displayed.  For example, "2 weeks, 3 days" and "1 year, 3 months" are
       
    16     possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not.
       
    17 
       
    18     Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
       
    19     """
       
    20     chunks = (
       
    21       (60 * 60 * 24 * 365, lambda n: ungettext('year', 'years', n)),
       
    22       (60 * 60 * 24 * 30, lambda n: ungettext('month', 'months', n)),
       
    23       (60 * 60 * 24 * 7, lambda n : ungettext('week', 'weeks', n)),
       
    24       (60 * 60 * 24, lambda n : ungettext('day', 'days', n)),
       
    25       (60 * 60, lambda n: ungettext('hour', 'hours', n)),
       
    26       (60, lambda n: ungettext('minute', 'minutes', n))
       
    27     )
       
    28     # Convert datetime.date to datetime.datetime for comparison
       
    29     if d.__class__ is not datetime.datetime:
       
    30         d = datetime.datetime(d.year, d.month, d.day)
       
    31     if now:
       
    32         t = now.timetuple()
       
    33     else:
       
    34         t = time.localtime()
       
    35     if d.tzinfo:
       
    36         tz = LocalTimezone(d)
       
    37     else:
       
    38         tz = None
       
    39     now = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz)
       
    40 
       
    41     # ignore microsecond part of 'd' since we removed it from 'now'
       
    42     delta = now - (d - datetime.timedelta(0, 0, d.microsecond))
       
    43     since = delta.days * 24 * 60 * 60 + delta.seconds
       
    44     if since <= 0:
       
    45         # d is in the future compared to now, stop processing.
       
    46         return u'0 ' + ugettext('minutes')
       
    47     for i, (seconds, name) in enumerate(chunks):
       
    48         count = since // seconds
       
    49         if count != 0:
       
    50             break
       
    51     s = ugettext('%(number)d %(type)s') % {'number': count, 'type': name(count)}
       
    52     if i + 1 < len(chunks):
       
    53         # Now get the second item
       
    54         seconds2, name2 = chunks[i + 1]
       
    55         count2 = (since - (seconds * count)) // seconds2
       
    56         if count2 != 0:
       
    57             s += ugettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)}
       
    58     return s
       
    59 
       
    60 def timeuntil(d, now=None):
       
    61     """
       
    62     Like timesince, but returns a string measuring the time until
       
    63     the given time.
       
    64     """
       
    65     if now == None:
       
    66         now = datetime.datetime.now()
       
    67     return timesince(now, d)