1from datetime import datetime 2 3import numpy as np 4import pytest 5from pytz import UTC 6 7from pandas._libs.tslibs import ( 8 OutOfBoundsTimedelta, 9 conversion, 10 iNaT, 11 timezones, 12 tzconversion, 13) 14 15from pandas import Timestamp, date_range 16import pandas._testing as tm 17 18 19def _compare_utc_to_local(tz_didx): 20 def f(x): 21 return tzconversion.tz_convert_from_utc_single(x, tz_didx.tz) 22 23 result = tzconversion.tz_convert_from_utc(tz_didx.asi8, tz_didx.tz) 24 expected = np.vectorize(f)(tz_didx.asi8) 25 26 tm.assert_numpy_array_equal(result, expected) 27 28 29def _compare_local_to_utc(tz_didx, naive_didx): 30 # Check that tz_localize behaves the same vectorized and pointwise. 31 err1 = err2 = None 32 try: 33 result = tzconversion.tz_localize_to_utc(naive_didx.asi8, tz_didx.tz) 34 err1 = None 35 except Exception as err: 36 err1 = err 37 38 try: 39 expected = naive_didx.map(lambda x: x.tz_localize(tz_didx.tz)).asi8 40 except Exception as err: 41 err2 = err 42 43 if err1 is not None: 44 assert type(err1) == type(err2) 45 else: 46 assert err2 is None 47 tm.assert_numpy_array_equal(result, expected) 48 49 50def test_tz_convert_single_matches_tz_convert_hourly(tz_aware_fixture): 51 tz = tz_aware_fixture 52 tz_didx = date_range("2014-03-01", "2015-01-10", freq="H", tz=tz) 53 naive_didx = date_range("2014-03-01", "2015-01-10", freq="H") 54 55 _compare_utc_to_local(tz_didx) 56 _compare_local_to_utc(tz_didx, naive_didx) 57 58 59@pytest.mark.parametrize("freq", ["D", "A"]) 60def test_tz_convert_single_matches_tz_convert(tz_aware_fixture, freq): 61 tz = tz_aware_fixture 62 tz_didx = date_range("2000-01-01", "2020-01-01", freq=freq, tz=tz) 63 naive_didx = date_range("2000-01-01", "2020-01-01", freq=freq) 64 65 _compare_utc_to_local(tz_didx) 66 _compare_local_to_utc(tz_didx, naive_didx) 67 68 69@pytest.mark.parametrize( 70 "arr", 71 [ 72 pytest.param(np.array([], dtype=np.int64), id="empty"), 73 pytest.param(np.array([iNaT], dtype=np.int64), id="all_nat"), 74 ], 75) 76def test_tz_convert_corner(arr): 77 result = tzconversion.tz_convert_from_utc(arr, timezones.maybe_get_tz("Asia/Tokyo")) 78 tm.assert_numpy_array_equal(result, arr) 79 80 81def test_tz_convert_readonly(): 82 # GH#35530 83 arr = np.array([0], dtype=np.int64) 84 arr.setflags(write=False) 85 result = tzconversion.tz_convert_from_utc(arr, UTC) 86 tm.assert_numpy_array_equal(result, arr) 87 88 89@pytest.mark.parametrize("copy", [True, False]) 90@pytest.mark.parametrize("dtype", ["M8[ns]", "M8[s]"]) 91def test_length_zero_copy(dtype, copy): 92 arr = np.array([], dtype=dtype) 93 result = conversion.ensure_datetime64ns(arr, copy=copy) 94 assert result.base is (None if copy else arr) 95 96 97def test_ensure_datetime64ns_bigendian(): 98 # GH#29684 99 arr = np.array([np.datetime64(1, "ms")], dtype=">M8[ms]") 100 result = conversion.ensure_datetime64ns(arr) 101 102 expected = np.array([np.datetime64(1, "ms")], dtype="M8[ns]") 103 tm.assert_numpy_array_equal(result, expected) 104 105 106def test_ensure_timedelta64ns_overflows(): 107 arr = np.arange(10).astype("m8[Y]") * 100 108 msg = r"Out of bounds for nanosecond timedelta64\[Y\] 900" 109 with pytest.raises(OutOfBoundsTimedelta, match=msg): 110 conversion.ensure_timedelta64ns(arr) 111 112 113class SubDatetime(datetime): 114 pass 115 116 117@pytest.mark.parametrize( 118 "dt, expected", 119 [ 120 pytest.param( 121 Timestamp("2000-01-01"), Timestamp("2000-01-01", tz=UTC), id="timestamp" 122 ), 123 pytest.param( 124 datetime(2000, 1, 1), datetime(2000, 1, 1, tzinfo=UTC), id="datetime" 125 ), 126 pytest.param( 127 SubDatetime(2000, 1, 1), 128 SubDatetime(2000, 1, 1, tzinfo=UTC), 129 id="subclassed_datetime", 130 ), 131 ], 132) 133def test_localize_pydatetime_dt_types(dt, expected): 134 # GH 25851 135 # ensure that subclassed datetime works with 136 # localize_pydatetime 137 result = conversion.localize_pydatetime(dt, UTC) 138 assert result == expected 139