diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index 453c34b0bd..9bd6e7cb3c 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -345,13 +345,25 @@ def time(value, arg=None): arg = settings.TIME_FORMAT return time_format(value, arg) -def timesince(value): +def timesince(value, arg=None): 'Formats a date as the time since that date (i.e. "4 days, 6 hours")' from django.utils.timesince import timesince if not value: return '' + if arg: + return timesince(arg, value) return timesince(value) +def timeuntil(value, arg=None): + 'Formats a date as the time until that date (i.e. "4 days, 6 hours")' + from django.utils.timesince import timesince + from datetime import datetime + if not value: + return '' + if arg: + return timesince(arg, value) + return timesince(datetime.now(), value) + ################### # LOGIC # ################### @@ -485,6 +497,7 @@ register.filter(stringformat) register.filter(striptags) register.filter(time) register.filter(timesince) +register.filter(timeuntil) register.filter(title) register.filter(truncatewords) register.filter(unordered_list) diff --git a/django/utils/timesince.py b/django/utils/timesince.py index bc4f969dc4..0b94d89bc6 100644 --- a/django/utils/timesince.py +++ b/django/utils/timesince.py @@ -47,10 +47,11 @@ def timesince(d, now=None): s += ', %d %s' % (count2, name2(count2)) return s -def timeuntil(d): +def timeuntil(d, now=None): """ Like timesince, but returns a string measuring the time until the given time. """ - now = datetime.datetime.now() + if now == None: + now = datetime.datetime.now() return timesince(now, d) diff --git a/docs/templates.txt b/docs/templates.txt index 5f397c5a60..42947510d1 100644 --- a/docs/templates.txt +++ b/docs/templates.txt @@ -1022,6 +1022,24 @@ timesince Formats a date as the time since that date (i.e. "4 days, 6 hours"). +Takes an optional argument that is a variable containing the date to use as +the comparison point (without the argument, the comparison point is *now*). +For example, if ``blog_date`` is a date instance representing midnight on 1 +June 2006, and ``comment_date`` is a date instanace for 08:00 on 1 June 2006, +then ``{{ comment_date|timesince:blog_date }}`` would return "8 hours". + +timeuntil +~~~~~~~~~ + +Similar to ``timesince``, except that it measures the time from now until the +given date or datetime. For example, if today is 1 June 2006 and +``conference_date`` is a date instance holding 29 June 2006, then +``{{ conference_date|timeuntil }}`` will return "28 days". + +Takes an optional argument that is a variable containing the date to use as +the comparison point (instead of *now*). If ``from_date`` contains 22 June +2006, then ``{{ conference_date|timeuntil:from_date }}`` will return "7 days". + title ~~~~~ diff --git a/tests/othertests/templates.py b/tests/othertests/templates.py index 96ad330917..6ad97d8f80 100644 --- a/tests/othertests/templates.py +++ b/tests/othertests/templates.py @@ -4,7 +4,7 @@ from django.conf import settings from django import template from django.template import loader from django.utils.translation import activate, deactivate, install -from datetime import datetime +from datetime import datetime, timedelta import traceback ################################# @@ -57,6 +57,9 @@ class OtherClass: def method(self): return "OtherClass.method" +# NOW used by timesince tag tests. +NOW = datetime.now() + # SYNTAX -- # 'template_name': ('template contents', 'context dict', 'expected string output' or Exception class) TEMPLATE_TESTS = { @@ -530,6 +533,27 @@ TEMPLATE_TESTS = { 'now02' : ('{% now "j "n" Y"%}', {}, template.TemplateSyntaxError), # 'now03' : ('{% now "j \"n\" Y"%}', {}, str(datetime.now().day) + '"' + str(datetime.now().month) + '"' + str(datetime.now().year)), # 'now04' : ('{% now "j \nn\n Y"%}', {}, str(datetime.now().day) + '\n' + str(datetime.now().month) + '\n' + str(datetime.now().year)) + + ### TIMESINCE TAG ################################################## + # Default compare with datetime.now() + 'timesince01' : ('{{ a|timesince }}', {'a':datetime.now()}, '0 minutes'), + 'timesince02' : ('{{ a|timesince }}', {'a':(datetime.now() - timedelta(days=1))}, '1 day'), + 'timesince03' : ('{{ a|timesince }}', {'a':(datetime.now() - + timedelta(hours=1, minutes=25))}, '1 hour, 25 minutes'), + + # Compare to a given parameter + 'timesince04' : ('{{ a|timesince:b }}', {'a':NOW + timedelta(days=2), 'b':NOW + timedelta(days=1)}, '1 day'), + 'timesince05' : ('{{ a|timesince:b }}', {'a':NOW + timedelta(days=2), 'b':NOW + timedelta(days=2)}, '0 minutes'), + + ### TIMEUNTIL TAG ################################################## + # Default compare with datetime.now() + 'timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now()}, '0 minutes'), + 'timeuntil02' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(days=1))}, '1 day'), + 'timeuntil03' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(hours=8, minutes=10))}, '8 hours, 10 minutes'), + + # Compare to a given parameter + 'timeuntil04' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=1), 'b':NOW - timedelta(days=2)}, '1 day'), + 'timeuntil05' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=2), 'b':NOW - timedelta(days=2)}, '0 minutes'), } def test_template_loader(template_name, template_dirs=None):