mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[1.9.x] Fixed debug view crash during autumn DST change.
This only happens if USE_TZ = False and pytz is installed (perhaps not
the most logical combination, but who am I to jugde?)
Refs #23714 which essentially fixed the same problem when USE_TZ = True.
Thanks Florian and Carl for insisting until I wrote a complete patch.
Backport of 1014ba026e from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							f5e1d72de2
						
					
				
				
					commit
					ca0278f496
				
			| @@ -136,6 +136,8 @@ class TimeFormat(Formatter): | ||||
|             return "" | ||||
|  | ||||
|         seconds = self.Z() | ||||
|         if seconds == "": | ||||
|             return "" | ||||
|         sign = '-' if seconds < 0 else '+' | ||||
|         seconds = abs(seconds) | ||||
|         return "%s%02d%02d" % (sign, seconds // 3600, (seconds // 60) % 60) | ||||
| @@ -167,7 +169,14 @@ class TimeFormat(Formatter): | ||||
|         if not self.timezone: | ||||
|             return "" | ||||
|  | ||||
|         name = self.timezone.tzname(self.data) if self.timezone else None | ||||
|         name = None | ||||
|         try: | ||||
|             name = self.timezone.tzname(self.data) | ||||
|         except Exception: | ||||
|             # pytz raises AmbiguousTimeError during the autumn DST change. | ||||
|             # This happens mainly when __init__ receives a naive datetime | ||||
|             # and sets self.timezone = get_default_timezone(). | ||||
|             pass | ||||
|         if name is None: | ||||
|             name = self.format('O') | ||||
|         return six.text_type(name) | ||||
| @@ -188,7 +197,14 @@ class TimeFormat(Formatter): | ||||
|         if not self.timezone: | ||||
|             return "" | ||||
|  | ||||
|         offset = self.timezone.utcoffset(self.data) | ||||
|         try: | ||||
|             offset = self.timezone.utcoffset(self.data) | ||||
|         except Exception: | ||||
|             # pytz raises AmbiguousTimeError during the autumn DST change. | ||||
|             # This happens mainly when __init__ receives a naive datetime | ||||
|             # and sets self.timezone = get_default_timezone(). | ||||
|             return "" | ||||
|  | ||||
|         # `offset` is a datetime.timedelta. For negative values (to the west of | ||||
|         # UTC) only days can be negative (days=-1) and seconds are always | ||||
|         # positive. e.g. UTC-1 -> timedelta(days=-1, seconds=82800, microseconds=0) | ||||
| @@ -228,10 +244,16 @@ class DateFormat(TimeFormat): | ||||
|  | ||||
|     def I(self): | ||||
|         "'1' if Daylight Savings Time, '0' otherwise." | ||||
|         if self.timezone and self.timezone.dst(self.data): | ||||
|             return '1' | ||||
|         else: | ||||
|             return '0' | ||||
|         try: | ||||
|             if self.timezone and self.timezone.dst(self.data): | ||||
|                 return '1' | ||||
|             else: | ||||
|                 return '0' | ||||
|         except Exception: | ||||
|             # pytz raises AmbiguousTimeError during the autumn DST change. | ||||
|             # This happens mainly when __init__ receives a naive datetime | ||||
|             # and sets self.timezone = get_default_timezone(). | ||||
|             return '' | ||||
|  | ||||
|     def j(self): | ||||
|         "Day of the month without leading zeros; i.e. '1' to '31'" | ||||
|   | ||||
| @@ -9,4 +9,7 @@ Django 1.8.7 fixes several bugs in 1.8.6. | ||||
| Bugfixes | ||||
| ======== | ||||
|  | ||||
| * Fixed a crash of the debug view during the autumn DST change when | ||||
|   :setting:`USE_TZ` is ``False`` and ``pytz`` is installed. | ||||
|  | ||||
| * ... | ||||
|   | ||||
| @@ -10,6 +10,11 @@ from django.utils.timezone import ( | ||||
|     get_default_timezone, get_fixed_timezone, make_aware, utc, | ||||
| ) | ||||
|  | ||||
| try: | ||||
|     import pytz | ||||
| except ImportError: | ||||
|     pytz = None | ||||
|  | ||||
|  | ||||
| @override_settings(TIME_ZONE='Europe/Copenhagen') | ||||
| class DateFormatTests(SimpleTestCase): | ||||
| @@ -29,6 +34,18 @@ class DateFormatTests(SimpleTestCase): | ||||
|         dt = datetime(2009, 5, 16, 5, 30, 30) | ||||
|         self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt) | ||||
|  | ||||
|     def test_naive_ambiguous_datetime(self): | ||||
|         # dt is ambiguous in Europe/Copenhagen. LocalTimezone guesses the | ||||
|         # offset (and gets it wrong 50% of the time) while pytz refuses the | ||||
|         # temptation to guess. In any case, this shouldn't crash. | ||||
|         dt = datetime(2015, 10, 25, 2, 30, 0) | ||||
|  | ||||
|         # Try all formatters that involve self.timezone. | ||||
|         self.assertEqual(format(dt, 'I'), '0' if pytz is None else '') | ||||
|         self.assertEqual(format(dt, 'O'), '+0100' if pytz is None else '') | ||||
|         self.assertEqual(format(dt, 'T'), 'CET' if pytz is None else '') | ||||
|         self.assertEqual(format(dt, 'Z'), '3600' if pytz is None else '') | ||||
|  | ||||
|     @requires_tz_support | ||||
|     def test_datetime_with_local_tzinfo(self): | ||||
|         ltz = get_default_timezone() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user