done
This commit is contained in:
@ -0,0 +1,251 @@
|
||||
"""
|
||||
Tests for DatetimeIndex timezone-related methods
|
||||
"""
|
||||
from datetime import (
|
||||
datetime,
|
||||
timedelta,
|
||||
timezone,
|
||||
tzinfo,
|
||||
)
|
||||
|
||||
from dateutil.tz import gettz
|
||||
import numpy as np
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pandas._libs.tslibs import (
|
||||
conversion,
|
||||
timezones,
|
||||
)
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
DatetimeIndex,
|
||||
Timestamp,
|
||||
bdate_range,
|
||||
date_range,
|
||||
isna,
|
||||
to_datetime,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
|
||||
|
||||
class FixedOffset(tzinfo):
|
||||
"""Fixed offset in minutes east from UTC."""
|
||||
|
||||
def __init__(self, offset, name) -> None:
|
||||
self.__offset = timedelta(minutes=offset)
|
||||
self.__name = name
|
||||
|
||||
def utcoffset(self, dt):
|
||||
return self.__offset
|
||||
|
||||
def tzname(self, dt):
|
||||
return self.__name
|
||||
|
||||
def dst(self, dt):
|
||||
return timedelta(0)
|
||||
|
||||
|
||||
fixed_off_no_name = FixedOffset(-330, None)
|
||||
|
||||
|
||||
class TestDatetimeIndexTimezones:
|
||||
# -------------------------------------------------------------
|
||||
# Unsorted
|
||||
|
||||
def test_dti_drop_dont_lose_tz(self):
|
||||
# GH#2621
|
||||
ind = date_range("2012-12-01", periods=10, tz="utc")
|
||||
ind = ind.drop(ind[-1])
|
||||
|
||||
assert ind.tz is not None
|
||||
|
||||
def test_dti_tz_conversion_freq(self, tz_naive_fixture):
|
||||
# GH25241
|
||||
t3 = DatetimeIndex(["2019-01-01 10:00"], freq="h")
|
||||
assert t3.tz_localize(tz=tz_naive_fixture).freq == t3.freq
|
||||
t4 = DatetimeIndex(["2019-01-02 12:00"], tz="UTC", freq="min")
|
||||
assert t4.tz_convert(tz="UTC").freq == t4.freq
|
||||
|
||||
def test_drop_dst_boundary(self):
|
||||
# see gh-18031
|
||||
tz = "Europe/Brussels"
|
||||
freq = "15min"
|
||||
|
||||
start = Timestamp("201710290100", tz=tz)
|
||||
end = Timestamp("201710290300", tz=tz)
|
||||
index = date_range(start=start, end=end, freq=freq)
|
||||
|
||||
expected = DatetimeIndex(
|
||||
[
|
||||
"201710290115",
|
||||
"201710290130",
|
||||
"201710290145",
|
||||
"201710290200",
|
||||
"201710290215",
|
||||
"201710290230",
|
||||
"201710290245",
|
||||
"201710290200",
|
||||
"201710290215",
|
||||
"201710290230",
|
||||
"201710290245",
|
||||
"201710290300",
|
||||
],
|
||||
dtype="M8[ns, Europe/Brussels]",
|
||||
freq=freq,
|
||||
ambiguous=[
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
],
|
||||
)
|
||||
result = index.drop(index[0])
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
def test_date_range_localize(self, unit):
|
||||
rng = date_range(
|
||||
"3/11/2012 03:00", periods=15, freq="h", tz="US/Eastern", unit=unit
|
||||
)
|
||||
rng2 = DatetimeIndex(
|
||||
["3/11/2012 03:00", "3/11/2012 04:00"], dtype=f"M8[{unit}, US/Eastern]"
|
||||
)
|
||||
rng3 = date_range("3/11/2012 03:00", periods=15, freq="h", unit=unit)
|
||||
rng3 = rng3.tz_localize("US/Eastern")
|
||||
|
||||
tm.assert_index_equal(rng._with_freq(None), rng3)
|
||||
|
||||
# DST transition time
|
||||
val = rng[0]
|
||||
exp = Timestamp("3/11/2012 03:00", tz="US/Eastern")
|
||||
|
||||
assert val.hour == 3
|
||||
assert exp.hour == 3
|
||||
assert val == exp # same UTC value
|
||||
tm.assert_index_equal(rng[:2], rng2)
|
||||
|
||||
def test_date_range_localize2(self, unit):
|
||||
# Right before the DST transition
|
||||
rng = date_range(
|
||||
"3/11/2012 00:00", periods=2, freq="h", tz="US/Eastern", unit=unit
|
||||
)
|
||||
rng2 = DatetimeIndex(
|
||||
["3/11/2012 00:00", "3/11/2012 01:00"],
|
||||
dtype=f"M8[{unit}, US/Eastern]",
|
||||
freq="h",
|
||||
)
|
||||
tm.assert_index_equal(rng, rng2)
|
||||
exp = Timestamp("3/11/2012 00:00", tz="US/Eastern")
|
||||
assert exp.hour == 0
|
||||
assert rng[0] == exp
|
||||
exp = Timestamp("3/11/2012 01:00", tz="US/Eastern")
|
||||
assert exp.hour == 1
|
||||
assert rng[1] == exp
|
||||
|
||||
rng = date_range(
|
||||
"3/11/2012 00:00", periods=10, freq="h", tz="US/Eastern", unit=unit
|
||||
)
|
||||
assert rng[2].hour == 3
|
||||
|
||||
def test_timestamp_equality_different_timezones(self):
|
||||
utc_range = date_range("1/1/2000", periods=20, tz="UTC")
|
||||
eastern_range = utc_range.tz_convert("US/Eastern")
|
||||
berlin_range = utc_range.tz_convert("Europe/Berlin")
|
||||
|
||||
for a, b, c in zip(utc_range, eastern_range, berlin_range):
|
||||
assert a == b
|
||||
assert b == c
|
||||
assert a == c
|
||||
|
||||
assert (utc_range == eastern_range).all()
|
||||
assert (utc_range == berlin_range).all()
|
||||
assert (berlin_range == eastern_range).all()
|
||||
|
||||
def test_dti_equals_with_tz(self):
|
||||
left = date_range("1/1/2011", periods=100, freq="h", tz="utc")
|
||||
right = date_range("1/1/2011", periods=100, freq="h", tz="US/Eastern")
|
||||
|
||||
assert not left.equals(right)
|
||||
|
||||
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
|
||||
def test_dti_tz_nat(self, tzstr):
|
||||
idx = DatetimeIndex([Timestamp("2013-1-1", tz=tzstr), pd.NaT])
|
||||
|
||||
assert isna(idx[1])
|
||||
assert idx[0].tzinfo is not None
|
||||
|
||||
@pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"])
|
||||
def test_utc_box_timestamp_and_localize(self, tzstr):
|
||||
tz = timezones.maybe_get_tz(tzstr)
|
||||
|
||||
rng = date_range("3/11/2012", "3/12/2012", freq="h", tz="utc")
|
||||
rng_eastern = rng.tz_convert(tzstr)
|
||||
|
||||
expected = rng[-1].astimezone(tz)
|
||||
|
||||
stamp = rng_eastern[-1]
|
||||
assert stamp == expected
|
||||
assert stamp.tzinfo == expected.tzinfo
|
||||
|
||||
# right tzinfo
|
||||
rng = date_range("3/13/2012", "3/14/2012", freq="h", tz="utc")
|
||||
rng_eastern = rng.tz_convert(tzstr)
|
||||
# test not valid for dateutil timezones.
|
||||
# assert 'EDT' in repr(rng_eastern[0].tzinfo)
|
||||
assert "EDT" in repr(rng_eastern[0].tzinfo) or "tzfile" in repr(
|
||||
rng_eastern[0].tzinfo
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("tz", [pytz.timezone("US/Central"), gettz("US/Central")])
|
||||
def test_with_tz(self, tz):
|
||||
# just want it to work
|
||||
start = datetime(2011, 3, 12, tzinfo=pytz.utc)
|
||||
dr = bdate_range(start, periods=50, freq=pd.offsets.Hour())
|
||||
assert dr.tz is pytz.utc
|
||||
|
||||
# DateRange with naive datetimes
|
||||
dr = bdate_range("1/1/2005", "1/1/2009", tz=pytz.utc)
|
||||
dr = bdate_range("1/1/2005", "1/1/2009", tz=tz)
|
||||
|
||||
# normalized
|
||||
central = dr.tz_convert(tz)
|
||||
assert central.tz is tz
|
||||
naive = central[0].to_pydatetime().replace(tzinfo=None)
|
||||
comp = conversion.localize_pydatetime(naive, tz).tzinfo
|
||||
assert central[0].tz is comp
|
||||
|
||||
# compare vs a localized tz
|
||||
naive = dr[0].to_pydatetime().replace(tzinfo=None)
|
||||
comp = conversion.localize_pydatetime(naive, tz).tzinfo
|
||||
assert central[0].tz is comp
|
||||
|
||||
# datetimes with tzinfo set
|
||||
dr = bdate_range(
|
||||
datetime(2005, 1, 1, tzinfo=pytz.utc), datetime(2009, 1, 1, tzinfo=pytz.utc)
|
||||
)
|
||||
msg = "Start and end cannot both be tz-aware with different timezones"
|
||||
with pytest.raises(Exception, match=msg):
|
||||
bdate_range(datetime(2005, 1, 1, tzinfo=pytz.utc), "1/1/2009", tz=tz)
|
||||
|
||||
@pytest.mark.parametrize("tz", [pytz.timezone("US/Eastern"), gettz("US/Eastern")])
|
||||
def test_dti_convert_tz_aware_datetime_datetime(self, tz):
|
||||
# GH#1581
|
||||
dates = [datetime(2000, 1, 1), datetime(2000, 1, 2), datetime(2000, 1, 3)]
|
||||
|
||||
dates_aware = [conversion.localize_pydatetime(x, tz) for x in dates]
|
||||
result = DatetimeIndex(dates_aware).as_unit("ns")
|
||||
assert timezones.tz_compare(result.tz, tz)
|
||||
|
||||
converted = to_datetime(dates_aware, utc=True).as_unit("ns")
|
||||
ex_vals = np.array([Timestamp(x).as_unit("ns")._value for x in dates_aware])
|
||||
tm.assert_numpy_array_equal(converted.asi8, ex_vals)
|
||||
assert converted.tz is timezone.utc
|
Reference in New Issue
Block a user