web/lib/django/utils/timesince.py
changeset 0 0d40e90630ef
equal deleted inserted replaced
-1:000000000000 0:0d40e90630ef
       
     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 not isinstance(d, datetime.datetime):
       
    30         d = datetime.datetime(d.year, d.month, d.day)
       
    31     if now and not isinstance(now, datetime.datetime):
       
    32         now = datetime.datetime(now.year, now.month, now.day)
       
    33 
       
    34     if not now:
       
    35         if d.tzinfo:
       
    36             now = datetime.datetime.now(LocalTimezone(d))
       
    37         else:
       
    38             now = datetime.datetime.now()
       
    39 
       
    40     # ignore microsecond part of 'd' since we removed it from 'now'
       
    41     delta = now - (d - datetime.timedelta(0, 0, d.microsecond))
       
    42     since = delta.days * 24 * 60 * 60 + delta.seconds
       
    43     if since <= 0:
       
    44         # d is in the future compared to now, stop processing.
       
    45         return u'0 ' + ugettext('minutes')
       
    46     for i, (seconds, name) in enumerate(chunks):
       
    47         count = since // seconds
       
    48         if count != 0:
       
    49             break
       
    50     s = ugettext('%(number)d %(type)s') % {'number': count, 'type': name(count)}
       
    51     if i + 1 < len(chunks):
       
    52         # Now get the second item
       
    53         seconds2, name2 = chunks[i + 1]
       
    54         count2 = (since - (seconds * count)) // seconds2
       
    55         if count2 != 0:
       
    56             s += ugettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)}
       
    57     return s
       
    58 
       
    59 def timeuntil(d, now=None):
       
    60     """
       
    61     Like timesince, but returns a string measuring the time until
       
    62     the given time.
       
    63     """
       
    64     if not now:
       
    65         if getattr(d, 'tzinfo', None):
       
    66             now = datetime.datetime.now(LocalTimezone(d))
       
    67         else:
       
    68             now = datetime.datetime.now()
       
    69     return timesince(now, d)