diff -r 57b4279d8c4e -r 03e267d67478 app/django/utils/timesince.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/django/utils/timesince.py Fri Jul 18 18:22:23 2008 +0000 @@ -0,0 +1,67 @@ +import datetime +import time + +from django.utils.tzinfo import LocalTimezone +from django.utils.translation import ungettext, ugettext + +def timesince(d, now=None): + """ + Takes two datetime objects and returns the time between d and now + as a nicely formatted string, e.g. "10 minutes". If d occurs after now, + then "0 minutes" is returned. + + Units used are years, months, weeks, days, hours, and minutes. + Seconds and microseconds are ignored. Up to two adjacent units will be + displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are + possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not. + + Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since + """ + chunks = ( + (60 * 60 * 24 * 365, lambda n: ungettext('year', 'years', n)), + (60 * 60 * 24 * 30, lambda n: ungettext('month', 'months', n)), + (60 * 60 * 24 * 7, lambda n : ungettext('week', 'weeks', n)), + (60 * 60 * 24, lambda n : ungettext('day', 'days', n)), + (60 * 60, lambda n: ungettext('hour', 'hours', n)), + (60, lambda n: ungettext('minute', 'minutes', n)) + ) + # Convert datetime.date to datetime.datetime for comparison + if d.__class__ is not datetime.datetime: + d = datetime.datetime(d.year, d.month, d.day) + if now: + t = now.timetuple() + else: + t = time.localtime() + if d.tzinfo: + tz = LocalTimezone(d) + else: + tz = None + now = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz) + + # ignore microsecond part of 'd' since we removed it from 'now' + delta = now - (d - datetime.timedelta(0, 0, d.microsecond)) + since = delta.days * 24 * 60 * 60 + delta.seconds + if since <= 0: + # d is in the future compared to now, stop processing. + return u'0 ' + ugettext('minutes') + for i, (seconds, name) in enumerate(chunks): + count = since // seconds + if count != 0: + break + s = ugettext('%(number)d %(type)s') % {'number': count, 'type': name(count)} + if i + 1 < len(chunks): + # Now get the second item + seconds2, name2 = chunks[i + 1] + count2 = (since - (seconds * count)) // seconds2 + if count2 != 0: + s += ugettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)} + return s + +def timeuntil(d, now=None): + """ + Like timesince, but returns a string measuring the time until + the given time. + """ + if now == None: + now = datetime.datetime.now() + return timesince(now, d)