Author: mtredinnick
Date: 2008-08-26 03:08:55 -0500 (Tue, 26 Aug 2008)
New Revision: 8579
Modified:
django/trunk/AUTHORS
django/trunk/django/template/defaultfilters.py
django/trunk/django/utils/timesince.py
django/trunk/docs/ref/templates/builtins.txt
django/trunk/tests/regressiontests/templates/filters.py
django/trunk/tests/regressiontests/utils/timesince.py
Log:
Fixed #7201 -- Fixed the timeuntil filter to work correctly with timezone-aware
times. Patch from Jeremy Carbaugh.
This is backwards incompatible in the sense that previously, if you tried to
compare timezone-aware and timezone-naive values, you got an incorrect result.
Now you get an empty string. So your previously incorrect code returns a
different incorrect result.
Modified: django/trunk/AUTHORS
===================================================================
--- django/trunk/AUTHORS 2008-08-26 07:56:39 UTC (rev 8578)
+++ django/trunk/AUTHORS 2008-08-26 08:08:55 UTC (rev 8579)
@@ -88,6 +88,7 @@
Juan Manuel Caicedo <[EMAIL PROTECTED]>
Trevor Caira <[EMAIL PROTECTED]>
Ricardo Javier Cárdenes Medina <[EMAIL PROTECTED]>
+ Jeremy Carbaugh <[EMAIL PROTECTED]>
Graham Carlyle <[EMAIL PROTECTED]>
Antonio Cavedoni <http://cavedoni.com/>
C8E
Modified: django/trunk/django/template/defaultfilters.py
===================================================================
--- django/trunk/django/template/defaultfilters.py 2008-08-26 07:56:39 UTC
(rev 8578)
+++ django/trunk/django/template/defaultfilters.py 2008-08-26 08:08:55 UTC
(rev 8579)
@@ -646,20 +646,24 @@
from django.utils.timesince import timesince
if not value:
return u''
- if arg:
- return timesince(value, arg)
- return timesince(value)
+ try:
+ if arg:
+ return timesince(value, arg)
+ return timesince(value)
+ except (ValueError, TypeError):
+ return u''
timesince.is_safe = False
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 django.utils.timesince import timeuntil
from datetime import datetime
if not value:
return u''
- if arg:
- return timesince(arg, value)
- return timesince(datetime.now(), value)
+ try:
+ return timeuntil(value, arg)
+ except (ValueError, TypeError):
+ return u''
timeuntil.is_safe = False
###################
Modified: django/trunk/django/utils/timesince.py
===================================================================
--- django/trunk/django/utils/timesince.py 2008-08-26 07:56:39 UTC (rev
8578)
+++ django/trunk/django/utils/timesince.py 2008-08-26 08:08:55 UTC (rev
8579)
@@ -28,16 +28,13 @@
# 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)
+ if not now:
+ if d.tzinfo:
+ now = datetime.datetime.now(LocalTimezone(d))
+ else:
+ now = datetime.datetime.now()
+
# 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
@@ -62,6 +59,9 @@
Like timesince, but returns a string measuring the time until
the given time.
"""
- if now == None:
- now = datetime.datetime.now()
+ if not now:
+ if d.tzinfo:
+ now = datetime.datetime.now(LocalTimezone(d))
+ else:
+ now = datetime.datetime.now()
return timesince(now, d)
Modified: django/trunk/docs/ref/templates/builtins.txt
===================================================================
--- django/trunk/docs/ref/templates/builtins.txt 2008-08-26 07:56:39 UTC
(rev 8578)
+++ django/trunk/docs/ref/templates/builtins.txt 2008-08-26 08:08:55 UTC
(rev 8579)
@@ -1332,6 +1332,8 @@
June 2006, and ``comment_date`` is a date instance for 08:00 on 1 June 2006,
then ``{{ blog_date|timesince:comment_date }}`` would return "8 hours".
+Comparing offset-naive and offset-aware datetimes will return an empty string.
+
Minutes is the smallest unit used, and "0 minutes" will be returned for any
date that is in the future relative to the comparison point.
@@ -1349,6 +1351,8 @@
the comparison point (instead of *now*). If ``from_date`` contains 22 June
2006, then ``{{ conference_date|timeuntil:from_date }}`` will return "1 week".
+Comparing offset-naive and offset-aware datetimes will return an empty string.
+
Minutes is the smallest unit used, and "0 minutes" will be returned for any
date that is in the past relative to the comparison point.
Modified: django/trunk/tests/regressiontests/templates/filters.py
===================================================================
--- django/trunk/tests/regressiontests/templates/filters.py 2008-08-26
07:56:39 UTC (rev 8578)
+++ django/trunk/tests/regressiontests/templates/filters.py 2008-08-26
08:08:55 UTC (rev 8579)
@@ -9,7 +9,7 @@
from datetime import datetime, timedelta
-from django.utils.tzinfo import LocalTimezone
+from django.utils.tzinfo import LocalTimezone, FixedOffset
from django.utils.safestring import mark_safe
# These two classes are used to test auto-escaping of __unicode__ output.
@@ -27,6 +27,7 @@
def get_filter_tests():
now = datetime.now()
now_tz = datetime.now(LocalTimezone(now))
+ now_tz_i = datetime.now(FixedOffset((3 * 60) + 15)) # imaginary time zone
return {
# Default compare with datetime.now()
'filter-timesince01' : ('{{ a|timesince }}', {'a': datetime.now() +
timedelta(minutes=-1, seconds = -10)}, '1 minute'),
@@ -46,6 +47,14 @@
'filter-timesince09': ('{{ later|timesince }}', { 'later': now +
timedelta(days=7) }, '0 minutes'),
'filter-timesince10': ('{{ later|timesince:now }}', { 'now': now,
'later': now + timedelta(days=7) }, '0 minutes'),
+ # Ensures that differing timezones are calculated correctly
+ 'filter-timesince11' : ('{{ a|timesince }}', {'a': now}, '0 minutes'),
+ 'filter-timesince12' : ('{{ a|timesince }}', {'a': now_tz}, '0
minutes'),
+ 'filter-timesince13' : ('{{ a|timesince }}', {'a': now_tz_i}, '0
minutes'),
+ 'filter-timesince14' : ('{{ a|timesince:b }}', {'a': now_tz, 'b':
now_tz_i}, '0 minutes'),
+ 'filter-timesince15' : ('{{ a|timesince:b }}', {'a': now, 'b':
now_tz_i}, ''),
+ 'filter-timesince16' : ('{{ a|timesince:b }}', {'a': now_tz_i, 'b':
now}, ''),
+
# Default compare with datetime.now()
'filter-timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now() +
timedelta(minutes=2, seconds = 10)}, '2 minutes'),
'filter-timeuntil02' : ('{{ a|timeuntil }}', {'a':(datetime.now() +
timedelta(days=1, seconds = 10))}, '1 day'),
@@ -61,6 +70,9 @@
'filter-timeuntil08': ('{{ later|timeuntil }}', { 'later': now +
timedelta(days=7, hours=1) }, '1 week'),
'filter-timeuntil09': ('{{ later|timeuntil:now }}', { 'now': now,
'later': now + timedelta(days=7) }, '1 week'),
+ # Ensures that differing timezones are calculated correctly
+ 'filter-timeuntil10' : ('{{ a|timeuntil }}', {'a': now_tz_i}, '0
minutes'),
+ 'filter-timeuntil11' : ('{{ a|timeuntil:b }}', {'a': now_tz_i, 'b':
now_tz}, '0 minutes'),
'filter-addslash01': ("{% autoescape off %}{{ a|addslashes }} {{
b|addslashes }}{% endautoescape %}", {"a": "<a>'", "b": mark_safe("<a>'")},
ur"<a>\' <a>\'"),
'filter-addslash02': ("{{ a|addslashes }} {{ b|addslashes }}", {"a":
"<a>'", "b": mark_safe("<a>'")}, ur"<a>\' <a>\'"),
Modified: django/trunk/tests/regressiontests/utils/timesince.py
===================================================================
--- django/trunk/tests/regressiontests/utils/timesince.py 2008-08-26
07:56:39 UTC (rev 8578)
+++ django/trunk/tests/regressiontests/utils/timesince.py 2008-08-26
08:08:55 UTC (rev 8579)
@@ -1,6 +1,7 @@
"""
>>> from datetime import datetime, timedelta
->>> from django.utils.timesince import timesince
+>>> from django.utils.timesince import timesince, timeuntil
+>>> from django.utils.tzinfo import LocalTimezone, FixedOffset
>>> t = datetime(2007, 8, 14, 13, 46, 0)
@@ -74,4 +75,15 @@
u'0 minutes'
>>> timesince(t, t-4*oneday-5*oneminute)
u'0 minutes'
+
+# When using two different timezones.
+>>> now = datetime.now()
+>>> now_tz = datetime.now(LocalTimezone(now))
+>>> now_tz_i = datetime.now(FixedOffset((3 * 60) + 15))
+>>> timesince(now)
+u'0 minutes'
+>>> timesince(now_tz)
+u'0 minutes'
+>>> timeuntil(now_tz, now_tz_i)
+u'0 minutes'
"""
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---