Django

Code

Changeset 8579

Show
Ignore:
Timestamp:
08/26/08 03:08:55 (3 months ago)
Author:
mtredinnick
Message:

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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/AUTHORS

    r8578 r8579  
    8989    Trevor Caira <trevor@caira.com> 
    9090    Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com> 
     91    Jeremy Carbaugh <jcarbaugh@gmail.com> 
    9192    Graham Carlyle <graham.carlyle@maplecroft.net> 
    9293    Antonio Cavedoni <http://cavedoni.com/> 
  • django/trunk/django/template/defaultfilters.py

    r8577 r8579  
    647647    if not value: 
    648648        return u'' 
    649     if arg: 
    650         return timesince(value, arg) 
    651     return timesince(value) 
     649    try: 
     650        if arg: 
     651            return timesince(value, arg) 
     652        return timesince(value) 
     653    except (ValueError, TypeError): 
     654        return u'' 
    652655timesince.is_safe = False 
    653656 
    654657def timeuntil(value, arg=None): 
    655658    """Formats a date as the time until that date (i.e. "4 days, 6 hours").""" 
    656     from django.utils.timesince import timesince 
     659    from django.utils.timesince import timeuntil 
    657660    from datetime import datetime 
    658661    if not value: 
    659662        return u'' 
    660     if arg: 
    661         return timesince(arg, value) 
    662     return timesince(datetime.now(), value) 
     663    try: 
     664        return timeuntil(value, arg) 
     665    except (ValueError, TypeError): 
     666        return u'' 
    663667timeuntil.is_safe = False 
    664668 
  • django/trunk/django/utils/timesince.py

    r6368 r8579  
    2929    if d.__class__ is not datetime.datetime: 
    3030        d = datetime.datetime(d.year, d.month, d.day) 
    31     if now: 
    32         t = now.timetuple() 
    33     else: 
    34         t = time.localtime() 
    35     if d.tzinfo: 
    36         tz = LocalTimezone(d) 
    37     else: 
    38         tz = None 
    39     now = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz) 
     31 
     32    if not now: 
     33        if d.tzinfo: 
     34            now = datetime.datetime.now(LocalTimezone(d)) 
     35        else: 
     36            now = datetime.datetime.now() 
    4037 
    4138    # ignore microsecond part of 'd' since we removed it from 'now' 
     
    6360    the given time. 
    6461    """ 
    65     if now == None: 
    66         now = datetime.datetime.now() 
     62    if not now: 
     63        if d.tzinfo: 
     64            now = datetime.datetime.now(LocalTimezone(d)) 
     65        else: 
     66            now = datetime.datetime.now() 
    6767    return timesince(now, d) 
  • django/trunk/docs/ref/templates/builtins.txt

    r8535 r8579  
    13331333then ``{{ blog_date|timesince:comment_date }}`` would return "8 hours". 
    13341334 
     1335Comparing offset-naive and offset-aware datetimes will return an empty string. 
     1336 
    13351337Minutes is the smallest unit used, and "0 minutes" will be returned for any 
    13361338date that is in the future relative to the comparison point. 
     
    13491351the comparison point (instead of *now*). If ``from_date`` contains 22 June 
    135013522006, then ``{{ conference_date|timeuntil:from_date }}`` will return "1 week". 
     1353 
     1354Comparing offset-naive and offset-aware datetimes will return an empty string. 
    13511355 
    13521356Minutes is the smallest unit used, and "0 minutes" will be returned for any 
  • django/trunk/tests/regressiontests/templates/filters.py

    r8577 r8579  
    1010from datetime import datetime, timedelta 
    1111 
    12 from django.utils.tzinfo import LocalTimezone 
     12from django.utils.tzinfo import LocalTimezone, FixedOffset 
    1313from django.utils.safestring import mark_safe 
    1414 
     
    2828    now = datetime.now() 
    2929    now_tz = datetime.now(LocalTimezone(now)) 
     30    now_tz_i = datetime.now(FixedOffset((3 * 60) + 15)) # imaginary time zone 
    3031    return { 
    3132        # Default compare with datetime.now() 
     
    4748        'filter-timesince10': ('{{ later|timesince:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '0 minutes'), 
    4849 
     50        # Ensures that differing timezones are calculated correctly 
     51        'filter-timesince11' : ('{{ a|timesince }}', {'a': now}, '0 minutes'), 
     52        'filter-timesince12' : ('{{ a|timesince }}', {'a': now_tz}, '0 minutes'), 
     53        'filter-timesince13' : ('{{ a|timesince }}', {'a': now_tz_i}, '0 minutes'), 
     54        'filter-timesince14' : ('{{ a|timesince:b }}', {'a': now_tz, 'b': now_tz_i}, '0 minutes'), 
     55        'filter-timesince15' : ('{{ a|timesince:b }}', {'a': now, 'b': now_tz_i}, ''), 
     56        'filter-timesince16' : ('{{ a|timesince:b }}', {'a': now_tz_i, 'b': now}, ''), 
     57 
    4958        # Default compare with datetime.now() 
    5059        'filter-timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now() + timedelta(minutes=2, seconds = 10)}, '2 minutes'), 
     
    6271        'filter-timeuntil09': ('{{ later|timeuntil:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '1 week'), 
    6372 
     73        # Ensures that differing timezones are calculated correctly 
     74        'filter-timeuntil10' : ('{{ a|timeuntil }}', {'a': now_tz_i}, '0 minutes'), 
     75        'filter-timeuntil11' : ('{{ a|timeuntil:b }}', {'a': now_tz_i, 'b': now_tz}, '0 minutes'), 
    6476 
    6577        'filter-addslash01': ("{% autoescape off %}{{ a|addslashes }} {{ b|addslashes }}{% endautoescape %}", {"a": "<a>'", "b": mark_safe("<a>'")}, ur"<a>\' <a>\'"), 
  • django/trunk/tests/regressiontests/utils/timesince.py

    r7294 r8579  
    11""" 
    22>>> from datetime import datetime, timedelta 
    3 >>> from django.utils.timesince import timesince 
     3>>> from django.utils.timesince import timesince, timeuntil 
     4>>> from django.utils.tzinfo import LocalTimezone, FixedOffset 
    45 
    56>>> t = datetime(2007, 8, 14, 13, 46, 0) 
     
    7576>>> timesince(t, t-4*oneday-5*oneminute) 
    7677u'0 minutes' 
     78 
     79# When using two different timezones. 
     80>>> now = datetime.now() 
     81>>> now_tz = datetime.now(LocalTimezone(now)) 
     82>>> now_tz_i = datetime.now(FixedOffset((3 * 60) + 15)) 
     83>>> timesince(now) 
     84u'0 minutes' 
     85>>> timesince(now_tz) 
     86u'0 minutes' 
     87>>> timeuntil(now_tz, now_tz_i) 
     88u'0 minutes' 
    7789"""