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"&lt;a&gt;\&#39; <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
-~----------~----~----~----~------~----~------~--~---

Reply via email to