test_timezones.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. from datetime import (
  2. datetime,
  3. timedelta,
  4. timezone,
  5. )
  6. import dateutil.tz
  7. import pytest
  8. import pytz
  9. from pandas._libs.tslibs import (
  10. conversion,
  11. timezones,
  12. )
  13. from pandas.compat import is_platform_windows
  14. from pandas import Timestamp
  15. def test_is_utc(utc_fixture):
  16. tz = timezones.maybe_get_tz(utc_fixture)
  17. assert timezones.is_utc(tz)
  18. @pytest.mark.parametrize("tz_name", list(pytz.common_timezones))
  19. def test_cache_keys_are_distinct_for_pytz_vs_dateutil(tz_name):
  20. tz_p = timezones.maybe_get_tz(tz_name)
  21. tz_d = timezones.maybe_get_tz("dateutil/" + tz_name)
  22. if tz_d is None:
  23. pytest.skip(tz_name + ": dateutil does not know about this one")
  24. if not (tz_name == "UTC" and is_platform_windows()):
  25. # they both end up as tzwin("UTC") on windows
  26. assert timezones._p_tz_cache_key(tz_p) != timezones._p_tz_cache_key(tz_d)
  27. def test_tzlocal_repr():
  28. # see gh-13583
  29. ts = Timestamp("2011-01-01", tz=dateutil.tz.tzlocal())
  30. assert ts.tz == dateutil.tz.tzlocal()
  31. assert "tz='tzlocal()')" in repr(ts)
  32. def test_tzlocal_maybe_get_tz():
  33. # see gh-13583
  34. tz = timezones.maybe_get_tz("tzlocal()")
  35. assert tz == dateutil.tz.tzlocal()
  36. def test_tzlocal_offset():
  37. # see gh-13583
  38. #
  39. # Get offset using normal datetime for test.
  40. ts = Timestamp("2011-01-01", tz=dateutil.tz.tzlocal())
  41. offset = dateutil.tz.tzlocal().utcoffset(datetime(2011, 1, 1))
  42. offset = offset.total_seconds()
  43. assert ts._value + offset == Timestamp("2011-01-01")._value
  44. def test_tzlocal_is_not_utc():
  45. # even if the machine running the test is localized to UTC
  46. tz = dateutil.tz.tzlocal()
  47. assert not timezones.is_utc(tz)
  48. assert not timezones.tz_compare(tz, dateutil.tz.tzutc())
  49. def test_tz_compare_utc(utc_fixture, utc_fixture2):
  50. tz = timezones.maybe_get_tz(utc_fixture)
  51. tz2 = timezones.maybe_get_tz(utc_fixture2)
  52. assert timezones.tz_compare(tz, tz2)
  53. @pytest.fixture(
  54. params=[
  55. (pytz.timezone("US/Eastern"), lambda tz, x: tz.localize(x)),
  56. (dateutil.tz.gettz("US/Eastern"), lambda tz, x: x.replace(tzinfo=tz)),
  57. ]
  58. )
  59. def infer_setup(request):
  60. eastern, localize = request.param
  61. start_naive = datetime(2001, 1, 1)
  62. end_naive = datetime(2009, 1, 1)
  63. start = localize(eastern, start_naive)
  64. end = localize(eastern, end_naive)
  65. return eastern, localize, start, end, start_naive, end_naive
  66. def test_infer_tz_compat(infer_setup):
  67. eastern, _, start, end, start_naive, end_naive = infer_setup
  68. assert (
  69. timezones.infer_tzinfo(start, end)
  70. is conversion.localize_pydatetime(start_naive, eastern).tzinfo
  71. )
  72. assert (
  73. timezones.infer_tzinfo(start, None)
  74. is conversion.localize_pydatetime(start_naive, eastern).tzinfo
  75. )
  76. assert (
  77. timezones.infer_tzinfo(None, end)
  78. is conversion.localize_pydatetime(end_naive, eastern).tzinfo
  79. )
  80. def test_infer_tz_utc_localize(infer_setup):
  81. _, _, start, end, start_naive, end_naive = infer_setup
  82. utc = pytz.utc
  83. start = utc.localize(start_naive)
  84. end = utc.localize(end_naive)
  85. assert timezones.infer_tzinfo(start, end) is utc
  86. @pytest.mark.parametrize("ordered", [True, False])
  87. def test_infer_tz_mismatch(infer_setup, ordered):
  88. eastern, _, _, _, start_naive, end_naive = infer_setup
  89. msg = "Inputs must both have the same timezone"
  90. utc = pytz.utc
  91. start = utc.localize(start_naive)
  92. end = conversion.localize_pydatetime(end_naive, eastern)
  93. args = (start, end) if ordered else (end, start)
  94. with pytest.raises(AssertionError, match=msg):
  95. timezones.infer_tzinfo(*args)
  96. def test_maybe_get_tz_invalid_types():
  97. with pytest.raises(TypeError, match="<class 'float'>"):
  98. timezones.maybe_get_tz(44.0)
  99. with pytest.raises(TypeError, match="<class 'module'>"):
  100. timezones.maybe_get_tz(pytz)
  101. msg = "<class 'pandas._libs.tslibs.timestamps.Timestamp'>"
  102. with pytest.raises(TypeError, match=msg):
  103. timezones.maybe_get_tz(Timestamp("2021-01-01", tz="UTC"))
  104. def test_maybe_get_tz_offset_only():
  105. # see gh-36004
  106. # timezone.utc
  107. tz = timezones.maybe_get_tz(timezone.utc)
  108. assert tz == timezone(timedelta(hours=0, minutes=0))
  109. # without UTC+- prefix
  110. tz = timezones.maybe_get_tz("+01:15")
  111. assert tz == timezone(timedelta(hours=1, minutes=15))
  112. tz = timezones.maybe_get_tz("-01:15")
  113. assert tz == timezone(-timedelta(hours=1, minutes=15))
  114. # with UTC+- prefix
  115. tz = timezones.maybe_get_tz("UTC+02:45")
  116. assert tz == timezone(timedelta(hours=2, minutes=45))
  117. tz = timezones.maybe_get_tz("UTC-02:45")
  118. assert tz == timezone(-timedelta(hours=2, minutes=45))