1 import datetime
2 import time
3
4 from django.utils.tzinfo import LocalTimezone
5 from django.utils.translation import ungettext, ugettext
6
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
29 if d.__class__ is not datetime.datetime:
30 d = datetime.datetime(d.year, d.month, d.day)
31
32 if not now:
33 if d.tzinfo:
34 now = datetime.datetime.now(LocalTimezone(d))
35 else:
36 now = datetime.datetime.now()
37
38
39 delta = now - (d - datetime.timedelta(0, 0, d.microsecond))
40 since = delta.days * 24 * 60 * 60 + delta.seconds
41 if since <= 0:
42
43 return u'0 ' + ugettext('minutes')
44 for i, (seconds, name) in enumerate(chunks):
45 count = since // seconds
46 if count != 0:
47 break
48 s = ugettext('%(number)d %(type)s') % {'number': count, 'type': name(count)}
49 if i + 1 < len(chunks):
50
51 seconds2, name2 = chunks[i + 1]
52 count2 = (since - (seconds * count)) // seconds2
53 if count2 != 0:
54 s += ugettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)}
55 return s
56
68