Project

General

Profile

Statistics
| Branch: | Revision:

root / env / lib / python2.7 / site-packages / django / utils / timesince.py @ 1a305335

History | View | Annotate | Download (2.37 KB)

1
import datetime
2

    
3
from django.utils.timezone import is_aware, utc
4
from django.utils.translation import ungettext, ugettext
5

    
6
def timesince(d, now=None, reversed=False):
7
    """
8
    Takes two datetime objects and returns the time between d and now
9
    as a nicely formatted string, e.g. "10 minutes".  If d occurs after now,
10
    then "0 minutes" is returned.
11

12
    Units used are years, months, weeks, days, hours, and minutes.
13
    Seconds and microseconds are ignored.  Up to two adjacent units will be
14
    displayed.  For example, "2 weeks, 3 days" and "1 year, 3 months" are
15
    possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not.
16

17
    Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
18
    """
19
    chunks = (
20
      (60 * 60 * 24 * 365, lambda n: ungettext('year', 'years', n)),
21
      (60 * 60 * 24 * 30, lambda n: ungettext('month', 'months', n)),
22
      (60 * 60 * 24 * 7, lambda n : ungettext('week', 'weeks', n)),
23
      (60 * 60 * 24, lambda n : ungettext('day', 'days', n)),
24
      (60 * 60, lambda n: ungettext('hour', 'hours', n)),
25
      (60, lambda n: ungettext('minute', 'minutes', n))
26
    )
27
    # Convert datetime.date to datetime.datetime for comparison.
28
    if not isinstance(d, datetime.datetime):
29
        d = datetime.datetime(d.year, d.month, d.day)
30
    if now and not isinstance(now, datetime.datetime):
31
        now = datetime.datetime(now.year, now.month, now.day)
32

    
33
    if not now:
34
        now = datetime.datetime.now(utc if is_aware(d) else None)
35

    
36
    delta = (d - now) if reversed else (now - d)
37
    # ignore microseconds
38
    since = delta.days * 24 * 60 * 60 + delta.seconds
39
    if since <= 0:
40
        # d is in the future compared to now, stop processing.
41
        return u'0 ' + ugettext('minutes')
42
    for i, (seconds, name) in enumerate(chunks):
43
        count = since // seconds
44
        if count != 0:
45
            break
46
    s = ugettext('%(number)d %(type)s') % {'number': count, 'type': name(count)}
47
    if i + 1 < len(chunks):
48
        # Now get the second item
49
        seconds2, name2 = chunks[i + 1]
50
        count2 = (since - (seconds * count)) // seconds2
51
        if count2 != 0:
52
            s += ugettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)}
53
    return s
54

    
55
def timeuntil(d, now=None):
56
    """
57
    Like timesince, but returns a string measuring the time until
58
    the given time.
59
    """
60
    return timesince(d, now, reversed=True)