[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:
parent
f5e1d72de2
commit
ca0278f496
|
@ -136,6 +136,8 @@ class TimeFormat(Formatter):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
seconds = self.Z()
|
seconds = self.Z()
|
||||||
|
if seconds == "":
|
||||||
|
return ""
|
||||||
sign = '-' if seconds < 0 else '+'
|
sign = '-' if seconds < 0 else '+'
|
||||||
seconds = abs(seconds)
|
seconds = abs(seconds)
|
||||||
return "%s%02d%02d" % (sign, seconds // 3600, (seconds // 60) % 60)
|
return "%s%02d%02d" % (sign, seconds // 3600, (seconds // 60) % 60)
|
||||||
|
@ -167,7 +169,14 @@ class TimeFormat(Formatter):
|
||||||
if not self.timezone:
|
if not self.timezone:
|
||||||
return ""
|
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:
|
if name is None:
|
||||||
name = self.format('O')
|
name = self.format('O')
|
||||||
return six.text_type(name)
|
return six.text_type(name)
|
||||||
|
@ -188,7 +197,14 @@ class TimeFormat(Formatter):
|
||||||
if not self.timezone:
|
if not self.timezone:
|
||||||
return ""
|
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
|
# `offset` is a datetime.timedelta. For negative values (to the west of
|
||||||
# UTC) only days can be negative (days=-1) and seconds are always
|
# UTC) only days can be negative (days=-1) and seconds are always
|
||||||
# positive. e.g. UTC-1 -> timedelta(days=-1, seconds=82800, microseconds=0)
|
# positive. e.g. UTC-1 -> timedelta(days=-1, seconds=82800, microseconds=0)
|
||||||
|
@ -228,10 +244,16 @@ class DateFormat(TimeFormat):
|
||||||
|
|
||||||
def I(self):
|
def I(self):
|
||||||
"'1' if Daylight Savings Time, '0' otherwise."
|
"'1' if Daylight Savings Time, '0' otherwise."
|
||||||
if self.timezone and self.timezone.dst(self.data):
|
try:
|
||||||
return '1'
|
if self.timezone and self.timezone.dst(self.data):
|
||||||
else:
|
return '1'
|
||||||
return '0'
|
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):
|
def j(self):
|
||||||
"Day of the month without leading zeros; i.e. '1' to '31'"
|
"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
|
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,
|
get_default_timezone, get_fixed_timezone, make_aware, utc,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pytz
|
||||||
|
except ImportError:
|
||||||
|
pytz = None
|
||||||
|
|
||||||
|
|
||||||
@override_settings(TIME_ZONE='Europe/Copenhagen')
|
@override_settings(TIME_ZONE='Europe/Copenhagen')
|
||||||
class DateFormatTests(SimpleTestCase):
|
class DateFormatTests(SimpleTestCase):
|
||||||
|
@ -29,6 +34,18 @@ class DateFormatTests(SimpleTestCase):
|
||||||
dt = datetime(2009, 5, 16, 5, 30, 30)
|
dt = datetime(2009, 5, 16, 5, 30, 30)
|
||||||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt)
|
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
|
@requires_tz_support
|
||||||
def test_datetime_with_local_tzinfo(self):
|
def test_datetime_with_local_tzinfo(self):
|
||||||
ltz = get_default_timezone()
|
ltz = get_default_timezone()
|
||||||
|
|
Loading…
Reference in New Issue