test_timezone.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import copy
  2. import datetime
  3. import pickle
  4. import unittest
  5. from django.test import override_settings
  6. from django.utils import timezone
  7. try:
  8. import pytz
  9. except ImportError:
  10. pytz = None
  11. if pytz is not None:
  12. CET = pytz.timezone("Europe/Paris")
  13. EAT = timezone.get_fixed_timezone(180) # Africa/Nairobi
  14. ICT = timezone.get_fixed_timezone(420) # Asia/Bangkok
  15. class TimezoneTests(unittest.TestCase):
  16. def test_localtime(self):
  17. now = datetime.datetime.utcnow().replace(tzinfo=timezone.utc)
  18. local_tz = timezone.LocalTimezone()
  19. local_now = timezone.localtime(now, local_tz)
  20. self.assertEqual(local_now.tzinfo, local_tz)
  21. def test_localtime_naive(self):
  22. with self.assertRaises(ValueError):
  23. timezone.localtime(datetime.datetime.now())
  24. def test_localtime_out_of_range(self):
  25. local_tz = timezone.LocalTimezone()
  26. long_ago = datetime.datetime(1900, 1, 1, tzinfo=timezone.utc)
  27. try:
  28. timezone.localtime(long_ago, local_tz)
  29. except (OverflowError, ValueError) as exc:
  30. self.assertIn("install pytz", exc.args[0])
  31. else:
  32. raise unittest.SkipTest("Failed to trigger an OverflowError or ValueError")
  33. def test_now(self):
  34. with override_settings(USE_TZ=True):
  35. self.assertTrue(timezone.is_aware(timezone.now()))
  36. with override_settings(USE_TZ=False):
  37. self.assertTrue(timezone.is_naive(timezone.now()))
  38. def test_override(self):
  39. default = timezone.get_default_timezone()
  40. try:
  41. timezone.activate(ICT)
  42. with timezone.override(EAT):
  43. self.assertIs(EAT, timezone.get_current_timezone())
  44. self.assertIs(ICT, timezone.get_current_timezone())
  45. with timezone.override(None):
  46. self.assertIs(default, timezone.get_current_timezone())
  47. self.assertIs(ICT, timezone.get_current_timezone())
  48. timezone.deactivate()
  49. with timezone.override(EAT):
  50. self.assertIs(EAT, timezone.get_current_timezone())
  51. self.assertIs(default, timezone.get_current_timezone())
  52. with timezone.override(None):
  53. self.assertIs(default, timezone.get_current_timezone())
  54. self.assertIs(default, timezone.get_current_timezone())
  55. finally:
  56. timezone.deactivate()
  57. def test_override_decorator(self):
  58. default = timezone.get_default_timezone()
  59. @timezone.override(EAT)
  60. def func_tz_eat():
  61. self.assertIs(EAT, timezone.get_current_timezone())
  62. @timezone.override(None)
  63. def func_tz_none():
  64. self.assertIs(default, timezone.get_current_timezone())
  65. try:
  66. timezone.activate(ICT)
  67. func_tz_eat()
  68. self.assertIs(ICT, timezone.get_current_timezone())
  69. func_tz_none()
  70. self.assertIs(ICT, timezone.get_current_timezone())
  71. timezone.deactivate()
  72. func_tz_eat()
  73. self.assertIs(default, timezone.get_current_timezone())
  74. func_tz_none()
  75. self.assertIs(default, timezone.get_current_timezone())
  76. finally:
  77. timezone.deactivate()
  78. def test_copy(self):
  79. self.assertIsInstance(copy.copy(timezone.UTC()), timezone.UTC)
  80. self.assertIsInstance(copy.copy(timezone.LocalTimezone()), timezone.LocalTimezone)
  81. def test_deepcopy(self):
  82. self.assertIsInstance(copy.deepcopy(timezone.UTC()), timezone.UTC)
  83. self.assertIsInstance(copy.deepcopy(timezone.LocalTimezone()), timezone.LocalTimezone)
  84. def test_pickling_unpickling(self):
  85. self.assertIsInstance(pickle.loads(pickle.dumps(timezone.UTC())), timezone.UTC)
  86. self.assertIsInstance(pickle.loads(pickle.dumps(timezone.LocalTimezone())), timezone.LocalTimezone)
  87. def test_is_aware(self):
  88. self.assertTrue(timezone.is_aware(datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT)))
  89. self.assertFalse(timezone.is_aware(datetime.datetime(2011, 9, 1, 13, 20, 30)))
  90. def test_is_naive(self):
  91. self.assertFalse(timezone.is_naive(datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT)))
  92. self.assertTrue(timezone.is_naive(datetime.datetime(2011, 9, 1, 13, 20, 30)))
  93. def test_make_aware(self):
  94. self.assertEqual(
  95. timezone.make_aware(datetime.datetime(2011, 9, 1, 13, 20, 30), EAT),
  96. datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT))
  97. with self.assertRaises(ValueError):
  98. timezone.make_aware(datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT), EAT)
  99. def test_make_naive(self):
  100. self.assertEqual(
  101. timezone.make_naive(datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT), EAT),
  102. datetime.datetime(2011, 9, 1, 13, 20, 30))
  103. self.assertEqual(
  104. timezone.make_naive(datetime.datetime(2011, 9, 1, 17, 20, 30, tzinfo=ICT), EAT),
  105. datetime.datetime(2011, 9, 1, 13, 20, 30))
  106. with self.assertRaises(ValueError):
  107. timezone.make_naive(datetime.datetime(2011, 9, 1, 13, 20, 30), EAT)
  108. @unittest.skipIf(pytz is None, "this test requires pytz")
  109. def test_make_aware2(self):
  110. self.assertEqual(
  111. timezone.make_aware(datetime.datetime(2011, 9, 1, 12, 20, 30), CET),
  112. CET.localize(datetime.datetime(2011, 9, 1, 12, 20, 30)))
  113. with self.assertRaises(ValueError):
  114. timezone.make_aware(CET.localize(datetime.datetime(2011, 9, 1, 12, 20, 30)), CET)
  115. @unittest.skipIf(pytz is None, "this test requires pytz")
  116. def test_make_aware_pytz(self):
  117. self.assertEqual(
  118. timezone.make_naive(CET.localize(datetime.datetime(2011, 9, 1, 12, 20, 30)), CET),
  119. datetime.datetime(2011, 9, 1, 12, 20, 30))
  120. self.assertEqual(
  121. timezone.make_naive(pytz.timezone("Asia/Bangkok").localize(datetime.datetime(2011, 9, 1, 17, 20, 30)), CET),
  122. datetime.datetime(2011, 9, 1, 12, 20, 30))
  123. with self.assertRaises(ValueError):
  124. timezone.make_naive(datetime.datetime(2011, 9, 1, 12, 20, 30), CET)
  125. @unittest.skipIf(pytz is None, "this test requires pytz")
  126. def test_make_aware_pytz_ambiguous(self):
  127. # 2:30 happens twice, once before DST ends and once after
  128. ambiguous = datetime.datetime(2015, 10, 25, 2, 30)
  129. with self.assertRaises(pytz.AmbiguousTimeError):
  130. timezone.make_aware(ambiguous, timezone=CET)
  131. std = timezone.make_aware(ambiguous, timezone=CET, is_dst=False)
  132. dst = timezone.make_aware(ambiguous, timezone=CET, is_dst=True)
  133. self.assertEqual(std - dst, datetime.timedelta(hours=1))
  134. self.assertEqual(std.tzinfo.utcoffset(std), datetime.timedelta(hours=1))
  135. self.assertEqual(dst.tzinfo.utcoffset(dst), datetime.timedelta(hours=2))
  136. @unittest.skipIf(pytz is None, "this test requires pytz")
  137. def test_make_aware_pytz_non_existent(self):
  138. # 2:30 never happened due to DST
  139. non_existent = datetime.datetime(2015, 3, 29, 2, 30)
  140. with self.assertRaises(pytz.NonExistentTimeError):
  141. timezone.make_aware(non_existent, timezone=CET)
  142. std = timezone.make_aware(non_existent, timezone=CET, is_dst=False)
  143. dst = timezone.make_aware(non_existent, timezone=CET, is_dst=True)
  144. self.assertEqual(std - dst, datetime.timedelta(hours=1))
  145. self.assertEqual(std.tzinfo.utcoffset(std), datetime.timedelta(hours=1))
  146. self.assertEqual(dst.tzinfo.utcoffset(dst), datetime.timedelta(hours=2))
  147. # round trip to UTC then back to CET
  148. std = timezone.localtime(timezone.localtime(std, timezone.UTC()), CET)
  149. dst = timezone.localtime(timezone.localtime(dst, timezone.UTC()), CET)
  150. self.assertEqual((std.hour, std.minute), (3, 30))
  151. self.assertEqual((dst.hour, dst.minute), (1, 30))