2005-11-24 05:13:00 +08:00
|
|
|
import datetime, math, time
|
2005-10-23 05:37:59 +08:00
|
|
|
from django.utils.tzinfo import LocalTimezone
|
2007-04-25 16:32:31 +08:00
|
|
|
from django.utils.translation import ngettext, gettext
|
2005-07-13 09:25:57 +08:00
|
|
|
|
|
|
|
def timesince(d, now=None):
|
|
|
|
"""
|
2005-12-09 10:52:27 +08:00
|
|
|
Takes two datetime objects and returns the time between then and now
|
2005-07-13 09:25:57 +08:00
|
|
|
as a nicely formatted string, e.g "10 minutes"
|
|
|
|
Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
|
|
|
|
"""
|
|
|
|
chunks = (
|
2005-11-23 05:45:54 +08:00
|
|
|
(60 * 60 * 24 * 365, lambda n: ngettext('year', 'years', n)),
|
|
|
|
(60 * 60 * 24 * 30, lambda n: ngettext('month', 'months', n)),
|
2006-05-02 09:31:56 +08:00
|
|
|
(60 * 60 * 24 * 7, lambda n : ngettext('week', 'weeks', n)),
|
2005-11-23 05:45:54 +08:00
|
|
|
(60 * 60 * 24, lambda n : ngettext('day', 'days', n)),
|
|
|
|
(60 * 60, lambda n: ngettext('hour', 'hours', n)),
|
|
|
|
(60, lambda n: ngettext('minute', 'minutes', n))
|
2005-07-13 09:25:57 +08:00
|
|
|
)
|
2006-02-24 04:27:03 +08:00
|
|
|
# Convert datetime.date to datetime.datetime for comparison
|
|
|
|
if d.__class__ is not datetime.datetime:
|
|
|
|
d = datetime.datetime(d.year, d.month, d.day)
|
2005-10-23 05:37:59 +08:00
|
|
|
if now:
|
2005-12-09 10:52:27 +08:00
|
|
|
t = now.timetuple()
|
2005-10-23 05:37:59 +08:00
|
|
|
else:
|
|
|
|
t = time.localtime()
|
|
|
|
if d.tzinfo:
|
2006-06-21 19:11:03 +08:00
|
|
|
tz = LocalTimezone(d)
|
2005-10-23 05:37:59 +08:00
|
|
|
else:
|
|
|
|
tz = None
|
|
|
|
now = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz)
|
2006-02-24 04:27:03 +08:00
|
|
|
|
2006-01-02 02:37:33 +08:00
|
|
|
# ignore microsecond part of 'd' since we removed it from 'now'
|
|
|
|
delta = now - (d - datetime.timedelta(0, 0, d.microsecond))
|
2005-10-23 05:37:59 +08:00
|
|
|
since = delta.days * 24 * 60 * 60 + delta.seconds
|
2005-11-23 05:45:54 +08:00
|
|
|
for i, (seconds, name) in enumerate(chunks):
|
|
|
|
count = since / seconds
|
2005-07-13 09:25:57 +08:00
|
|
|
if count != 0:
|
|
|
|
break
|
2005-11-24 05:13:00 +08:00
|
|
|
if count < 0:
|
2007-04-25 16:32:31 +08:00
|
|
|
return gettext('%d milliseconds') % math.floor((now - d).microseconds / 1000)
|
|
|
|
s = gettext('%(number)d %(type)s') % {'number': count, 'type': name(count)}
|
2005-07-13 09:25:57 +08:00
|
|
|
if i + 1 < len(chunks):
|
|
|
|
# Now get the second item
|
|
|
|
seconds2, name2 = chunks[i + 1]
|
2005-11-23 05:45:54 +08:00
|
|
|
count2 = (since - (seconds * count)) / seconds2
|
2005-07-13 09:25:57 +08:00
|
|
|
if count2 != 0:
|
2007-04-25 16:32:31 +08:00
|
|
|
s += gettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)}
|
2005-07-13 09:25:57 +08:00
|
|
|
return s
|
|
|
|
|
2006-06-21 14:56:08 +08:00
|
|
|
def timeuntil(d, now=None):
|
2005-07-13 09:25:57 +08:00
|
|
|
"""
|
|
|
|
Like timesince, but returns a string measuring the time until
|
|
|
|
the given time.
|
|
|
|
"""
|
2006-06-21 14:56:08 +08:00
|
|
|
if now == None:
|
|
|
|
now = datetime.datetime.now()
|
2005-12-09 10:52:27 +08:00
|
|
|
return timesince(now, d)
|