diff options
| author | Paul Ganssle <paul@ganssle.io> | 2021-01-19 11:16:01 +0100 |
|---|---|---|
| committer | Carlton Gibson <carlton.gibson@noumenal.es> | 2021-01-19 12:00:40 +0100 |
| commit | a5d70cca12aaa1067871eb4e67ab2ed088d1edd6 (patch) | |
| tree | 9cee8f3ffda53629160df0fab580d8e03ae13ce7 /tests/utils_tests/test_timezone.py | |
| parent | de4e854f079dd3a638b9919ad73e5835d5e90d3f (diff) | |
[3.2.x] Refs #32365 -- Allowed use of non-pytz timezone implementations.
Backport of 10d126198434810529e0220b0c6896ed64ca0e88 from master
Diffstat (limited to 'tests/utils_tests/test_timezone.py')
| -rw-r--r-- | tests/utils_tests/test_timezone.py | 82 |
1 files changed, 78 insertions, 4 deletions
diff --git a/tests/utils_tests/test_timezone.py b/tests/utils_tests/test_timezone.py index bfd71fb506..2e28d3a9a5 100644 --- a/tests/utils_tests/test_timezone.py +++ b/tests/utils_tests/test_timezone.py @@ -1,14 +1,38 @@ import datetime +import unittest from unittest import mock import pytz +try: + import zoneinfo +except ImportError: + try: + from backports import zoneinfo + except ImportError: + zoneinfo = None + from django.test import SimpleTestCase, override_settings from django.utils import timezone CET = pytz.timezone("Europe/Paris") EAT = timezone.get_fixed_timezone(180) # Africa/Nairobi ICT = timezone.get_fixed_timezone(420) # Asia/Bangkok +UTC = datetime.timezone.utc + +HAS_ZONEINFO = zoneinfo is not None + +if not HAS_ZONEINFO: + PARIS_ZI = None + PARIS_IMPLS = (CET,) + + needs_zoneinfo = unittest.skip("Test requires zoneinfo") +else: + PARIS_ZI = zoneinfo.ZoneInfo('Europe/Paris') + PARIS_IMPLS = (CET, PARIS_ZI) + + def needs_zoneinfo(f): + return f class TimezoneTests(SimpleTestCase): @@ -142,13 +166,21 @@ class TimezoneTests(SimpleTestCase): ) def test_make_aware2(self): - self.assertEqual( - timezone.make_aware(datetime.datetime(2011, 9, 1, 12, 20, 30), CET), - CET.localize(datetime.datetime(2011, 9, 1, 12, 20, 30))) + CEST = datetime.timezone(datetime.timedelta(hours=2), 'CEST') + for tz in PARIS_IMPLS: + with self.subTest(repr(tz)): + self.assertEqual( + timezone.make_aware(datetime.datetime(2011, 9, 1, 12, 20, 30), tz), + datetime.datetime(2011, 9, 1, 12, 20, 30, tzinfo=CEST)) + with self.assertRaises(ValueError): timezone.make_aware(CET.localize(datetime.datetime(2011, 9, 1, 12, 20, 30)), CET) - def test_make_aware_pytz(self): + if HAS_ZONEINFO: + with self.assertRaises(ValueError): + timezone.make_aware(datetime.datetime(2011, 9, 1, 12, 20, 30, tzinfo=PARIS_ZI), PARIS_ZI) + + def test_make_naive_pytz(self): self.assertEqual( timezone.make_naive(CET.localize(datetime.datetime(2011, 9, 1, 12, 20, 30)), CET), datetime.datetime(2011, 9, 1, 12, 20, 30)) @@ -160,6 +192,18 @@ class TimezoneTests(SimpleTestCase): with self.assertRaisesMessage(ValueError, 'make_naive() cannot be applied to a naive datetime'): timezone.make_naive(datetime.datetime(2011, 9, 1, 12, 20, 30), CET) + @needs_zoneinfo + def test_make_naive_zoneinfo(self): + self.assertEqual( + timezone.make_naive(datetime.datetime(2011, 9, 1, 12, 20, 30, tzinfo=PARIS_ZI), PARIS_ZI), + datetime.datetime(2011, 9, 1, 12, 20, 30) + ) + + self.assertEqual( + timezone.make_naive(datetime.datetime(2011, 9, 1, 12, 20, 30, fold=1, tzinfo=PARIS_ZI), PARIS_ZI), + datetime.datetime(2011, 9, 1, 12, 20, 30, fold=1) + ) + def test_make_aware_pytz_ambiguous(self): # 2:30 happens twice, once before DST ends and once after ambiguous = datetime.datetime(2015, 10, 25, 2, 30) @@ -173,6 +217,21 @@ class TimezoneTests(SimpleTestCase): self.assertEqual(std.tzinfo.utcoffset(std), datetime.timedelta(hours=1)) self.assertEqual(dst.tzinfo.utcoffset(dst), datetime.timedelta(hours=2)) + @needs_zoneinfo + def test_make_aware_zoneinfo_ambiguous(self): + # 2:30 happens twice, once before DST ends and once after + ambiguous = datetime.datetime(2015, 10, 25, 2, 30) + + std = timezone.make_aware(ambiguous.replace(fold=1), timezone=PARIS_ZI) + dst = timezone.make_aware(ambiguous, timezone=PARIS_ZI) + + self.assertEqual( + std.astimezone(UTC) - dst.astimezone(UTC), + datetime.timedelta(hours=1) + ) + self.assertEqual(std.utcoffset(), datetime.timedelta(hours=1)) + self.assertEqual(dst.utcoffset(), datetime.timedelta(hours=2)) + def test_make_aware_pytz_non_existent(self): # 2:30 never happened due to DST non_existent = datetime.datetime(2015, 3, 29, 2, 30) @@ -186,6 +245,21 @@ class TimezoneTests(SimpleTestCase): self.assertEqual(std.tzinfo.utcoffset(std), datetime.timedelta(hours=1)) self.assertEqual(dst.tzinfo.utcoffset(dst), datetime.timedelta(hours=2)) + @needs_zoneinfo + def test_make_aware_zoneinfo_non_existent(self): + # 2:30 never happened due to DST + non_existent = datetime.datetime(2015, 3, 29, 2, 30) + + std = timezone.make_aware(non_existent, PARIS_ZI) + dst = timezone.make_aware(non_existent.replace(fold=1), PARIS_ZI) + + self.assertEqual( + std.astimezone(UTC) - dst.astimezone(UTC), + datetime.timedelta(hours=1) + ) + self.assertEqual(std.utcoffset(), datetime.timedelta(hours=1)) + self.assertEqual(dst.utcoffset(), datetime.timedelta(hours=2)) + def test_get_default_timezone(self): self.assertEqual(timezone.get_default_timezone_name(), 'America/Chicago') |
