mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	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. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8579 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		
							
								
								
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -88,6 +88,7 @@ answer newbie questions, and generally made Django that much better: | ||||
|     Juan Manuel Caicedo <juan.manuel.caicedo@gmail.com> | ||||
|     Trevor Caira <trevor@caira.com> | ||||
|     Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com> | ||||
|     Jeremy Carbaugh <jcarbaugh@gmail.com> | ||||
|     Graham Carlyle <graham.carlyle@maplecroft.net> | ||||
|     Antonio Cavedoni <http://cavedoni.com/> | ||||
|     C8E | ||||
|   | ||||
| @@ -646,20 +646,24 @@ def timesince(value, arg=None): | ||||
|     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 | ||||
|  | ||||
| ################### | ||||
|   | ||||
| @@ -28,15 +28,12 @@ def timesince(d, now=None): | ||||
|     # 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)) | ||||
| @@ -62,6 +59,9 @@ 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() | ||||
|     if not now: | ||||
|         if d.tzinfo: | ||||
|             now = datetime.datetime.now(LocalTimezone(d)) | ||||
|         else: | ||||
|             now = datetime.datetime.now() | ||||
|     return timesince(now, d) | ||||
|   | ||||
| @@ -1332,6 +1332,8 @@ For example, if ``blog_date`` is a date instance representing midnight on 1 | ||||
| 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 @@ 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 "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. | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ consistent. | ||||
|  | ||||
| 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 @@ class SafeClass: | ||||
| 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 @@ def get_filter_tests(): | ||||
|         '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 @@ def get_filter_tests(): | ||||
|         '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>\'"), | ||||
|   | ||||
| @@ -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' | ||||
| 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' | ||||
| """ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user