Updated script that can be controled by Nodejs web app

This commit is contained in:
mac OS
2024-11-25 12:24:18 +07:00
parent c440eda1f4
commit 8b0ab2bd3a
8662 changed files with 1803808 additions and 34 deletions

View File

@ -0,0 +1,30 @@
from datetime import timedelta
from pandas import (
Index,
Timestamp,
date_range,
isna,
)
class TestAsOf:
def test_asof_partial(self):
index = date_range("2010-01-01", periods=2, freq="ME")
expected = Timestamp("2010-02-28")
result = index.asof("2010-02")
assert result == expected
assert not isinstance(result, Index)
def test_asof(self):
index = date_range("2020-01-01", periods=10)
dt = index[0]
assert index.asof(dt) == dt
assert isna(index.asof(dt - timedelta(1)))
dt = index[-1]
assert index.asof(dt + timedelta(1)) == dt
dt = index[0].to_pydatetime()
assert isinstance(index.asof(dt), Timestamp)

View File

@ -0,0 +1,335 @@
from datetime import datetime
import dateutil
import numpy as np
import pytest
import pytz
import pandas as pd
from pandas import (
DatetimeIndex,
Index,
NaT,
PeriodIndex,
Timestamp,
date_range,
)
import pandas._testing as tm
class TestDatetimeIndex:
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
def test_dti_astype_asobject_around_dst_transition(self, tzstr):
# GH#1345
# dates around a dst transition
rng = date_range("2/13/2010", "5/6/2010", tz=tzstr)
objs = rng.astype(object)
for i, x in enumerate(objs):
exval = rng[i]
assert x == exval
assert x.tzinfo == exval.tzinfo
objs = rng.astype(object)
for i, x in enumerate(objs):
exval = rng[i]
assert x == exval
assert x.tzinfo == exval.tzinfo
def test_astype(self):
# GH 13149, GH 13209
idx = DatetimeIndex(
["2016-05-16", "NaT", NaT, np.nan], dtype="M8[ns]", name="idx"
)
result = idx.astype(object)
expected = Index(
[Timestamp("2016-05-16")] + [NaT] * 3, dtype=object, name="idx"
)
tm.assert_index_equal(result, expected)
result = idx.astype(np.int64)
expected = Index(
[1463356800000000000] + [-9223372036854775808] * 3,
dtype=np.int64,
name="idx",
)
tm.assert_index_equal(result, expected)
def test_astype2(self):
rng = date_range("1/1/2000", periods=10, name="idx")
result = rng.astype("i8")
tm.assert_index_equal(result, Index(rng.asi8, name="idx"))
tm.assert_numpy_array_equal(result.values, rng.asi8)
def test_astype_uint(self):
arr = date_range("2000", periods=2, name="idx")
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
arr.astype("uint64")
with pytest.raises(TypeError, match=r"Do obj.astype\('int64'\)"):
arr.astype("uint32")
def test_astype_with_tz(self):
# with tz
rng = date_range("1/1/2000", periods=10, tz="US/Eastern")
msg = "Cannot use .astype to convert from timezone-aware"
with pytest.raises(TypeError, match=msg):
# deprecated
rng.astype("datetime64[ns]")
with pytest.raises(TypeError, match=msg):
# check DatetimeArray while we're here deprecated
rng._data.astype("datetime64[ns]")
def test_astype_tzaware_to_tzaware(self):
# GH 18951: tz-aware to tz-aware
idx = date_range("20170101", periods=4, tz="US/Pacific")
result = idx.astype("datetime64[ns, US/Eastern]")
expected = date_range("20170101 03:00:00", periods=4, tz="US/Eastern")
tm.assert_index_equal(result, expected)
assert result.freq == expected.freq
def test_astype_tznaive_to_tzaware(self):
# GH 18951: tz-naive to tz-aware
idx = date_range("20170101", periods=4)
idx = idx._with_freq(None) # tz_localize does not preserve freq
msg = "Cannot use .astype to convert from timezone-naive"
with pytest.raises(TypeError, match=msg):
# dt64->dt64tz deprecated
idx.astype("datetime64[ns, US/Eastern]")
with pytest.raises(TypeError, match=msg):
# dt64->dt64tz deprecated
idx._data.astype("datetime64[ns, US/Eastern]")
def test_astype_str_nat(self):
# GH 13149, GH 13209
# verify that we are returning NaT as a string (and not unicode)
idx = DatetimeIndex(["2016-05-16", "NaT", NaT, np.nan])
result = idx.astype(str)
expected = Index(["2016-05-16", "NaT", "NaT", "NaT"], dtype=object)
tm.assert_index_equal(result, expected)
def test_astype_str(self):
# test astype string - #10442
dti = date_range("2012-01-01", periods=4, name="test_name")
result = dti.astype(str)
expected = Index(
["2012-01-01", "2012-01-02", "2012-01-03", "2012-01-04"],
name="test_name",
dtype=object,
)
tm.assert_index_equal(result, expected)
def test_astype_str_tz_and_name(self):
# test astype string with tz and name
dti = date_range("2012-01-01", periods=3, name="test_name", tz="US/Eastern")
result = dti.astype(str)
expected = Index(
[
"2012-01-01 00:00:00-05:00",
"2012-01-02 00:00:00-05:00",
"2012-01-03 00:00:00-05:00",
],
name="test_name",
dtype=object,
)
tm.assert_index_equal(result, expected)
def test_astype_str_freq_and_name(self):
# test astype string with freqH and name
dti = date_range("1/1/2011", periods=3, freq="h", name="test_name")
result = dti.astype(str)
expected = Index(
["2011-01-01 00:00:00", "2011-01-01 01:00:00", "2011-01-01 02:00:00"],
name="test_name",
dtype=object,
)
tm.assert_index_equal(result, expected)
def test_astype_str_freq_and_tz(self):
# test astype string with freqH and timezone
dti = date_range(
"3/6/2012 00:00", periods=2, freq="h", tz="Europe/London", name="test_name"
)
result = dti.astype(str)
expected = Index(
["2012-03-06 00:00:00+00:00", "2012-03-06 01:00:00+00:00"],
dtype=object,
name="test_name",
)
tm.assert_index_equal(result, expected)
def test_astype_datetime64(self):
# GH 13149, GH 13209
idx = DatetimeIndex(
["2016-05-16", "NaT", NaT, np.nan], dtype="M8[ns]", name="idx"
)
result = idx.astype("datetime64[ns]")
tm.assert_index_equal(result, idx)
assert result is not idx
result = idx.astype("datetime64[ns]", copy=False)
tm.assert_index_equal(result, idx)
assert result is idx
idx_tz = DatetimeIndex(["2016-05-16", "NaT", NaT, np.nan], tz="EST", name="idx")
msg = "Cannot use .astype to convert from timezone-aware"
with pytest.raises(TypeError, match=msg):
# dt64tz->dt64 deprecated
result = idx_tz.astype("datetime64[ns]")
def test_astype_object(self):
rng = date_range("1/1/2000", periods=20)
casted = rng.astype("O")
exp_values = list(rng)
tm.assert_index_equal(casted, Index(exp_values, dtype=np.object_))
assert casted.tolist() == exp_values
@pytest.mark.parametrize("tz", [None, "Asia/Tokyo"])
def test_astype_object_tz(self, tz):
idx = date_range(start="2013-01-01", periods=4, freq="ME", name="idx", tz=tz)
expected_list = [
Timestamp("2013-01-31", tz=tz),
Timestamp("2013-02-28", tz=tz),
Timestamp("2013-03-31", tz=tz),
Timestamp("2013-04-30", tz=tz),
]
expected = Index(expected_list, dtype=object, name="idx")
result = idx.astype(object)
tm.assert_index_equal(result, expected)
assert idx.tolist() == expected_list
def test_astype_object_with_nat(self):
idx = DatetimeIndex(
[datetime(2013, 1, 1), datetime(2013, 1, 2), NaT, datetime(2013, 1, 4)],
name="idx",
)
expected_list = [
Timestamp("2013-01-01"),
Timestamp("2013-01-02"),
NaT,
Timestamp("2013-01-04"),
]
expected = Index(expected_list, dtype=object, name="idx")
result = idx.astype(object)
tm.assert_index_equal(result, expected)
assert idx.tolist() == expected_list
@pytest.mark.parametrize(
"dtype",
[float, "timedelta64", "timedelta64[ns]", "datetime64", "datetime64[D]"],
)
def test_astype_raises(self, dtype):
# GH 13149, GH 13209
idx = DatetimeIndex(["2016-05-16", "NaT", NaT, np.nan])
msg = "Cannot cast DatetimeIndex to dtype"
if dtype == "datetime64":
msg = "Casting to unit-less dtype 'datetime64' is not supported"
with pytest.raises(TypeError, match=msg):
idx.astype(dtype)
def test_index_convert_to_datetime_array(self):
def _check_rng(rng):
converted = rng.to_pydatetime()
assert isinstance(converted, np.ndarray)
for x, stamp in zip(converted, rng):
assert isinstance(x, datetime)
assert x == stamp.to_pydatetime()
assert x.tzinfo == stamp.tzinfo
rng = date_range("20090415", "20090519")
rng_eastern = date_range("20090415", "20090519", tz="US/Eastern")
rng_utc = date_range("20090415", "20090519", tz="utc")
_check_rng(rng)
_check_rng(rng_eastern)
_check_rng(rng_utc)
def test_index_convert_to_datetime_array_explicit_pytz(self):
def _check_rng(rng):
converted = rng.to_pydatetime()
assert isinstance(converted, np.ndarray)
for x, stamp in zip(converted, rng):
assert isinstance(x, datetime)
assert x == stamp.to_pydatetime()
assert x.tzinfo == stamp.tzinfo
rng = date_range("20090415", "20090519")
rng_eastern = date_range("20090415", "20090519", tz=pytz.timezone("US/Eastern"))
rng_utc = date_range("20090415", "20090519", tz=pytz.utc)
_check_rng(rng)
_check_rng(rng_eastern)
_check_rng(rng_utc)
def test_index_convert_to_datetime_array_dateutil(self):
def _check_rng(rng):
converted = rng.to_pydatetime()
assert isinstance(converted, np.ndarray)
for x, stamp in zip(converted, rng):
assert isinstance(x, datetime)
assert x == stamp.to_pydatetime()
assert x.tzinfo == stamp.tzinfo
rng = date_range("20090415", "20090519")
rng_eastern = date_range("20090415", "20090519", tz="dateutil/US/Eastern")
rng_utc = date_range("20090415", "20090519", tz=dateutil.tz.tzutc())
_check_rng(rng)
_check_rng(rng_eastern)
_check_rng(rng_utc)
@pytest.mark.parametrize(
"tz, dtype",
[["US/Pacific", "datetime64[ns, US/Pacific]"], [None, "datetime64[ns]"]],
)
def test_integer_index_astype_datetime(self, tz, dtype):
# GH 20997, 20964, 24559
val = [Timestamp("2018-01-01", tz=tz).as_unit("ns")._value]
result = Index(val, name="idx").astype(dtype)
expected = DatetimeIndex(["2018-01-01"], tz=tz, name="idx").as_unit("ns")
tm.assert_index_equal(result, expected)
def test_dti_astype_period(self):
idx = DatetimeIndex([NaT, "2011-01-01", "2011-02-01"], name="idx")
res = idx.astype("period[M]")
exp = PeriodIndex(["NaT", "2011-01", "2011-02"], freq="M", name="idx")
tm.assert_index_equal(res, exp)
res = idx.astype("period[3M]")
exp = PeriodIndex(["NaT", "2011-01", "2011-02"], freq="3M", name="idx")
tm.assert_index_equal(res, exp)
class TestAstype:
@pytest.mark.parametrize("tz", [None, "US/Central"])
def test_astype_category(self, tz):
obj = date_range("2000", periods=2, tz=tz, name="idx")
result = obj.astype("category")
dti = DatetimeIndex(["2000-01-01", "2000-01-02"], tz=tz).as_unit("ns")
expected = pd.CategoricalIndex(
dti,
name="idx",
)
tm.assert_index_equal(result, expected)
result = obj._data.astype("category")
expected = expected.values
tm.assert_categorical_equal(result, expected)
@pytest.mark.parametrize("tz", [None, "US/Central"])
def test_astype_array_fallback(self, tz):
obj = date_range("2000", periods=2, tz=tz, name="idx")
result = obj.astype(bool)
expected = Index(np.array([True, True]), name="idx")
tm.assert_index_equal(result, expected)
result = obj._data.astype(bool)
expected = np.array([True, True])
tm.assert_numpy_array_equal(result, expected)

View File

@ -0,0 +1,141 @@
import pytest
from pandas import (
DatetimeIndex,
Series,
date_range,
)
import pandas._testing as tm
class TestDelete:
def test_delete(self, unit):
idx = date_range(
start="2000-01-01", periods=5, freq="ME", name="idx", unit=unit
)
# preserve freq
expected_0 = date_range(
start="2000-02-01", periods=4, freq="ME", name="idx", unit=unit
)
expected_4 = date_range(
start="2000-01-01", periods=4, freq="ME", name="idx", unit=unit
)
# reset freq to None
expected_1 = DatetimeIndex(
["2000-01-31", "2000-03-31", "2000-04-30", "2000-05-31"],
freq=None,
name="idx",
).as_unit(unit)
cases = {
0: expected_0,
-5: expected_0,
-1: expected_4,
4: expected_4,
1: expected_1,
}
for n, expected in cases.items():
result = idx.delete(n)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq == expected.freq
with pytest.raises((IndexError, ValueError), match="out of bounds"):
# either depending on numpy version
idx.delete(5)
@pytest.mark.parametrize("tz", [None, "Asia/Tokyo", "US/Pacific"])
def test_delete2(self, tz):
idx = date_range(
start="2000-01-01 09:00", periods=10, freq="h", name="idx", tz=tz
)
expected = date_range(
start="2000-01-01 10:00", periods=9, freq="h", name="idx", tz=tz
)
result = idx.delete(0)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freqstr == "h"
assert result.tz == expected.tz
expected = date_range(
start="2000-01-01 09:00", periods=9, freq="h", name="idx", tz=tz
)
result = idx.delete(-1)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freqstr == "h"
assert result.tz == expected.tz
def test_delete_slice(self, unit):
idx = date_range(
start="2000-01-01", periods=10, freq="D", name="idx", unit=unit
)
# preserve freq
expected_0_2 = date_range(
start="2000-01-04", periods=7, freq="D", name="idx", unit=unit
)
expected_7_9 = date_range(
start="2000-01-01", periods=7, freq="D", name="idx", unit=unit
)
# reset freq to None
expected_3_5 = DatetimeIndex(
[
"2000-01-01",
"2000-01-02",
"2000-01-03",
"2000-01-07",
"2000-01-08",
"2000-01-09",
"2000-01-10",
],
freq=None,
name="idx",
).as_unit(unit)
cases = {
(0, 1, 2): expected_0_2,
(7, 8, 9): expected_7_9,
(3, 4, 5): expected_3_5,
}
for n, expected in cases.items():
result = idx.delete(n)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq == expected.freq
result = idx.delete(slice(n[0], n[-1] + 1))
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq == expected.freq
# TODO: belongs in Series.drop tests?
@pytest.mark.parametrize("tz", [None, "Asia/Tokyo", "US/Pacific"])
def test_delete_slice2(self, tz, unit):
dti = date_range(
"2000-01-01 09:00", periods=10, freq="h", name="idx", tz=tz, unit=unit
)
ts = Series(
1,
index=dti,
)
# preserve freq
result = ts.drop(ts.index[:5]).index
expected = dti[5:]
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq == expected.freq
assert result.tz == expected.tz
# reset freq to None
result = ts.drop(ts.index[[1, 3, 5, 7, 9]]).index
expected = dti[::2]._with_freq(None)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq == expected.freq
assert result.tz == expected.tz

View File

@ -0,0 +1,125 @@
import numpy as np
import pytest
from pandas import (
DatetimeIndex,
Index,
date_range,
factorize,
)
import pandas._testing as tm
class TestDatetimeIndexFactorize:
def test_factorize(self):
idx1 = DatetimeIndex(
["2014-01", "2014-01", "2014-02", "2014-02", "2014-03", "2014-03"]
)
exp_arr = np.array([0, 0, 1, 1, 2, 2], dtype=np.intp)
exp_idx = DatetimeIndex(["2014-01", "2014-02", "2014-03"])
arr, idx = idx1.factorize()
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, exp_idx)
assert idx.freq == exp_idx.freq
arr, idx = idx1.factorize(sort=True)
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, exp_idx)
assert idx.freq == exp_idx.freq
# tz must be preserved
idx1 = idx1.tz_localize("Asia/Tokyo")
exp_idx = exp_idx.tz_localize("Asia/Tokyo")
arr, idx = idx1.factorize()
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, exp_idx)
assert idx.freq == exp_idx.freq
idx2 = DatetimeIndex(
["2014-03", "2014-03", "2014-02", "2014-01", "2014-03", "2014-01"]
)
exp_arr = np.array([2, 2, 1, 0, 2, 0], dtype=np.intp)
exp_idx = DatetimeIndex(["2014-01", "2014-02", "2014-03"])
arr, idx = idx2.factorize(sort=True)
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, exp_idx)
assert idx.freq == exp_idx.freq
exp_arr = np.array([0, 0, 1, 2, 0, 2], dtype=np.intp)
exp_idx = DatetimeIndex(["2014-03", "2014-02", "2014-01"])
arr, idx = idx2.factorize()
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, exp_idx)
assert idx.freq == exp_idx.freq
def test_factorize_preserves_freq(self):
# GH#38120 freq should be preserved
idx3 = date_range("2000-01", periods=4, freq="ME", tz="Asia/Tokyo")
exp_arr = np.array([0, 1, 2, 3], dtype=np.intp)
arr, idx = idx3.factorize()
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, idx3)
assert idx.freq == idx3.freq
arr, idx = factorize(idx3)
tm.assert_numpy_array_equal(arr, exp_arr)
tm.assert_index_equal(idx, idx3)
assert idx.freq == idx3.freq
def test_factorize_tz(self, tz_naive_fixture, index_or_series):
tz = tz_naive_fixture
# GH#13750
base = date_range("2016-11-05", freq="h", periods=100, tz=tz)
idx = base.repeat(5)
exp_arr = np.arange(100, dtype=np.intp).repeat(5)
obj = index_or_series(idx)
arr, res = obj.factorize()
tm.assert_numpy_array_equal(arr, exp_arr)
expected = base._with_freq(None)
tm.assert_index_equal(res, expected)
assert res.freq == expected.freq
def test_factorize_dst(self, index_or_series):
# GH#13750
idx = date_range("2016-11-06", freq="h", periods=12, tz="US/Eastern")
obj = index_or_series(idx)
arr, res = obj.factorize()
tm.assert_numpy_array_equal(arr, np.arange(12, dtype=np.intp))
tm.assert_index_equal(res, idx)
if index_or_series is Index:
assert res.freq == idx.freq
idx = date_range("2016-06-13", freq="h", periods=12, tz="US/Eastern")
obj = index_or_series(idx)
arr, res = obj.factorize()
tm.assert_numpy_array_equal(arr, np.arange(12, dtype=np.intp))
tm.assert_index_equal(res, idx)
if index_or_series is Index:
assert res.freq == idx.freq
@pytest.mark.parametrize("sort", [True, False])
def test_factorize_no_freq_non_nano(self, tz_naive_fixture, sort):
# GH#51978 case that does not go through the fastpath based on
# non-None freq
tz = tz_naive_fixture
idx = date_range("2016-11-06", freq="h", periods=5, tz=tz)[[0, 4, 1, 3, 2]]
exp_codes, exp_uniques = idx.factorize(sort=sort)
res_codes, res_uniques = idx.as_unit("s").factorize(sort=sort)
tm.assert_numpy_array_equal(res_codes, exp_codes)
tm.assert_index_equal(res_uniques, exp_uniques.as_unit("s"))
res_codes, res_uniques = idx.as_unit("s").to_series().factorize(sort=sort)
tm.assert_numpy_array_equal(res_codes, exp_codes)
tm.assert_index_equal(res_uniques, exp_uniques.as_unit("s"))

View File

@ -0,0 +1,62 @@
import pytest
import pandas as pd
import pandas._testing as tm
class TestDatetimeIndexFillNA:
@pytest.mark.parametrize("tz", ["US/Eastern", "Asia/Tokyo"])
def test_fillna_datetime64(self, tz):
# GH 11343
idx = pd.DatetimeIndex(["2011-01-01 09:00", pd.NaT, "2011-01-01 11:00"])
exp = pd.DatetimeIndex(
["2011-01-01 09:00", "2011-01-01 10:00", "2011-01-01 11:00"]
)
tm.assert_index_equal(idx.fillna(pd.Timestamp("2011-01-01 10:00")), exp)
# tz mismatch
exp = pd.Index(
[
pd.Timestamp("2011-01-01 09:00"),
pd.Timestamp("2011-01-01 10:00", tz=tz),
pd.Timestamp("2011-01-01 11:00"),
],
dtype=object,
)
tm.assert_index_equal(idx.fillna(pd.Timestamp("2011-01-01 10:00", tz=tz)), exp)
# object
exp = pd.Index(
[pd.Timestamp("2011-01-01 09:00"), "x", pd.Timestamp("2011-01-01 11:00")],
dtype=object,
)
tm.assert_index_equal(idx.fillna("x"), exp)
idx = pd.DatetimeIndex(["2011-01-01 09:00", pd.NaT, "2011-01-01 11:00"], tz=tz)
exp = pd.DatetimeIndex(
["2011-01-01 09:00", "2011-01-01 10:00", "2011-01-01 11:00"], tz=tz
)
tm.assert_index_equal(idx.fillna(pd.Timestamp("2011-01-01 10:00", tz=tz)), exp)
exp = pd.Index(
[
pd.Timestamp("2011-01-01 09:00", tz=tz),
pd.Timestamp("2011-01-01 10:00"),
pd.Timestamp("2011-01-01 11:00", tz=tz),
],
dtype=object,
)
tm.assert_index_equal(idx.fillna(pd.Timestamp("2011-01-01 10:00")), exp)
# object
exp = pd.Index(
[
pd.Timestamp("2011-01-01 09:00", tz=tz),
"x",
pd.Timestamp("2011-01-01 11:00", tz=tz),
],
dtype=object,
)
tm.assert_index_equal(idx.fillna("x"), exp)

View File

@ -0,0 +1,265 @@
from datetime import datetime
import numpy as np
import pytest
import pytz
from pandas import (
NA,
DatetimeIndex,
Index,
NaT,
Timestamp,
date_range,
)
import pandas._testing as tm
class TestInsert:
@pytest.mark.parametrize("null", [None, np.nan, np.datetime64("NaT"), NaT, NA])
@pytest.mark.parametrize("tz", [None, "UTC", "US/Eastern"])
def test_insert_nat(self, tz, null):
# GH#16537, GH#18295 (test missing)
idx = DatetimeIndex(["2017-01-01"], tz=tz)
expected = DatetimeIndex(["NaT", "2017-01-01"], tz=tz)
if tz is not None and isinstance(null, np.datetime64):
expected = Index([null, idx[0]], dtype=object)
res = idx.insert(0, null)
tm.assert_index_equal(res, expected)
@pytest.mark.parametrize("tz", [None, "UTC", "US/Eastern"])
def test_insert_invalid_na(self, tz):
idx = DatetimeIndex(["2017-01-01"], tz=tz)
item = np.timedelta64("NaT")
result = idx.insert(0, item)
expected = Index([item] + list(idx), dtype=object)
tm.assert_index_equal(result, expected)
def test_insert_empty_preserves_freq(self, tz_naive_fixture):
# GH#33573
tz = tz_naive_fixture
dti = DatetimeIndex([], tz=tz, freq="D")
item = Timestamp("2017-04-05").tz_localize(tz)
result = dti.insert(0, item)
assert result.freq == dti.freq
# But not when we insert an item that doesn't conform to freq
dti = DatetimeIndex([], tz=tz, freq="W-THU")
result = dti.insert(0, item)
assert result.freq is None
def test_insert(self, unit):
idx = DatetimeIndex(
["2000-01-04", "2000-01-01", "2000-01-02"], name="idx"
).as_unit(unit)
result = idx.insert(2, datetime(2000, 1, 5))
exp = DatetimeIndex(
["2000-01-04", "2000-01-01", "2000-01-05", "2000-01-02"], name="idx"
).as_unit(unit)
tm.assert_index_equal(result, exp)
# insertion of non-datetime should coerce to object index
result = idx.insert(1, "inserted")
expected = Index(
[
datetime(2000, 1, 4),
"inserted",
datetime(2000, 1, 1),
datetime(2000, 1, 2),
],
name="idx",
)
assert not isinstance(result, DatetimeIndex)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
def test_insert2(self, unit):
idx = date_range("1/1/2000", periods=3, freq="ME", name="idx", unit=unit)
# preserve freq
expected_0 = DatetimeIndex(
["1999-12-31", "2000-01-31", "2000-02-29", "2000-03-31"],
name="idx",
freq="ME",
).as_unit(unit)
expected_3 = DatetimeIndex(
["2000-01-31", "2000-02-29", "2000-03-31", "2000-04-30"],
name="idx",
freq="ME",
).as_unit(unit)
# reset freq to None
expected_1_nofreq = DatetimeIndex(
["2000-01-31", "2000-01-31", "2000-02-29", "2000-03-31"],
name="idx",
freq=None,
).as_unit(unit)
expected_3_nofreq = DatetimeIndex(
["2000-01-31", "2000-02-29", "2000-03-31", "2000-01-02"],
name="idx",
freq=None,
).as_unit(unit)
cases = [
(0, datetime(1999, 12, 31), expected_0),
(-3, datetime(1999, 12, 31), expected_0),
(3, datetime(2000, 4, 30), expected_3),
(1, datetime(2000, 1, 31), expected_1_nofreq),
(3, datetime(2000, 1, 2), expected_3_nofreq),
]
for n, d, expected in cases:
result = idx.insert(n, d)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq == expected.freq
def test_insert3(self, unit):
idx = date_range("1/1/2000", periods=3, freq="ME", name="idx", unit=unit)
# reset freq to None
result = idx.insert(3, datetime(2000, 1, 2))
expected = DatetimeIndex(
["2000-01-31", "2000-02-29", "2000-03-31", "2000-01-02"],
name="idx",
freq=None,
).as_unit(unit)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq is None
def test_insert4(self, unit):
for tz in ["US/Pacific", "Asia/Singapore"]:
idx = date_range(
"1/1/2000 09:00", periods=6, freq="h", tz=tz, name="idx", unit=unit
)
# preserve freq
expected = date_range(
"1/1/2000 09:00", periods=7, freq="h", tz=tz, name="idx", unit=unit
)
for d in [
Timestamp("2000-01-01 15:00", tz=tz),
pytz.timezone(tz).localize(datetime(2000, 1, 1, 15)),
]:
result = idx.insert(6, d)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.freq == expected.freq
assert result.tz == expected.tz
expected = DatetimeIndex(
[
"2000-01-01 09:00",
"2000-01-01 10:00",
"2000-01-01 11:00",
"2000-01-01 12:00",
"2000-01-01 13:00",
"2000-01-01 14:00",
"2000-01-01 10:00",
],
name="idx",
tz=tz,
freq=None,
).as_unit(unit)
# reset freq to None
for d in [
Timestamp("2000-01-01 10:00", tz=tz),
pytz.timezone(tz).localize(datetime(2000, 1, 1, 10)),
]:
result = idx.insert(6, d)
tm.assert_index_equal(result, expected)
assert result.name == expected.name
assert result.tz == expected.tz
assert result.freq is None
# TODO: also changes DataFrame.__setitem__ with expansion
def test_insert_mismatched_tzawareness(self):
# see GH#7299
idx = date_range("1/1/2000", periods=3, freq="D", tz="Asia/Tokyo", name="idx")
# mismatched tz-awareness
item = Timestamp("2000-01-04")
result = idx.insert(3, item)
expected = Index(
list(idx[:3]) + [item] + list(idx[3:]), dtype=object, name="idx"
)
tm.assert_index_equal(result, expected)
# mismatched tz-awareness
item = datetime(2000, 1, 4)
result = idx.insert(3, item)
expected = Index(
list(idx[:3]) + [item] + list(idx[3:]), dtype=object, name="idx"
)
tm.assert_index_equal(result, expected)
# TODO: also changes DataFrame.__setitem__ with expansion
def test_insert_mismatched_tz(self):
# see GH#7299
# pre-2.0 with mismatched tzs we would cast to object
idx = date_range("1/1/2000", periods=3, freq="D", tz="Asia/Tokyo", name="idx")
# mismatched tz -> cast to object (could reasonably cast to same tz or UTC)
item = Timestamp("2000-01-04", tz="US/Eastern")
result = idx.insert(3, item)
expected = Index(
list(idx[:3]) + [item.tz_convert(idx.tz)] + list(idx[3:]),
name="idx",
)
assert expected.dtype == idx.dtype
tm.assert_index_equal(result, expected)
item = datetime(2000, 1, 4, tzinfo=pytz.timezone("US/Eastern"))
result = idx.insert(3, item)
expected = Index(
list(idx[:3]) + [item.astimezone(idx.tzinfo)] + list(idx[3:]),
name="idx",
)
assert expected.dtype == idx.dtype
tm.assert_index_equal(result, expected)
@pytest.mark.parametrize(
"item", [0, np.int64(0), np.float64(0), np.array(0), np.timedelta64(456)]
)
def test_insert_mismatched_types_raises(self, tz_aware_fixture, item):
# GH#33703 dont cast these to dt64
tz = tz_aware_fixture
dti = date_range("2019-11-04", periods=9, freq="-1D", name=9, tz=tz)
result = dti.insert(1, item)
if isinstance(item, np.ndarray):
assert item.item() == 0
expected = Index([dti[0], 0] + list(dti[1:]), dtype=object, name=9)
else:
expected = Index([dti[0], item] + list(dti[1:]), dtype=object, name=9)
tm.assert_index_equal(result, expected)
def test_insert_castable_str(self, tz_aware_fixture):
# GH#33703
tz = tz_aware_fixture
dti = date_range("2019-11-04", periods=3, freq="-1D", name=9, tz=tz)
value = "2019-11-05"
result = dti.insert(0, value)
ts = Timestamp(value).tz_localize(tz)
expected = DatetimeIndex([ts] + list(dti), dtype=dti.dtype, name=9)
tm.assert_index_equal(result, expected)
def test_insert_non_castable_str(self, tz_aware_fixture):
# GH#33703
tz = tz_aware_fixture
dti = date_range("2019-11-04", periods=3, freq="-1D", name=9, tz=tz)
value = "foo"
result = dti.insert(0, value)
expected = Index(["foo"] + list(dti), dtype=object, name=9)
tm.assert_index_equal(result, expected)

View File

@ -0,0 +1,28 @@
from pandas import (
DataFrame,
DatetimeIndex,
date_range,
)
import pandas._testing as tm
def test_isocalendar_returns_correct_values_close_to_new_year_with_tz():
# GH#6538: Check that DatetimeIndex and its TimeStamp elements
# return the same weekofyear accessor close to new year w/ tz
dates = ["2013/12/29", "2013/12/30", "2013/12/31"]
dates = DatetimeIndex(dates, tz="Europe/Brussels")
result = dates.isocalendar()
expected_data_frame = DataFrame(
[[2013, 52, 7], [2014, 1, 1], [2014, 1, 2]],
columns=["year", "week", "day"],
index=dates,
dtype="UInt32",
)
tm.assert_frame_equal(result, expected_data_frame)
def test_dti_timestamp_isocalendar_fields():
idx = date_range("2020-01-01", periods=10)
expected = tuple(idx.isocalendar().iloc[-1].to_list())
result = idx[-1].isocalendar()
assert result == expected

View File

@ -0,0 +1,47 @@
import pytest
from pandas import (
DatetimeIndex,
Index,
MultiIndex,
Period,
date_range,
)
import pandas._testing as tm
class TestMap:
def test_map(self):
rng = date_range("1/1/2000", periods=10)
f = lambda x: x.strftime("%Y%m%d")
result = rng.map(f)
exp = Index([f(x) for x in rng])
tm.assert_index_equal(result, exp)
def test_map_fallthrough(self, capsys):
# GH#22067, check we don't get warnings about silently ignored errors
dti = date_range("2017-01-01", "2018-01-01", freq="B")
dti.map(lambda x: Period(year=x.year, month=x.month, freq="M"))
captured = capsys.readouterr()
assert captured.err == ""
def test_map_bug_1677(self):
index = DatetimeIndex(["2012-04-25 09:30:00.393000"])
f = index.asof
result = index.map(f)
expected = Index([f(index[0])])
tm.assert_index_equal(result, expected)
@pytest.mark.parametrize("name", [None, "name"])
def test_index_map(self, name):
# see GH#20990
count = 6
index = date_range("2018-01-01", periods=count, freq="ME", name=name).map(
lambda x: (x.year, x.month)
)
exp_index = MultiIndex.from_product(((2018,), range(1, 7)), names=[name, name])
tm.assert_index_equal(index, exp_index)

View File

@ -0,0 +1,95 @@
from dateutil.tz import tzlocal
import numpy as np
import pytest
import pandas.util._test_decorators as td
from pandas import (
DatetimeIndex,
NaT,
Timestamp,
date_range,
)
import pandas._testing as tm
class TestNormalize:
def test_normalize(self):
rng = date_range("1/1/2000 9:30", periods=10, freq="D")
result = rng.normalize()
expected = date_range("1/1/2000", periods=10, freq="D")
tm.assert_index_equal(result, expected)
arr_ns = np.array([1380585623454345752, 1380585612343234312]).astype(
"datetime64[ns]"
)
rng_ns = DatetimeIndex(arr_ns)
rng_ns_normalized = rng_ns.normalize()
arr_ns = np.array([1380585600000000000, 1380585600000000000]).astype(
"datetime64[ns]"
)
expected = DatetimeIndex(arr_ns)
tm.assert_index_equal(rng_ns_normalized, expected)
assert result.is_normalized
assert not rng.is_normalized
def test_normalize_nat(self):
dti = DatetimeIndex([NaT, Timestamp("2018-01-01 01:00:00")])
result = dti.normalize()
expected = DatetimeIndex([NaT, Timestamp("2018-01-01")])
tm.assert_index_equal(result, expected)
def test_normalize_tz(self):
rng = date_range("1/1/2000 9:30", periods=10, freq="D", tz="US/Eastern")
result = rng.normalize() # does not preserve freq
expected = date_range("1/1/2000", periods=10, freq="D", tz="US/Eastern")
tm.assert_index_equal(result, expected._with_freq(None))
assert result.is_normalized
assert not rng.is_normalized
rng = date_range("1/1/2000 9:30", periods=10, freq="D", tz="UTC")
result = rng.normalize()
expected = date_range("1/1/2000", periods=10, freq="D", tz="UTC")
tm.assert_index_equal(result, expected)
assert result.is_normalized
assert not rng.is_normalized
rng = date_range("1/1/2000 9:30", periods=10, freq="D", tz=tzlocal())
result = rng.normalize() # does not preserve freq
expected = date_range("1/1/2000", periods=10, freq="D", tz=tzlocal())
tm.assert_index_equal(result, expected._with_freq(None))
assert result.is_normalized
assert not rng.is_normalized
@td.skip_if_windows
@pytest.mark.parametrize(
"timezone",
[
"US/Pacific",
"US/Eastern",
"UTC",
"Asia/Kolkata",
"Asia/Shanghai",
"Australia/Canberra",
],
)
def test_normalize_tz_local(self, timezone):
# GH#13459
with tm.set_timezone(timezone):
rng = date_range("1/1/2000 9:30", periods=10, freq="D", tz=tzlocal())
result = rng.normalize()
expected = date_range("1/1/2000", periods=10, freq="D", tz=tzlocal())
expected = expected._with_freq(None)
tm.assert_index_equal(result, expected)
assert result.is_normalized
assert not rng.is_normalized

View File

@ -0,0 +1,83 @@
import numpy as np
import pytest
from pandas import (
DatetimeIndex,
Timestamp,
date_range,
)
import pandas._testing as tm
class TestRepeat:
def test_repeat_range(self, tz_naive_fixture):
rng = date_range("1/1/2000", "1/1/2001")
result = rng.repeat(5)
assert result.freq is None
assert len(result) == 5 * len(rng)
def test_repeat_range2(self, tz_naive_fixture, unit):
tz = tz_naive_fixture
index = date_range("2001-01-01", periods=2, freq="D", tz=tz, unit=unit)
exp = DatetimeIndex(
["2001-01-01", "2001-01-01", "2001-01-02", "2001-01-02"], tz=tz
).as_unit(unit)
for res in [index.repeat(2), np.repeat(index, 2)]:
tm.assert_index_equal(res, exp)
assert res.freq is None
def test_repeat_range3(self, tz_naive_fixture, unit):
tz = tz_naive_fixture
index = date_range("2001-01-01", periods=2, freq="2D", tz=tz, unit=unit)
exp = DatetimeIndex(
["2001-01-01", "2001-01-01", "2001-01-03", "2001-01-03"], tz=tz
).as_unit(unit)
for res in [index.repeat(2), np.repeat(index, 2)]:
tm.assert_index_equal(res, exp)
assert res.freq is None
def test_repeat_range4(self, tz_naive_fixture, unit):
tz = tz_naive_fixture
index = DatetimeIndex(["2001-01-01", "NaT", "2003-01-01"], tz=tz).as_unit(unit)
exp = DatetimeIndex(
[
"2001-01-01",
"2001-01-01",
"2001-01-01",
"NaT",
"NaT",
"NaT",
"2003-01-01",
"2003-01-01",
"2003-01-01",
],
tz=tz,
).as_unit(unit)
for res in [index.repeat(3), np.repeat(index, 3)]:
tm.assert_index_equal(res, exp)
assert res.freq is None
def test_repeat(self, tz_naive_fixture, unit):
tz = tz_naive_fixture
reps = 2
msg = "the 'axis' parameter is not supported"
rng = date_range(start="2016-01-01", periods=2, freq="30Min", tz=tz, unit=unit)
expected_rng = DatetimeIndex(
[
Timestamp("2016-01-01 00:00:00", tz=tz),
Timestamp("2016-01-01 00:00:00", tz=tz),
Timestamp("2016-01-01 00:30:00", tz=tz),
Timestamp("2016-01-01 00:30:00", tz=tz),
]
).as_unit(unit)
res = rng.repeat(reps)
tm.assert_index_equal(res, expected_rng)
assert res.freq is None
tm.assert_index_equal(np.repeat(rng, reps), expected_rng)
with pytest.raises(ValueError, match=msg):
np.repeat(rng, reps, axis=1)

View File

@ -0,0 +1,31 @@
from dateutil.tz import tzlocal
import pytest
from pandas.compat import IS64
from pandas import date_range
@pytest.mark.parametrize(
"freq,expected",
[
("YE", "day"),
("QE", "day"),
("ME", "day"),
("D", "day"),
("h", "hour"),
("min", "minute"),
("s", "second"),
("ms", "millisecond"),
("us", "microsecond"),
],
)
def test_dti_resolution(request, tz_naive_fixture, freq, expected):
tz = tz_naive_fixture
if freq == "YE" and not IS64 and isinstance(tz, tzlocal):
request.applymarker(
pytest.mark.xfail(reason="OverflowError inside tzlocal past 2038")
)
idx = date_range(start="2013-04-01", periods=30, freq=freq, tz=tz)
assert idx.resolution == expected

View File

@ -0,0 +1,221 @@
import pytest
from pandas._libs.tslibs import to_offset
from pandas._libs.tslibs.offsets import INVALID_FREQ_ERR_MSG
from pandas import (
DatetimeIndex,
Timestamp,
date_range,
)
import pandas._testing as tm
class TestDatetimeIndexRound:
def test_round_daily(self):
dti = date_range("20130101 09:10:11", periods=5)
result = dti.round("D")
expected = date_range("20130101", periods=5)
tm.assert_index_equal(result, expected)
dti = dti.tz_localize("UTC").tz_convert("US/Eastern")
result = dti.round("D")
expected = date_range("20130101", periods=5).tz_localize("US/Eastern")
tm.assert_index_equal(result, expected)
result = dti.round("s")
tm.assert_index_equal(result, dti)
@pytest.mark.parametrize(
"freq, error_msg",
[
("YE", "<YearEnd: month=12> is a non-fixed frequency"),
("ME", "<MonthEnd> is a non-fixed frequency"),
("foobar", "Invalid frequency: foobar"),
],
)
def test_round_invalid(self, freq, error_msg):
dti = date_range("20130101 09:10:11", periods=5)
dti = dti.tz_localize("UTC").tz_convert("US/Eastern")
with pytest.raises(ValueError, match=error_msg):
dti.round(freq)
def test_round(self, tz_naive_fixture, unit):
tz = tz_naive_fixture
rng = date_range(start="2016-01-01", periods=5, freq="30Min", tz=tz, unit=unit)
elt = rng[1]
expected_rng = DatetimeIndex(
[
Timestamp("2016-01-01 00:00:00", tz=tz),
Timestamp("2016-01-01 00:00:00", tz=tz),
Timestamp("2016-01-01 01:00:00", tz=tz),
Timestamp("2016-01-01 02:00:00", tz=tz),
Timestamp("2016-01-01 02:00:00", tz=tz),
]
).as_unit(unit)
expected_elt = expected_rng[1]
result = rng.round(freq="h")
tm.assert_index_equal(result, expected_rng)
assert elt.round(freq="h") == expected_elt
msg = INVALID_FREQ_ERR_MSG
with pytest.raises(ValueError, match=msg):
rng.round(freq="foo")
with pytest.raises(ValueError, match=msg):
elt.round(freq="foo")
msg = "<MonthEnd> is a non-fixed frequency"
with pytest.raises(ValueError, match=msg):
rng.round(freq="ME")
with pytest.raises(ValueError, match=msg):
elt.round(freq="ME")
def test_round2(self, tz_naive_fixture):
tz = tz_naive_fixture
# GH#14440 & GH#15578
index = DatetimeIndex(["2016-10-17 12:00:00.0015"], tz=tz).as_unit("ns")
result = index.round("ms")
expected = DatetimeIndex(["2016-10-17 12:00:00.002000"], tz=tz).as_unit("ns")
tm.assert_index_equal(result, expected)
for freq in ["us", "ns"]:
tm.assert_index_equal(index, index.round(freq))
def test_round3(self, tz_naive_fixture):
tz = tz_naive_fixture
index = DatetimeIndex(["2016-10-17 12:00:00.00149"], tz=tz).as_unit("ns")
result = index.round("ms")
expected = DatetimeIndex(["2016-10-17 12:00:00.001000"], tz=tz).as_unit("ns")
tm.assert_index_equal(result, expected)
def test_round4(self, tz_naive_fixture):
index = DatetimeIndex(["2016-10-17 12:00:00.001501031"], dtype="M8[ns]")
result = index.round("10ns")
expected = DatetimeIndex(["2016-10-17 12:00:00.001501030"], dtype="M8[ns]")
tm.assert_index_equal(result, expected)
ts = "2016-10-17 12:00:00.001501031"
dti = DatetimeIndex([ts], dtype="M8[ns]")
with tm.assert_produces_warning(False):
dti.round("1010ns")
def test_no_rounding_occurs(self, tz_naive_fixture):
# GH 21262
tz = tz_naive_fixture
rng = date_range(start="2016-01-01", periods=5, freq="2Min", tz=tz)
expected_rng = DatetimeIndex(
[
Timestamp("2016-01-01 00:00:00", tz=tz),
Timestamp("2016-01-01 00:02:00", tz=tz),
Timestamp("2016-01-01 00:04:00", tz=tz),
Timestamp("2016-01-01 00:06:00", tz=tz),
Timestamp("2016-01-01 00:08:00", tz=tz),
]
).as_unit("ns")
result = rng.round(freq="2min")
tm.assert_index_equal(result, expected_rng)
@pytest.mark.parametrize(
"test_input, rounder, freq, expected",
[
(["2117-01-01 00:00:45"], "floor", "15s", ["2117-01-01 00:00:45"]),
(["2117-01-01 00:00:45"], "ceil", "15s", ["2117-01-01 00:00:45"]),
(
["2117-01-01 00:00:45.000000012"],
"floor",
"10ns",
["2117-01-01 00:00:45.000000010"],
),
(
["1823-01-01 00:00:01.000000012"],
"ceil",
"10ns",
["1823-01-01 00:00:01.000000020"],
),
(["1823-01-01 00:00:01"], "floor", "1s", ["1823-01-01 00:00:01"]),
(["1823-01-01 00:00:01"], "ceil", "1s", ["1823-01-01 00:00:01"]),
(["2018-01-01 00:15:00"], "ceil", "15min", ["2018-01-01 00:15:00"]),
(["2018-01-01 00:15:00"], "floor", "15min", ["2018-01-01 00:15:00"]),
(["1823-01-01 03:00:00"], "ceil", "3h", ["1823-01-01 03:00:00"]),
(["1823-01-01 03:00:00"], "floor", "3h", ["1823-01-01 03:00:00"]),
(
("NaT", "1823-01-01 00:00:01"),
"floor",
"1s",
("NaT", "1823-01-01 00:00:01"),
),
(
("NaT", "1823-01-01 00:00:01"),
"ceil",
"1s",
("NaT", "1823-01-01 00:00:01"),
),
],
)
def test_ceil_floor_edge(self, test_input, rounder, freq, expected):
dt = DatetimeIndex(list(test_input))
func = getattr(dt, rounder)
result = func(freq)
expected = DatetimeIndex(list(expected))
assert expected.equals(result)
@pytest.mark.parametrize(
"start, index_freq, periods",
[("2018-01-01", "12h", 25), ("2018-01-01 0:0:0.124999", "1ns", 1000)],
)
@pytest.mark.parametrize(
"round_freq",
[
"2ns",
"3ns",
"4ns",
"5ns",
"6ns",
"7ns",
"250ns",
"500ns",
"750ns",
"1us",
"19us",
"250us",
"500us",
"750us",
"1s",
"2s",
"3s",
"12h",
"1D",
],
)
def test_round_int64(self, start, index_freq, periods, round_freq):
dt = date_range(start=start, freq=index_freq, periods=periods)
unit = to_offset(round_freq).nanos
# test floor
result = dt.floor(round_freq)
diff = dt.asi8 - result.asi8
mod = result.asi8 % unit
assert (mod == 0).all(), f"floor not a {round_freq} multiple"
assert (0 <= diff).all() and (diff < unit).all(), "floor error"
# test ceil
result = dt.ceil(round_freq)
diff = result.asi8 - dt.asi8
mod = result.asi8 % unit
assert (mod == 0).all(), f"ceil not a {round_freq} multiple"
assert (0 <= diff).all() and (diff < unit).all(), "ceil error"
# test round
result = dt.round(round_freq)
diff = abs(result.asi8 - dt.asi8)
mod = result.asi8 % unit
assert (mod == 0).all(), f"round not a {round_freq} multiple"
assert (diff <= unit // 2).all(), "round error"
if unit % 2 == 0:
assert (
result.asi8[diff == unit // 2] % 2 == 0
).all(), "round half to even error"

View File

@ -0,0 +1,169 @@
from datetime import datetime
import pytest
import pytz
from pandas.errors import NullFrequencyError
import pandas as pd
from pandas import (
DatetimeIndex,
Series,
date_range,
)
import pandas._testing as tm
START, END = datetime(2009, 1, 1), datetime(2010, 1, 1)
class TestDatetimeIndexShift:
# -------------------------------------------------------------
# DatetimeIndex.shift is used in integer addition
def test_dti_shift_tzaware(self, tz_naive_fixture, unit):
# GH#9903
tz = tz_naive_fixture
idx = DatetimeIndex([], name="xxx", tz=tz).as_unit(unit)
tm.assert_index_equal(idx.shift(0, freq="h"), idx)
tm.assert_index_equal(idx.shift(3, freq="h"), idx)
idx = DatetimeIndex(
["2011-01-01 10:00", "2011-01-01 11:00", "2011-01-01 12:00"],
name="xxx",
tz=tz,
freq="h",
).as_unit(unit)
tm.assert_index_equal(idx.shift(0, freq="h"), idx)
exp = DatetimeIndex(
["2011-01-01 13:00", "2011-01-01 14:00", "2011-01-01 15:00"],
name="xxx",
tz=tz,
freq="h",
).as_unit(unit)
tm.assert_index_equal(idx.shift(3, freq="h"), exp)
exp = DatetimeIndex(
["2011-01-01 07:00", "2011-01-01 08:00", "2011-01-01 09:00"],
name="xxx",
tz=tz,
freq="h",
).as_unit(unit)
tm.assert_index_equal(idx.shift(-3, freq="h"), exp)
def test_dti_shift_freqs(self, unit):
# test shift for DatetimeIndex and non DatetimeIndex
# GH#8083
drange = date_range("20130101", periods=5, unit=unit)
result = drange.shift(1)
expected = DatetimeIndex(
["2013-01-02", "2013-01-03", "2013-01-04", "2013-01-05", "2013-01-06"],
dtype=f"M8[{unit}]",
freq="D",
)
tm.assert_index_equal(result, expected)
result = drange.shift(-1)
expected = DatetimeIndex(
["2012-12-31", "2013-01-01", "2013-01-02", "2013-01-03", "2013-01-04"],
dtype=f"M8[{unit}]",
freq="D",
)
tm.assert_index_equal(result, expected)
result = drange.shift(3, freq="2D")
expected = DatetimeIndex(
["2013-01-07", "2013-01-08", "2013-01-09", "2013-01-10", "2013-01-11"],
dtype=f"M8[{unit}]",
freq="D",
)
tm.assert_index_equal(result, expected)
def test_dti_shift_int(self, unit):
rng = date_range("1/1/2000", periods=20, unit=unit)
result = rng + 5 * rng.freq
expected = rng.shift(5)
tm.assert_index_equal(result, expected)
result = rng - 5 * rng.freq
expected = rng.shift(-5)
tm.assert_index_equal(result, expected)
def test_dti_shift_no_freq(self, unit):
# GH#19147
dti = DatetimeIndex(["2011-01-01 10:00", "2011-01-01"], freq=None).as_unit(unit)
with pytest.raises(NullFrequencyError, match="Cannot shift with no freq"):
dti.shift(2)
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
def test_dti_shift_localized(self, tzstr, unit):
dr = date_range("2011/1/1", "2012/1/1", freq="W-FRI", unit=unit)
dr_tz = dr.tz_localize(tzstr)
result = dr_tz.shift(1, "10min")
assert result.tz == dr_tz.tz
def test_dti_shift_across_dst(self, unit):
# GH 8616
idx = date_range(
"2013-11-03", tz="America/Chicago", periods=7, freq="h", unit=unit
)
ser = Series(index=idx[:-1], dtype=object)
result = ser.shift(freq="h")
expected = Series(index=idx[1:], dtype=object)
tm.assert_series_equal(result, expected)
@pytest.mark.parametrize(
"shift, result_time",
[
[0, "2014-11-14 00:00:00"],
[-1, "2014-11-13 23:00:00"],
[1, "2014-11-14 01:00:00"],
],
)
def test_dti_shift_near_midnight(self, shift, result_time, unit):
# GH 8616
dt = datetime(2014, 11, 14, 0)
dt_est = pytz.timezone("EST").localize(dt)
idx = DatetimeIndex([dt_est]).as_unit(unit)
ser = Series(data=[1], index=idx)
result = ser.shift(shift, freq="h")
exp_index = DatetimeIndex([result_time], tz="EST").as_unit(unit)
expected = Series(1, index=exp_index)
tm.assert_series_equal(result, expected)
def test_shift_periods(self, unit):
# GH#22458 : argument 'n' was deprecated in favor of 'periods'
idx = date_range(start=START, end=END, periods=3, unit=unit)
tm.assert_index_equal(idx.shift(periods=0), idx)
tm.assert_index_equal(idx.shift(0), idx)
@pytest.mark.parametrize("freq", ["B", "C"])
def test_shift_bday(self, freq, unit):
rng = date_range(START, END, freq=freq, unit=unit)
shifted = rng.shift(5)
assert shifted[0] == rng[5]
assert shifted.freq == rng.freq
shifted = rng.shift(-5)
assert shifted[5] == rng[0]
assert shifted.freq == rng.freq
shifted = rng.shift(0)
assert shifted[0] == rng[0]
assert shifted.freq == rng.freq
def test_shift_bmonth(self, unit):
rng = date_range(START, END, freq=pd.offsets.BMonthEnd(), unit=unit)
shifted = rng.shift(1, freq=pd.offsets.BDay())
assert shifted[0] == rng[0] + pd.offsets.BDay()
rng = date_range(START, END, freq=pd.offsets.BMonthEnd(), unit=unit)
with tm.assert_produces_warning(pd.errors.PerformanceWarning):
shifted = rng.shift(1, freq=pd.offsets.CDay())
assert shifted[0] == rng[0] + pd.offsets.CDay()
def test_shift_empty(self, unit):
# GH#14811
dti = date_range(start="2016-10-21", end="2016-10-21", freq="BME", unit=unit)
result = dti.shift(1)
tm.assert_index_equal(result, dti)

View File

@ -0,0 +1,47 @@
import pytest
from pandas import (
DatetimeIndex,
date_range,
)
import pandas._testing as tm
@pytest.mark.parametrize("tz", [None, "Asia/Shanghai", "Europe/Berlin"])
@pytest.mark.parametrize("name", [None, "my_dti"])
@pytest.mark.parametrize("unit", ["ns", "us", "ms", "s"])
def test_dti_snap(name, tz, unit):
dti = DatetimeIndex(
[
"1/1/2002",
"1/2/2002",
"1/3/2002",
"1/4/2002",
"1/5/2002",
"1/6/2002",
"1/7/2002",
],
name=name,
tz=tz,
freq="D",
)
dti = dti.as_unit(unit)
result = dti.snap(freq="W-MON")
expected = date_range("12/31/2001", "1/7/2002", name=name, tz=tz, freq="w-mon")
expected = expected.repeat([3, 4])
expected = expected.as_unit(unit)
tm.assert_index_equal(result, expected)
assert result.tz == expected.tz
assert result.freq is None
assert expected.freq is None
result = dti.snap(freq="B")
expected = date_range("1/1/2002", "1/7/2002", name=name, tz=tz, freq="b")
expected = expected.repeat([1, 1, 1, 2, 2])
expected = expected.as_unit(unit)
tm.assert_index_equal(result, expected)
assert result.tz == expected.tz
assert result.freq is None
assert expected.freq is None

View File

@ -0,0 +1,28 @@
from pandas import (
DataFrame,
Index,
date_range,
)
import pandas._testing as tm
class TestToFrame:
def test_to_frame_datetime_tz(self):
# GH#25809
idx = date_range(start="2019-01-01", end="2019-01-30", freq="D", tz="UTC")
result = idx.to_frame()
expected = DataFrame(idx, index=idx)
tm.assert_frame_equal(result, expected)
def test_to_frame_respects_none_name(self):
# GH#44212 if we explicitly pass name=None, then that should be respected,
# not changed to 0
# GH-45448 this is first deprecated to only change in the future
idx = date_range(start="2019-01-01", end="2019-01-30", freq="D", tz="UTC")
result = idx.to_frame(name=None)
exp_idx = Index([None], dtype=object)
tm.assert_index_equal(exp_idx, result.columns)
result = idx.rename("foo").to_frame(name=None)
exp_idx = Index([None], dtype=object)
tm.assert_index_equal(exp_idx, result.columns)

View File

@ -0,0 +1,45 @@
import numpy as np
from pandas import (
Index,
Timestamp,
date_range,
)
import pandas._testing as tm
class TestDateTimeIndexToJulianDate:
def test_1700(self):
dr = date_range(start=Timestamp("1710-10-01"), periods=5, freq="D")
r1 = Index([x.to_julian_date() for x in dr])
r2 = dr.to_julian_date()
assert isinstance(r2, Index) and r2.dtype == np.float64
tm.assert_index_equal(r1, r2)
def test_2000(self):
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="D")
r1 = Index([x.to_julian_date() for x in dr])
r2 = dr.to_julian_date()
assert isinstance(r2, Index) and r2.dtype == np.float64
tm.assert_index_equal(r1, r2)
def test_hour(self):
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="h")
r1 = Index([x.to_julian_date() for x in dr])
r2 = dr.to_julian_date()
assert isinstance(r2, Index) and r2.dtype == np.float64
tm.assert_index_equal(r1, r2)
def test_minute(self):
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="min")
r1 = Index([x.to_julian_date() for x in dr])
r2 = dr.to_julian_date()
assert isinstance(r2, Index) and r2.dtype == np.float64
tm.assert_index_equal(r1, r2)
def test_second(self):
dr = date_range(start=Timestamp("2000-02-27"), periods=5, freq="s")
r1 = Index([x.to_julian_date() for x in dr])
r2 = dr.to_julian_date()
assert isinstance(r2, Index) and r2.dtype == np.float64
tm.assert_index_equal(r1, r2)

View File

@ -0,0 +1,225 @@
import dateutil.tz
from dateutil.tz import tzlocal
import pytest
import pytz
from pandas._libs.tslibs.ccalendar import MONTHS
from pandas._libs.tslibs.offsets import MonthEnd
from pandas._libs.tslibs.period import INVALID_FREQ_ERR_MSG
from pandas import (
DatetimeIndex,
Period,
PeriodIndex,
Timestamp,
date_range,
period_range,
)
import pandas._testing as tm
class TestToPeriod:
def test_dti_to_period(self):
dti = date_range(start="1/1/2005", end="12/1/2005", freq="ME")
pi1 = dti.to_period()
pi2 = dti.to_period(freq="D")
pi3 = dti.to_period(freq="3D")
assert pi1[0] == Period("Jan 2005", freq="M")
assert pi2[0] == Period("1/31/2005", freq="D")
assert pi3[0] == Period("1/31/2005", freq="3D")
assert pi1[-1] == Period("Nov 2005", freq="M")
assert pi2[-1] == Period("11/30/2005", freq="D")
assert pi3[-1], Period("11/30/2005", freq="3D")
tm.assert_index_equal(pi1, period_range("1/1/2005", "11/1/2005", freq="M"))
tm.assert_index_equal(
pi2, period_range("1/1/2005", "11/1/2005", freq="M").asfreq("D")
)
tm.assert_index_equal(
pi3, period_range("1/1/2005", "11/1/2005", freq="M").asfreq("3D")
)
@pytest.mark.parametrize("month", MONTHS)
def test_to_period_quarterly(self, month):
# make sure we can make the round trip
freq = f"Q-{month}"
rng = period_range("1989Q3", "1991Q3", freq=freq)
stamps = rng.to_timestamp()
result = stamps.to_period(freq)
tm.assert_index_equal(rng, result)
@pytest.mark.parametrize("off", ["BQE", "QS", "BQS"])
def test_to_period_quarterlyish(self, off):
rng = date_range("01-Jan-2012", periods=8, freq=off)
prng = rng.to_period()
assert prng.freq == "QE-DEC"
@pytest.mark.parametrize("off", ["BYE", "YS", "BYS"])
def test_to_period_annualish(self, off):
rng = date_range("01-Jan-2012", periods=8, freq=off)
prng = rng.to_period()
assert prng.freq == "YE-DEC"
def test_to_period_monthish(self):
offsets = ["MS", "BME"]
for off in offsets:
rng = date_range("01-Jan-2012", periods=8, freq=off)
prng = rng.to_period()
assert prng.freqstr == "M"
rng = date_range("01-Jan-2012", periods=8, freq="ME")
prng = rng.to_period()
assert prng.freqstr == "M"
with pytest.raises(ValueError, match=INVALID_FREQ_ERR_MSG):
date_range("01-Jan-2012", periods=8, freq="EOM")
@pytest.mark.parametrize(
"freq_offset, freq_period",
[
("2ME", "2M"),
(MonthEnd(2), MonthEnd(2)),
],
)
def test_dti_to_period_2monthish(self, freq_offset, freq_period):
dti = date_range("2020-01-01", periods=3, freq=freq_offset)
pi = dti.to_period()
tm.assert_index_equal(pi, period_range("2020-01", "2020-05", freq=freq_period))
@pytest.mark.parametrize(
"freq, freq_depr",
[
("2ME", "2M"),
("2QE", "2Q"),
("2QE-SEP", "2Q-SEP"),
("1YE", "1Y"),
("2YE-MAR", "2Y-MAR"),
("1YE", "1A"),
("2YE-MAR", "2A-MAR"),
],
)
def test_to_period_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
# GH#9586
msg = f"'{freq_depr[1:]}' is deprecated and will be removed "
f"in a future version, please use '{freq[1:]}' instead."
rng = date_range("01-Jan-2012", periods=8, freq=freq)
prng = rng.to_period()
with tm.assert_produces_warning(FutureWarning, match=msg):
assert prng.freq == freq_depr
def test_to_period_infer(self):
# https://github.com/pandas-dev/pandas/issues/33358
rng = date_range(
start="2019-12-22 06:40:00+00:00",
end="2019-12-22 08:45:00+00:00",
freq="5min",
)
with tm.assert_produces_warning(UserWarning):
pi1 = rng.to_period("5min")
with tm.assert_produces_warning(UserWarning):
pi2 = rng.to_period()
tm.assert_index_equal(pi1, pi2)
@pytest.mark.filterwarnings(r"ignore:PeriodDtype\[B\] is deprecated:FutureWarning")
def test_period_dt64_round_trip(self):
dti = date_range("1/1/2000", "1/7/2002", freq="B")
pi = dti.to_period()
tm.assert_index_equal(pi.to_timestamp(), dti)
dti = date_range("1/1/2000", "1/7/2002", freq="B")
pi = dti.to_period(freq="h")
tm.assert_index_equal(pi.to_timestamp(), dti)
def test_to_period_millisecond(self):
index = DatetimeIndex(
[
Timestamp("2007-01-01 10:11:12.123456Z"),
Timestamp("2007-01-01 10:11:13.789123Z"),
]
)
with tm.assert_produces_warning(UserWarning):
# warning that timezone info will be lost
period = index.to_period(freq="ms")
assert 2 == len(period)
assert period[0] == Period("2007-01-01 10:11:12.123Z", "ms")
assert period[1] == Period("2007-01-01 10:11:13.789Z", "ms")
def test_to_period_microsecond(self):
index = DatetimeIndex(
[
Timestamp("2007-01-01 10:11:12.123456Z"),
Timestamp("2007-01-01 10:11:13.789123Z"),
]
)
with tm.assert_produces_warning(UserWarning):
# warning that timezone info will be lost
period = index.to_period(freq="us")
assert 2 == len(period)
assert period[0] == Period("2007-01-01 10:11:12.123456Z", "us")
assert period[1] == Period("2007-01-01 10:11:13.789123Z", "us")
@pytest.mark.parametrize(
"tz",
["US/Eastern", pytz.utc, tzlocal(), "dateutil/US/Eastern", dateutil.tz.tzutc()],
)
def test_to_period_tz(self, tz):
ts = date_range("1/1/2000", "2/1/2000", tz=tz)
with tm.assert_produces_warning(UserWarning):
# GH#21333 warning that timezone info will be lost
# filter warning about freq deprecation
result = ts.to_period()[0]
expected = ts[0].to_period(ts.freq)
assert result == expected
expected = date_range("1/1/2000", "2/1/2000").to_period()
with tm.assert_produces_warning(UserWarning):
# GH#21333 warning that timezone info will be lost
result = ts.to_period(ts.freq)
tm.assert_index_equal(result, expected)
@pytest.mark.parametrize("tz", ["Etc/GMT-1", "Etc/GMT+1"])
def test_to_period_tz_utc_offset_consistency(self, tz):
# GH#22905
ts = date_range("1/1/2000", "2/1/2000", tz="Etc/GMT-1")
with tm.assert_produces_warning(UserWarning):
result = ts.to_period()[0]
expected = ts[0].to_period(ts.freq)
assert result == expected
def test_to_period_nofreq(self):
idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-04"])
msg = "You must pass a freq argument as current index has none."
with pytest.raises(ValueError, match=msg):
idx.to_period()
idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"], freq="infer")
assert idx.freqstr == "D"
expected = PeriodIndex(["2000-01-01", "2000-01-02", "2000-01-03"], freq="D")
tm.assert_index_equal(idx.to_period(), expected)
# GH#7606
idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"])
assert idx.freqstr is None
tm.assert_index_equal(idx.to_period(), expected)
@pytest.mark.parametrize("freq", ["2BMS", "1SME-15"])
def test_to_period_offsets_not_supported(self, freq):
# GH#56243
msg = f"{freq[1:]} is not supported as period frequency"
ts = date_range("1/1/2012", periods=4, freq=freq)
with pytest.raises(ValueError, match=msg):
ts.to_period()

View File

@ -0,0 +1,51 @@
from datetime import (
datetime,
timezone,
)
import dateutil.parser
import dateutil.tz
from dateutil.tz import tzlocal
import numpy as np
from pandas import (
DatetimeIndex,
date_range,
to_datetime,
)
import pandas._testing as tm
from pandas.tests.indexes.datetimes.test_timezones import FixedOffset
fixed_off = FixedOffset(-420, "-07:00")
class TestToPyDatetime:
def test_dti_to_pydatetime(self):
dt = dateutil.parser.parse("2012-06-13T01:39:00Z")
dt = dt.replace(tzinfo=tzlocal())
arr = np.array([dt], dtype=object)
result = to_datetime(arr, utc=True)
assert result.tz is timezone.utc
rng = date_range("2012-11-03 03:00", "2012-11-05 03:00", tz=tzlocal())
arr = rng.to_pydatetime()
result = to_datetime(arr, utc=True)
assert result.tz is timezone.utc
def test_dti_to_pydatetime_fizedtz(self):
dates = np.array(
[
datetime(2000, 1, 1, tzinfo=fixed_off),
datetime(2000, 1, 2, tzinfo=fixed_off),
datetime(2000, 1, 3, tzinfo=fixed_off),
]
)
dti = DatetimeIndex(dates)
result = dti.to_pydatetime()
tm.assert_numpy_array_equal(dates, result)
result = dti._mpl_repr()
tm.assert_numpy_array_equal(dates, result)

View File

@ -0,0 +1,18 @@
import numpy as np
from pandas import (
DatetimeIndex,
Series,
)
import pandas._testing as tm
class TestToSeries:
def test_to_series(self):
naive = DatetimeIndex(["2013-1-1 13:00", "2013-1-2 14:00"], name="B")
idx = naive.tz_localize("US/Pacific")
expected = Series(np.array(idx.tolist(), dtype="object"), name="B")
result = idx.to_series(index=[0, 1])
assert expected.dtype == idx.dtype
tm.assert_series_equal(result, expected)

View File

@ -0,0 +1,283 @@
from datetime import datetime
import dateutil.tz
from dateutil.tz import gettz
import numpy as np
import pytest
import pytz
from pandas._libs.tslibs import timezones
from pandas import (
DatetimeIndex,
Index,
NaT,
Timestamp,
date_range,
offsets,
)
import pandas._testing as tm
class TestTZConvert:
def test_tz_convert_nat(self):
# GH#5546
dates = [NaT]
idx = DatetimeIndex(dates)
idx = idx.tz_localize("US/Pacific")
tm.assert_index_equal(idx, DatetimeIndex(dates, tz="US/Pacific"))
idx = idx.tz_convert("US/Eastern")
tm.assert_index_equal(idx, DatetimeIndex(dates, tz="US/Eastern"))
idx = idx.tz_convert("UTC")
tm.assert_index_equal(idx, DatetimeIndex(dates, tz="UTC"))
dates = ["2010-12-01 00:00", "2010-12-02 00:00", NaT]
idx = DatetimeIndex(dates)
idx = idx.tz_localize("US/Pacific")
tm.assert_index_equal(idx, DatetimeIndex(dates, tz="US/Pacific"))
idx = idx.tz_convert("US/Eastern")
expected = ["2010-12-01 03:00", "2010-12-02 03:00", NaT]
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Eastern"))
idx = idx + offsets.Hour(5)
expected = ["2010-12-01 08:00", "2010-12-02 08:00", NaT]
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Eastern"))
idx = idx.tz_convert("US/Pacific")
expected = ["2010-12-01 05:00", "2010-12-02 05:00", NaT]
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Pacific"))
idx = idx + np.timedelta64(3, "h")
expected = ["2010-12-01 08:00", "2010-12-02 08:00", NaT]
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Pacific"))
idx = idx.tz_convert("US/Eastern")
expected = ["2010-12-01 11:00", "2010-12-02 11:00", NaT]
tm.assert_index_equal(idx, DatetimeIndex(expected, tz="US/Eastern"))
@pytest.mark.parametrize("prefix", ["", "dateutil/"])
def test_dti_tz_convert_compat_timestamp(self, prefix):
strdates = ["1/1/2012", "3/1/2012", "4/1/2012"]
idx = DatetimeIndex(strdates, tz=prefix + "US/Eastern")
conv = idx[0].tz_convert(prefix + "US/Pacific")
expected = idx.tz_convert(prefix + "US/Pacific")[0]
assert conv == expected
def test_dti_tz_convert_hour_overflow_dst(self):
# Regression test for GH#13306
# sorted case US/Eastern -> UTC
ts = ["2008-05-12 09:50:00", "2008-12-12 09:50:35", "2009-05-12 09:50:32"]
tt = DatetimeIndex(ts).tz_localize("US/Eastern")
ut = tt.tz_convert("UTC")
expected = Index([13, 14, 13], dtype=np.int32)
tm.assert_index_equal(ut.hour, expected)
# sorted case UTC -> US/Eastern
ts = ["2008-05-12 13:50:00", "2008-12-12 14:50:35", "2009-05-12 13:50:32"]
tt = DatetimeIndex(ts).tz_localize("UTC")
ut = tt.tz_convert("US/Eastern")
expected = Index([9, 9, 9], dtype=np.int32)
tm.assert_index_equal(ut.hour, expected)
# unsorted case US/Eastern -> UTC
ts = ["2008-05-12 09:50:00", "2008-12-12 09:50:35", "2008-05-12 09:50:32"]
tt = DatetimeIndex(ts).tz_localize("US/Eastern")
ut = tt.tz_convert("UTC")
expected = Index([13, 14, 13], dtype=np.int32)
tm.assert_index_equal(ut.hour, expected)
# unsorted case UTC -> US/Eastern
ts = ["2008-05-12 13:50:00", "2008-12-12 14:50:35", "2008-05-12 13:50:32"]
tt = DatetimeIndex(ts).tz_localize("UTC")
ut = tt.tz_convert("US/Eastern")
expected = Index([9, 9, 9], dtype=np.int32)
tm.assert_index_equal(ut.hour, expected)
@pytest.mark.parametrize("tz", ["US/Eastern", "dateutil/US/Eastern"])
def test_dti_tz_convert_hour_overflow_dst_timestamps(self, tz):
# Regression test for GH#13306
# sorted case US/Eastern -> UTC
ts = [
Timestamp("2008-05-12 09:50:00", tz=tz),
Timestamp("2008-12-12 09:50:35", tz=tz),
Timestamp("2009-05-12 09:50:32", tz=tz),
]
tt = DatetimeIndex(ts)
ut = tt.tz_convert("UTC")
expected = Index([13, 14, 13], dtype=np.int32)
tm.assert_index_equal(ut.hour, expected)
# sorted case UTC -> US/Eastern
ts = [
Timestamp("2008-05-12 13:50:00", tz="UTC"),
Timestamp("2008-12-12 14:50:35", tz="UTC"),
Timestamp("2009-05-12 13:50:32", tz="UTC"),
]
tt = DatetimeIndex(ts)
ut = tt.tz_convert("US/Eastern")
expected = Index([9, 9, 9], dtype=np.int32)
tm.assert_index_equal(ut.hour, expected)
# unsorted case US/Eastern -> UTC
ts = [
Timestamp("2008-05-12 09:50:00", tz=tz),
Timestamp("2008-12-12 09:50:35", tz=tz),
Timestamp("2008-05-12 09:50:32", tz=tz),
]
tt = DatetimeIndex(ts)
ut = tt.tz_convert("UTC")
expected = Index([13, 14, 13], dtype=np.int32)
tm.assert_index_equal(ut.hour, expected)
# unsorted case UTC -> US/Eastern
ts = [
Timestamp("2008-05-12 13:50:00", tz="UTC"),
Timestamp("2008-12-12 14:50:35", tz="UTC"),
Timestamp("2008-05-12 13:50:32", tz="UTC"),
]
tt = DatetimeIndex(ts)
ut = tt.tz_convert("US/Eastern")
expected = Index([9, 9, 9], dtype=np.int32)
tm.assert_index_equal(ut.hour, expected)
@pytest.mark.parametrize("freq, n", [("h", 1), ("min", 60), ("s", 3600)])
def test_dti_tz_convert_trans_pos_plus_1__bug(self, freq, n):
# Regression test for tslib.tz_convert(vals, tz1, tz2).
# See GH#4496 for details.
idx = date_range(datetime(2011, 3, 26, 23), datetime(2011, 3, 27, 1), freq=freq)
idx = idx.tz_localize("UTC")
idx = idx.tz_convert("Europe/Moscow")
expected = np.repeat(np.array([3, 4, 5]), np.array([n, n, 1]))
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
def test_dti_tz_convert_dst(self):
for freq, n in [("h", 1), ("min", 60), ("s", 3600)]:
# Start DST
idx = date_range(
"2014-03-08 23:00", "2014-03-09 09:00", freq=freq, tz="UTC"
)
idx = idx.tz_convert("US/Eastern")
expected = np.repeat(
np.array([18, 19, 20, 21, 22, 23, 0, 1, 3, 4, 5]),
np.array([n, n, n, n, n, n, n, n, n, n, 1]),
)
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
idx = date_range(
"2014-03-08 18:00", "2014-03-09 05:00", freq=freq, tz="US/Eastern"
)
idx = idx.tz_convert("UTC")
expected = np.repeat(
np.array([23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
np.array([n, n, n, n, n, n, n, n, n, n, 1]),
)
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
# End DST
idx = date_range(
"2014-11-01 23:00", "2014-11-02 09:00", freq=freq, tz="UTC"
)
idx = idx.tz_convert("US/Eastern")
expected = np.repeat(
np.array([19, 20, 21, 22, 23, 0, 1, 1, 2, 3, 4]),
np.array([n, n, n, n, n, n, n, n, n, n, 1]),
)
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
idx = date_range(
"2014-11-01 18:00", "2014-11-02 05:00", freq=freq, tz="US/Eastern"
)
idx = idx.tz_convert("UTC")
expected = np.repeat(
np.array([22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
np.array([n, n, n, n, n, n, n, n, n, n, n, n, 1]),
)
tm.assert_index_equal(idx.hour, Index(expected, dtype=np.int32))
# daily
# Start DST
idx = date_range("2014-03-08 00:00", "2014-03-09 00:00", freq="D", tz="UTC")
idx = idx.tz_convert("US/Eastern")
tm.assert_index_equal(idx.hour, Index([19, 19], dtype=np.int32))
idx = date_range(
"2014-03-08 00:00", "2014-03-09 00:00", freq="D", tz="US/Eastern"
)
idx = idx.tz_convert("UTC")
tm.assert_index_equal(idx.hour, Index([5, 5], dtype=np.int32))
# End DST
idx = date_range("2014-11-01 00:00", "2014-11-02 00:00", freq="D", tz="UTC")
idx = idx.tz_convert("US/Eastern")
tm.assert_index_equal(idx.hour, Index([20, 20], dtype=np.int32))
idx = date_range(
"2014-11-01 00:00", "2014-11-02 000:00", freq="D", tz="US/Eastern"
)
idx = idx.tz_convert("UTC")
tm.assert_index_equal(idx.hour, Index([4, 4], dtype=np.int32))
def test_tz_convert_roundtrip(self, tz_aware_fixture):
tz = tz_aware_fixture
idx1 = date_range(start="2014-01-01", end="2014-12-31", freq="ME", tz="UTC")
exp1 = date_range(start="2014-01-01", end="2014-12-31", freq="ME")
idx2 = date_range(start="2014-01-01", end="2014-12-31", freq="D", tz="UTC")
exp2 = date_range(start="2014-01-01", end="2014-12-31", freq="D")
idx3 = date_range(start="2014-01-01", end="2014-03-01", freq="h", tz="UTC")
exp3 = date_range(start="2014-01-01", end="2014-03-01", freq="h")
idx4 = date_range(start="2014-08-01", end="2014-10-31", freq="min", tz="UTC")
exp4 = date_range(start="2014-08-01", end="2014-10-31", freq="min")
for idx, expected in [(idx1, exp1), (idx2, exp2), (idx3, exp3), (idx4, exp4)]:
converted = idx.tz_convert(tz)
reset = converted.tz_convert(None)
tm.assert_index_equal(reset, expected)
assert reset.tzinfo is None
expected = converted.tz_convert("UTC").tz_localize(None)
expected = expected._with_freq("infer")
tm.assert_index_equal(reset, expected)
def test_dti_tz_convert_tzlocal(self):
# GH#13583
# tz_convert doesn't affect to internal
dti = date_range(start="2001-01-01", end="2001-03-01", tz="UTC")
dti2 = dti.tz_convert(dateutil.tz.tzlocal())
tm.assert_numpy_array_equal(dti2.asi8, dti.asi8)
dti = date_range(start="2001-01-01", end="2001-03-01", tz=dateutil.tz.tzlocal())
dti2 = dti.tz_convert(None)
tm.assert_numpy_array_equal(dti2.asi8, dti.asi8)
@pytest.mark.parametrize(
"tz",
[
"US/Eastern",
"dateutil/US/Eastern",
pytz.timezone("US/Eastern"),
gettz("US/Eastern"),
],
)
def test_dti_tz_convert_utc_to_local_no_modify(self, tz):
rng = date_range("3/11/2012", "3/12/2012", freq="h", tz="utc")
rng_eastern = rng.tz_convert(tz)
# Values are unmodified
tm.assert_numpy_array_equal(rng.asi8, rng_eastern.asi8)
assert timezones.tz_compare(rng_eastern.tz, timezones.maybe_get_tz(tz))
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
def test_tz_convert_unsorted(self, tzstr):
dr = date_range("2012-03-09", freq="h", periods=100, tz="utc")
dr = dr.tz_convert(tzstr)
result = dr[::-1].hour
exp = dr.hour[::-1]
tm.assert_almost_equal(result, exp)

View File

@ -0,0 +1,402 @@
from datetime import (
datetime,
timedelta,
)
import dateutil.tz
from dateutil.tz import gettz
import numpy as np
import pytest
import pytz
from pandas import (
DatetimeIndex,
Timestamp,
bdate_range,
date_range,
offsets,
to_datetime,
)
import pandas._testing as tm
try:
from zoneinfo import ZoneInfo
except ImportError:
# Cannot assign to a type [misc]
ZoneInfo = None # type: ignore[misc, assignment]
easts = [pytz.timezone("US/Eastern"), gettz("US/Eastern")]
if ZoneInfo is not None:
try:
tz = ZoneInfo("US/Eastern")
except KeyError:
# no tzdata
pass
else:
easts.append(tz)
class TestTZLocalize:
def test_tz_localize_invalidates_freq(self):
# we only preserve freq in unambiguous cases
# if localized to US/Eastern, this crosses a DST transition
dti = date_range("2014-03-08 23:00", "2014-03-09 09:00", freq="h")
assert dti.freq == "h"
result = dti.tz_localize(None) # no-op
assert result.freq == "h"
result = dti.tz_localize("UTC") # unambiguous freq preservation
assert result.freq == "h"
result = dti.tz_localize("US/Eastern", nonexistent="shift_forward")
assert result.freq is None
assert result.inferred_freq is None # i.e. we are not _too_ strict here
# Case where we _can_ keep freq because we're length==1
dti2 = dti[:1]
result = dti2.tz_localize("US/Eastern")
assert result.freq == "h"
def test_tz_localize_utc_copies(self, utc_fixture):
# GH#46460
times = ["2015-03-08 01:00", "2015-03-08 02:00", "2015-03-08 03:00"]
index = DatetimeIndex(times)
res = index.tz_localize(utc_fixture)
assert not tm.shares_memory(res, index)
res2 = index._data.tz_localize(utc_fixture)
assert not tm.shares_memory(index._data, res2)
def test_dti_tz_localize_nonexistent_raise_coerce(self):
# GH#13057
times = ["2015-03-08 01:00", "2015-03-08 02:00", "2015-03-08 03:00"]
index = DatetimeIndex(times)
tz = "US/Eastern"
with pytest.raises(pytz.NonExistentTimeError, match="|".join(times)):
index.tz_localize(tz=tz)
with pytest.raises(pytz.NonExistentTimeError, match="|".join(times)):
index.tz_localize(tz=tz, nonexistent="raise")
result = index.tz_localize(tz=tz, nonexistent="NaT")
test_times = ["2015-03-08 01:00-05:00", "NaT", "2015-03-08 03:00-04:00"]
dti = to_datetime(test_times, utc=True)
expected = dti.tz_convert("US/Eastern")
tm.assert_index_equal(result, expected)
@pytest.mark.parametrize("tz", easts)
def test_dti_tz_localize_ambiguous_infer(self, tz):
# November 6, 2011, fall back, repeat 2 AM hour
# With no repeated hours, we cannot infer the transition
dr = date_range(datetime(2011, 11, 6, 0), periods=5, freq=offsets.Hour())
with pytest.raises(pytz.AmbiguousTimeError, match="Cannot infer dst time"):
dr.tz_localize(tz)
@pytest.mark.parametrize("tz", easts)
def test_dti_tz_localize_ambiguous_infer2(self, tz, unit):
# With repeated hours, we can infer the transition
dr = date_range(
datetime(2011, 11, 6, 0), periods=5, freq=offsets.Hour(), tz=tz, unit=unit
)
times = [
"11/06/2011 00:00",
"11/06/2011 01:00",
"11/06/2011 01:00",
"11/06/2011 02:00",
"11/06/2011 03:00",
]
di = DatetimeIndex(times).as_unit(unit)
result = di.tz_localize(tz, ambiguous="infer")
expected = dr._with_freq(None)
tm.assert_index_equal(result, expected)
result2 = DatetimeIndex(times, tz=tz, ambiguous="infer").as_unit(unit)
tm.assert_index_equal(result2, expected)
@pytest.mark.parametrize("tz", easts)
def test_dti_tz_localize_ambiguous_infer3(self, tz):
# When there is no dst transition, nothing special happens
dr = date_range(datetime(2011, 6, 1, 0), periods=10, freq=offsets.Hour())
localized = dr.tz_localize(tz)
localized_infer = dr.tz_localize(tz, ambiguous="infer")
tm.assert_index_equal(localized, localized_infer)
@pytest.mark.parametrize("tz", easts)
def test_dti_tz_localize_ambiguous_times(self, tz):
# March 13, 2011, spring forward, skip from 2 AM to 3 AM
dr = date_range(datetime(2011, 3, 13, 1, 30), periods=3, freq=offsets.Hour())
with pytest.raises(pytz.NonExistentTimeError, match="2011-03-13 02:30:00"):
dr.tz_localize(tz)
# after dst transition, it works
dr = date_range(
datetime(2011, 3, 13, 3, 30), periods=3, freq=offsets.Hour(), tz=tz
)
# November 6, 2011, fall back, repeat 2 AM hour
dr = date_range(datetime(2011, 11, 6, 1, 30), periods=3, freq=offsets.Hour())
with pytest.raises(pytz.AmbiguousTimeError, match="Cannot infer dst time"):
dr.tz_localize(tz)
# UTC is OK
dr = date_range(
datetime(2011, 3, 13), periods=48, freq=offsets.Minute(30), tz=pytz.utc
)
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
def test_dti_tz_localize_pass_dates_to_utc(self, tzstr):
strdates = ["1/1/2012", "3/1/2012", "4/1/2012"]
idx = DatetimeIndex(strdates)
conv = idx.tz_localize(tzstr)
fromdates = DatetimeIndex(strdates, tz=tzstr)
assert conv.tz == fromdates.tz
tm.assert_numpy_array_equal(conv.values, fromdates.values)
@pytest.mark.parametrize("prefix", ["", "dateutil/"])
def test_dti_tz_localize(self, prefix):
tzstr = prefix + "US/Eastern"
dti = date_range(start="1/1/2005", end="1/1/2005 0:00:30.256", freq="ms")
dti2 = dti.tz_localize(tzstr)
dti_utc = date_range(
start="1/1/2005 05:00", end="1/1/2005 5:00:30.256", freq="ms", tz="utc"
)
tm.assert_numpy_array_equal(dti2.values, dti_utc.values)
dti3 = dti2.tz_convert(prefix + "US/Pacific")
tm.assert_numpy_array_equal(dti3.values, dti_utc.values)
dti = date_range(start="11/6/2011 1:59", end="11/6/2011 2:00", freq="ms")
with pytest.raises(pytz.AmbiguousTimeError, match="Cannot infer dst time"):
dti.tz_localize(tzstr)
dti = date_range(start="3/13/2011 1:59", end="3/13/2011 2:00", freq="ms")
with pytest.raises(pytz.NonExistentTimeError, match="2011-03-13 02:00:00"):
dti.tz_localize(tzstr)
@pytest.mark.parametrize(
"tz",
[
"US/Eastern",
"dateutil/US/Eastern",
pytz.timezone("US/Eastern"),
gettz("US/Eastern"),
],
)
def test_dti_tz_localize_utc_conversion(self, tz):
# Localizing to time zone should:
# 1) check for DST ambiguities
# 2) convert to UTC
rng = date_range("3/10/2012", "3/11/2012", freq="30min")
converted = rng.tz_localize(tz)
expected_naive = rng + offsets.Hour(5)
tm.assert_numpy_array_equal(converted.asi8, expected_naive.asi8)
# DST ambiguity, this should fail
rng = date_range("3/11/2012", "3/12/2012", freq="30min")
# Is this really how it should fail??
with pytest.raises(pytz.NonExistentTimeError, match="2012-03-11 02:00:00"):
rng.tz_localize(tz)
def test_dti_tz_localize_roundtrip(self, tz_aware_fixture):
# note: this tz tests that a tz-naive index can be localized
# and de-localized successfully, when there are no DST transitions
# in the range.
idx = date_range(start="2014-06-01", end="2014-08-30", freq="15min")
tz = tz_aware_fixture
localized = idx.tz_localize(tz)
# can't localize a tz-aware object
with pytest.raises(
TypeError, match="Already tz-aware, use tz_convert to convert"
):
localized.tz_localize(tz)
reset = localized.tz_localize(None)
assert reset.tzinfo is None
expected = idx._with_freq(None)
tm.assert_index_equal(reset, expected)
def test_dti_tz_localize_naive(self):
rng = date_range("1/1/2011", periods=100, freq="h")
conv = rng.tz_localize("US/Pacific")
exp = date_range("1/1/2011", periods=100, freq="h", tz="US/Pacific")
tm.assert_index_equal(conv, exp._with_freq(None))
def test_dti_tz_localize_tzlocal(self):
# GH#13583
offset = dateutil.tz.tzlocal().utcoffset(datetime(2011, 1, 1))
offset = int(offset.total_seconds() * 1000000000)
dti = date_range(start="2001-01-01", end="2001-03-01")
dti2 = dti.tz_localize(dateutil.tz.tzlocal())
tm.assert_numpy_array_equal(dti2.asi8 + offset, dti.asi8)
dti = date_range(start="2001-01-01", end="2001-03-01", tz=dateutil.tz.tzlocal())
dti2 = dti.tz_localize(None)
tm.assert_numpy_array_equal(dti2.asi8 - offset, dti.asi8)
@pytest.mark.parametrize("tz", easts)
def test_dti_tz_localize_ambiguous_nat(self, tz):
times = [
"11/06/2011 00:00",
"11/06/2011 01:00",
"11/06/2011 01:00",
"11/06/2011 02:00",
"11/06/2011 03:00",
]
di = DatetimeIndex(times)
localized = di.tz_localize(tz, ambiguous="NaT")
times = [
"11/06/2011 00:00",
np.nan,
np.nan,
"11/06/2011 02:00",
"11/06/2011 03:00",
]
di_test = DatetimeIndex(times, tz="US/Eastern")
# left dtype is datetime64[ns, US/Eastern]
# right is datetime64[ns, tzfile('/usr/share/zoneinfo/US/Eastern')]
tm.assert_numpy_array_equal(di_test.values, localized.values)
@pytest.mark.parametrize("tz", easts)
def test_dti_tz_localize_ambiguous_flags(self, tz, unit):
# November 6, 2011, fall back, repeat 2 AM hour
# Pass in flags to determine right dst transition
dr = date_range(
datetime(2011, 11, 6, 0), periods=5, freq=offsets.Hour(), tz=tz, unit=unit
)
times = [
"11/06/2011 00:00",
"11/06/2011 01:00",
"11/06/2011 01:00",
"11/06/2011 02:00",
"11/06/2011 03:00",
]
# Test tz_localize
di = DatetimeIndex(times).as_unit(unit)
is_dst = [1, 1, 0, 0, 0]
localized = di.tz_localize(tz, ambiguous=is_dst)
expected = dr._with_freq(None)
tm.assert_index_equal(expected, localized)
result = DatetimeIndex(times, tz=tz, ambiguous=is_dst).as_unit(unit)
tm.assert_index_equal(result, expected)
localized = di.tz_localize(tz, ambiguous=np.array(is_dst))
tm.assert_index_equal(dr, localized)
localized = di.tz_localize(tz, ambiguous=np.array(is_dst).astype("bool"))
tm.assert_index_equal(dr, localized)
# Test constructor
localized = DatetimeIndex(times, tz=tz, ambiguous=is_dst).as_unit(unit)
tm.assert_index_equal(dr, localized)
# Test duplicate times where inferring the dst fails
times += times
di = DatetimeIndex(times).as_unit(unit)
# When the sizes are incompatible, make sure error is raised
msg = "Length of ambiguous bool-array must be the same size as vals"
with pytest.raises(Exception, match=msg):
di.tz_localize(tz, ambiguous=is_dst)
# When sizes are compatible and there are repeats ('infer' won't work)
is_dst = np.hstack((is_dst, is_dst))
localized = di.tz_localize(tz, ambiguous=is_dst)
dr = dr.append(dr)
tm.assert_index_equal(dr, localized)
@pytest.mark.parametrize("tz", easts)
def test_dti_tz_localize_ambiguous_flags2(self, tz, unit):
# When there is no dst transition, nothing special happens
dr = date_range(datetime(2011, 6, 1, 0), periods=10, freq=offsets.Hour())
is_dst = np.array([1] * 10)
localized = dr.tz_localize(tz)
localized_is_dst = dr.tz_localize(tz, ambiguous=is_dst)
tm.assert_index_equal(localized, localized_is_dst)
def test_dti_tz_localize_bdate_range(self):
dr = bdate_range("1/1/2009", "1/1/2010")
dr_utc = bdate_range("1/1/2009", "1/1/2010", tz=pytz.utc)
localized = dr.tz_localize(pytz.utc)
tm.assert_index_equal(dr_utc, localized)
@pytest.mark.parametrize(
"start_ts, tz, end_ts, shift",
[
["2015-03-29 02:20:00", "Europe/Warsaw", "2015-03-29 03:00:00", "forward"],
[
"2015-03-29 02:20:00",
"Europe/Warsaw",
"2015-03-29 01:59:59.999999999",
"backward",
],
[
"2015-03-29 02:20:00",
"Europe/Warsaw",
"2015-03-29 03:20:00",
timedelta(hours=1),
],
[
"2015-03-29 02:20:00",
"Europe/Warsaw",
"2015-03-29 01:20:00",
timedelta(hours=-1),
],
["2018-03-11 02:33:00", "US/Pacific", "2018-03-11 03:00:00", "forward"],
[
"2018-03-11 02:33:00",
"US/Pacific",
"2018-03-11 01:59:59.999999999",
"backward",
],
[
"2018-03-11 02:33:00",
"US/Pacific",
"2018-03-11 03:33:00",
timedelta(hours=1),
],
[
"2018-03-11 02:33:00",
"US/Pacific",
"2018-03-11 01:33:00",
timedelta(hours=-1),
],
],
)
@pytest.mark.parametrize("tz_type", ["", "dateutil/"])
def test_dti_tz_localize_nonexistent_shift(
self, start_ts, tz, end_ts, shift, tz_type, unit
):
# GH#8917
tz = tz_type + tz
if isinstance(shift, str):
shift = "shift_" + shift
dti = DatetimeIndex([Timestamp(start_ts)]).as_unit(unit)
result = dti.tz_localize(tz, nonexistent=shift)
expected = DatetimeIndex([Timestamp(end_ts)]).tz_localize(tz).as_unit(unit)
tm.assert_index_equal(result, expected)
@pytest.mark.parametrize("offset", [-1, 1])
def test_dti_tz_localize_nonexistent_shift_invalid(self, offset, warsaw):
# GH#8917
tz = warsaw
dti = DatetimeIndex([Timestamp("2015-03-29 02:20:00")])
msg = "The provided timedelta will relocalize on a nonexistent time"
with pytest.raises(ValueError, match=msg):
dti.tz_localize(tz, nonexistent=timedelta(seconds=offset))

View File

@ -0,0 +1,77 @@
from datetime import (
datetime,
timedelta,
)
from pandas import (
DatetimeIndex,
NaT,
Timestamp,
)
import pandas._testing as tm
def test_unique(tz_naive_fixture):
idx = DatetimeIndex(["2017"] * 2, tz=tz_naive_fixture)
expected = idx[:1]
result = idx.unique()
tm.assert_index_equal(result, expected)
# GH#21737
# Ensure the underlying data is consistent
assert result[0] == expected[0]
def test_index_unique(rand_series_with_duplicate_datetimeindex):
dups = rand_series_with_duplicate_datetimeindex
index = dups.index
uniques = index.unique()
expected = DatetimeIndex(
[
datetime(2000, 1, 2),
datetime(2000, 1, 3),
datetime(2000, 1, 4),
datetime(2000, 1, 5),
],
dtype=index.dtype,
)
assert uniques.dtype == index.dtype # sanity
tm.assert_index_equal(uniques, expected)
assert index.nunique() == 4
# GH#2563
assert isinstance(uniques, DatetimeIndex)
dups_local = index.tz_localize("US/Eastern")
dups_local.name = "foo"
result = dups_local.unique()
expected = DatetimeIndex(expected, name="foo")
expected = expected.tz_localize("US/Eastern")
assert result.tz is not None
assert result.name == "foo"
tm.assert_index_equal(result, expected)
def test_index_unique2():
# NaT, note this is excluded
arr = [1370745748 + t for t in range(20)] + [NaT._value]
idx = DatetimeIndex(arr * 3)
tm.assert_index_equal(idx.unique(), DatetimeIndex(arr))
assert idx.nunique() == 20
assert idx.nunique(dropna=False) == 21
def test_index_unique3():
arr = [
Timestamp("2013-06-09 02:42:28") + timedelta(seconds=t) for t in range(20)
] + [NaT]
idx = DatetimeIndex(arr * 3)
tm.assert_index_equal(idx.unique(), DatetimeIndex(arr))
assert idx.nunique() == 20
assert idx.nunique(dropna=False) == 21
def test_is_unique_monotonic(rand_series_with_duplicate_datetimeindex):
index = rand_series_with_duplicate_datetimeindex.index
assert not index.is_unique