summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2013-09-07 18:56:49 -0500
committerAymeric Augustin <aymeric.augustin@m4x.org>2013-09-08 02:04:43 -0500
commitded11aa620e5b38c78ff92e691a459d1977a2539 (patch)
tree71919fae5cc14901d3dc4b2047be56422069e1d9
parentb11564fd36587b1077bf7d77b62b7879cc08c382 (diff)
Fixed #18766 -- Pointed to pytz when LocalTimezone fails.
Thanks void for the report.
-rw-r--r--django/utils/timezone.py25
-rw-r--r--tests/utils_tests/test_timezone.py7
2 files changed, 30 insertions, 2 deletions
diff --git a/django/utils/timezone.py b/django/utils/timezone.py
index 3493e056fb..93ef4dfd57 100644
--- a/django/utils/timezone.py
+++ b/django/utils/timezone.py
@@ -1,10 +1,12 @@
-"""Timezone helper functions.
+"""
+Timezone-related classes and functions.
This module uses pytz when it's available and fallbacks when it isn't.
"""
from datetime import datetime, timedelta, tzinfo
from threading import local
+import sys
import time as _time
try:
@@ -45,12 +47,14 @@ class UTC(tzinfo):
def dst(self, dt):
return ZERO
-class LocalTimezone(tzinfo):
+class ReferenceLocalTimezone(tzinfo):
"""
Local time implementation taken from Python's docs.
Used only when pytz isn't available, and most likely inaccurate. If you're
having trouble with this class, don't waste your time, just install pytz.
+
+ Kept identical to the reference version. Subclasses contain improvements.
"""
def __init__(self):
@@ -91,6 +95,23 @@ class LocalTimezone(tzinfo):
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
+class LocalTimezone(ReferenceLocalTimezone):
+ """
+ Slightly improved local time implementation focusing on correctness.
+
+ It still crashes on dates before 1970 or after 2038, but at least the
+ error message is helpful.
+ """
+
+ def _isdst(self, dt):
+ try:
+ return super(LocalTimezone, self)._isdst(dt)
+ except (OverflowError, ValueError) as exc:
+ exc_type = type(exc)
+ exc_value = exc_type(
+ "Unsupported value: %r. You should install pytz." % dt)
+ exc_value.__cause__ = exc
+ six.reraise(exc_type, exc_value, sys.exc_info()[2])
utc = pytz.utc if pytz else UTC()
"""UTC time zone as a tzinfo instance."""
diff --git a/tests/utils_tests/test_timezone.py b/tests/utils_tests/test_timezone.py
index 2a13c10d7c..d0fbc54840 100644
--- a/tests/utils_tests/test_timezone.py
+++ b/tests/utils_tests/test_timezone.py
@@ -4,6 +4,7 @@ import pickle
import unittest
from django.test.utils import override_settings
+from django.utils import six
from django.utils import timezone
from django.utils.tzinfo import FixedOffset
@@ -20,6 +21,12 @@ class TimezoneTests(unittest.TestCase):
local_now = timezone.localtime(now, local_tz)
self.assertEqual(local_now.tzinfo, local_tz)
+ def test_localtime_out_of_range(self):
+ local_tz = timezone.LocalTimezone()
+ long_ago = datetime.datetime(1900, 1, 1, tzinfo=timezone.utc)
+ with six.assertRaisesRegex(self, OverflowError, "install pytz"):
+ timezone.localtime(long_ago, local_tz)
+
def test_now(self):
with override_settings(USE_TZ=True):
self.assertTrue(timezone.is_aware(timezone.now()))