""" test partial slicing on Series/Frame """

from datetime import datetime

import numpy as np
import pytest

from pandas import (
    DataFrame,
    DatetimeIndex,
    Index,
    Series,
    Timedelta,
    Timestamp,
    date_range,
)
import pandas._testing as tm


class TestSlicing:
    def test_string_index_series_name_converted(self):
        # GH#1644
        df = DataFrame(
            np.random.default_rng(2).standard_normal((10, 4)),
            index=date_range("1/1/2000", periods=10),
        )

        result = df.loc["1/3/2000"]
        assert result.name == df.index[2]

        result = df.T["1/3/2000"]
        assert result.name == df.index[2]

    def test_stringified_slice_with_tz(self):
        # GH#2658
        start = "2013-01-07"
        idx = date_range(start=start, freq="1d", periods=10, tz="US/Eastern")
        df = DataFrame(np.arange(10), index=idx)
        df["2013-01-14 23:44:34.437768-05:00":]  # no exception here

    def test_return_type_doesnt_depend_on_monotonicity(self):
        # GH#24892 we get Series back regardless of whether our DTI is monotonic
        dti = date_range(start="2015-5-13 23:59:00", freq="min", periods=3)
        ser = Series(range(3), index=dti)

        # non-monotonic index
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])

        # key with resolution strictly lower than "min"
        key = "2015-5-14 00"

        # monotonic increasing index
        result = ser.loc[key]
        expected = ser.iloc[1:]
        tm.assert_series_equal(result, expected)

        # monotonic decreasing index
        result = ser.iloc[::-1].loc[key]
        expected = ser.iloc[::-1][:-1]
        tm.assert_series_equal(result, expected)

        # non-monotonic index
        result2 = ser2.loc[key]
        expected2 = ser2.iloc[::2]
        tm.assert_series_equal(result2, expected2)

    def test_return_type_doesnt_depend_on_monotonicity_higher_reso(self):
        # GH#24892 we get Series back regardless of whether our DTI is monotonic
        dti = date_range(start="2015-5-13 23:59:00", freq="min", periods=3)
        ser = Series(range(3), index=dti)

        # non-monotonic index
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])

        # key with resolution strictly *higher) than "min"
        key = "2015-5-14 00:00:00"

        # monotonic increasing index
        result = ser.loc[key]
        assert result == 1

        # monotonic decreasing index
        result = ser.iloc[::-1].loc[key]
        assert result == 1

        # non-monotonic index
        result2 = ser2.loc[key]
        assert result2 == 0

    def test_monotone_DTI_indexing_bug(self):
        # GH 19362
        # Testing accessing the first element in a monotonic descending
        # partial string indexing.

        df = DataFrame(list(range(5)))
        date_list = [
            "2018-01-02",
            "2017-02-10",
            "2016-03-10",
            "2015-03-15",
            "2014-03-16",
        ]
        date_index = DatetimeIndex(date_list)
        df["date"] = date_index
        expected = DataFrame({0: list(range(5)), "date": date_index})
        tm.assert_frame_equal(df, expected)

        # We get a slice because df.index's resolution is hourly and we
        #  are slicing with a daily-resolution string.  If both were daily,
        #  we would get a single item back
        dti = date_range("20170101 01:00:00", periods=3)
        df = DataFrame({"A": [1, 2, 3]}, index=dti[::-1])

        expected = DataFrame({"A": 1}, index=dti[-1:][::-1])
        result = df.loc["2017-01-03"]
        tm.assert_frame_equal(result, expected)

        result2 = df.iloc[::-1].loc["2017-01-03"]
        expected2 = expected.iloc[::-1]
        tm.assert_frame_equal(result2, expected2)

    def test_slice_year(self):
        dti = date_range(freq="B", start=datetime(2005, 1, 1), periods=500)

        s = Series(np.arange(len(dti)), index=dti)
        result = s["2005"]
        expected = s[s.index.year == 2005]
        tm.assert_series_equal(result, expected)

        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)), index=dti)
        result = df.loc["2005"]
        expected = df[df.index.year == 2005]
        tm.assert_frame_equal(result, expected)

    @pytest.mark.parametrize(
        "partial_dtime",
        [
            "2019",
            "2019Q4",
            "Dec 2019",
            "2019-12-31",
            "2019-12-31 23",
            "2019-12-31 23:59",
        ],
    )
    def test_slice_end_of_period_resolution(self, partial_dtime):
        # GH#31064
        dti = date_range("2019-12-31 23:59:55.999999999", periods=10, freq="s")

        ser = Series(range(10), index=dti)
        result = ser[partial_dtime]
        expected = ser.iloc[:5]
        tm.assert_series_equal(result, expected)

    def test_slice_quarter(self):
        dti = date_range(freq="D", start=datetime(2000, 6, 1), periods=500)

        s = Series(np.arange(len(dti)), index=dti)
        assert len(s["2001Q1"]) == 90

        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)), index=dti)
        assert len(df.loc["1Q01"]) == 90

    def test_slice_month(self):
        dti = date_range(freq="D", start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s["2005-11"]) == 30

        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)), index=dti)
        assert len(df.loc["2005-11"]) == 30

        tm.assert_series_equal(s["2005-11"], s["11-2005"])

    def test_partial_slice(self):
        rng = date_range(freq="D", start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["2005-05":"2006-02"]
        expected = s["20050501":"20060228"]
        tm.assert_series_equal(result, expected)

        result = s["2005-05":]
        expected = s["20050501":]
        tm.assert_series_equal(result, expected)

        result = s[:"2006-02"]
        expected = s[:"20060228"]
        tm.assert_series_equal(result, expected)

        result = s["2005-1-1"]
        assert result == s.iloc[0]

        with pytest.raises(KeyError, match=r"^'2004-12-31'$"):
            s["2004-12-31"]

    def test_partial_slice_daily(self):
        rng = date_range(freq="H", start=datetime(2005, 1, 31), periods=500)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["2005-1-31"]
        tm.assert_series_equal(result, s.iloc[:24])

        with pytest.raises(KeyError, match=r"^'2004-12-31 00'$"):
            s["2004-12-31 00"]

    def test_partial_slice_hourly(self):
        rng = date_range(freq="min", start=datetime(2005, 1, 1, 20, 0, 0), periods=500)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["2005-1-1"]
        tm.assert_series_equal(result, s.iloc[: 60 * 4])

        result = s["2005-1-1 20"]
        tm.assert_series_equal(result, s.iloc[:60])

        assert s["2005-1-1 20:00"] == s.iloc[0]
        with pytest.raises(KeyError, match=r"^'2004-12-31 00:15'$"):
            s["2004-12-31 00:15"]

    def test_partial_slice_minutely(self):
        rng = date_range(freq="s", start=datetime(2005, 1, 1, 23, 59, 0), periods=500)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["2005-1-1 23:59"]
        tm.assert_series_equal(result, s.iloc[:60])

        result = s["2005-1-1"]
        tm.assert_series_equal(result, s.iloc[:60])

        assert s[Timestamp("2005-1-1 23:59:00")] == s.iloc[0]
        with pytest.raises(KeyError, match=r"^'2004-12-31 00:00:00'$"):
            s["2004-12-31 00:00:00"]

    def test_partial_slice_second_precision(self):
        rng = date_range(
            start=datetime(2005, 1, 1, 0, 0, 59, microsecond=999990),
            periods=20,
            freq="US",
        )
        s = Series(np.arange(20), rng)

        tm.assert_series_equal(s["2005-1-1 00:00"], s.iloc[:10])
        tm.assert_series_equal(s["2005-1-1 00:00:59"], s.iloc[:10])

        tm.assert_series_equal(s["2005-1-1 00:01"], s.iloc[10:])
        tm.assert_series_equal(s["2005-1-1 00:01:00"], s.iloc[10:])

        assert s[Timestamp("2005-1-1 00:00:59.999990")] == s.iloc[0]
        with pytest.raises(KeyError, match="2005-1-1 00:00:00"):
            s["2005-1-1 00:00:00"]

    def test_partial_slicing_dataframe(self):
        # GH14856
        # Test various combinations of string slicing resolution vs.
        # index resolution
        # - If string resolution is less precise than index resolution,
        # string is considered a slice
        # - If string resolution is equal to or more precise than index
        # resolution, string is considered an exact match
        formats = [
            "%Y",
            "%Y-%m",
            "%Y-%m-%d",
            "%Y-%m-%d %H",
            "%Y-%m-%d %H:%M",
            "%Y-%m-%d %H:%M:%S",
        ]
        resolutions = ["year", "month", "day", "hour", "minute", "second"]
        for rnum, resolution in enumerate(resolutions[2:], 2):
            # we check only 'day', 'hour', 'minute' and 'second'
            unit = Timedelta("1 " + resolution)
            middate = datetime(2012, 1, 1, 0, 0, 0)
            index = DatetimeIndex([middate - unit, middate, middate + unit])
            values = [1, 2, 3]
            df = DataFrame({"a": values}, index, dtype=np.int64)
            assert df.index.resolution == resolution

            # Timestamp with the same resolution as index
            # Should be exact match for Series (return scalar)
            # and raise KeyError for Frame
            for timestamp, expected in zip(index, values):
                ts_string = timestamp.strftime(formats[rnum])
                # make ts_string as precise as index
                result = df["a"][ts_string]
                assert isinstance(result, np.int64)
                assert result == expected
                msg = rf"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]

            # Timestamp with resolution less precise than index
            for fmt in formats[:rnum]:
                for element, theslice in [[0, slice(None, 1)], [1, slice(1, None)]]:
                    ts_string = index[element].strftime(fmt)

                    # Series should return slice
                    result = df["a"][ts_string]
                    expected = df["a"][theslice]
                    tm.assert_series_equal(result, expected)

                    # pre-2.0 df[ts_string] was overloaded to interpret this
                    #  as slicing along index
                    with pytest.raises(KeyError, match=ts_string):
                        df[ts_string]

            # Timestamp with resolution more precise than index
            # Compatible with existing key
            # Should return scalar for Series
            # and raise KeyError for Frame
            for fmt in formats[rnum + 1 :]:
                ts_string = index[1].strftime(fmt)
                result = df["a"][ts_string]
                assert isinstance(result, np.int64)
                assert result == 2
                msg = rf"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]

            # Not compatible with existing key
            # Should raise KeyError
            for fmt, res in list(zip(formats, resolutions))[rnum + 1 :]:
                ts = index[1] + Timedelta("1 " + res)
                ts_string = ts.strftime(fmt)
                msg = rf"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df["a"][ts_string]
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]

    def test_partial_slicing_with_multiindex(self):
        # GH 4758
        # partial string indexing with a multi-index buggy
        df = DataFrame(
            {
                "ACCOUNT": ["ACCT1", "ACCT1", "ACCT1", "ACCT2"],
                "TICKER": ["ABC", "MNP", "XYZ", "XYZ"],
                "val": [1, 2, 3, 4],
            },
            index=date_range("2013-06-19 09:30:00", periods=4, freq="5min"),
        )
        df_multi = df.set_index(["ACCOUNT", "TICKER"], append=True)

        expected = DataFrame(
            [[1]], index=Index(["ABC"], name="TICKER"), columns=["val"]
        )
        result = df_multi.loc[("2013-06-19 09:30:00", "ACCT1")]
        tm.assert_frame_equal(result, expected)

        expected = df_multi.loc[
            (Timestamp("2013-06-19 09:30:00", tz=None), "ACCT1", "ABC")
        ]
        result = df_multi.loc[("2013-06-19 09:30:00", "ACCT1", "ABC")]
        tm.assert_series_equal(result, expected)

        # partial string indexing on first level, scalar indexing on the other two
        result = df_multi.loc[("2013-06-19", "ACCT1", "ABC")]
        expected = df_multi.iloc[:1].droplevel([1, 2])
        tm.assert_frame_equal(result, expected)

    def test_partial_slicing_with_multiindex_series(self):
        # GH 4294
        # partial slice on a series mi
        ser = DataFrame(
            np.random.default_rng(2).random((1000, 1000)),
            index=date_range("2000-1-1", periods=1000),
        ).stack(future_stack=True)

        s2 = ser[:-1].copy()
        expected = s2["2000-1-4"]
        result = s2[Timestamp("2000-1-4")]
        tm.assert_series_equal(result, expected)

        result = ser[Timestamp("2000-1-4")]
        expected = ser["2000-1-4"]
        tm.assert_series_equal(result, expected)

        df2 = DataFrame(ser)
        expected = df2.xs("2000-1-4")
        result = df2.loc[Timestamp("2000-1-4")]
        tm.assert_frame_equal(result, expected)

    def test_partial_slice_requires_monotonicity(self):
        # Disallowed since 2.0 (GH 37819)
        ser = Series(np.arange(10), date_range("2014-01-01", periods=10))

        nonmonotonic = ser.iloc[[3, 5, 4]]
        timestamp = Timestamp("2014-01-10")
        with pytest.raises(
            KeyError, match="Value based partial slicing on non-monotonic"
        ):
            nonmonotonic["2014-01-10":]

        with pytest.raises(KeyError, match=r"Timestamp\('2014-01-10 00:00:00'\)"):
            nonmonotonic[timestamp:]

        with pytest.raises(
            KeyError, match="Value based partial slicing on non-monotonic"
        ):
            nonmonotonic.loc["2014-01-10":]

        with pytest.raises(KeyError, match=r"Timestamp\('2014-01-10 00:00:00'\)"):
            nonmonotonic.loc[timestamp:]

    def test_loc_datetime_length_one(self):
        # GH16071
        df = DataFrame(
            columns=["1"],
            index=date_range("2016-10-01T00:00:00", "2016-10-01T23:59:59"),
        )
        result = df.loc[datetime(2016, 10, 1) :]
        tm.assert_frame_equal(result, df)

        result = df.loc["2016-10-01T00:00:00":]
        tm.assert_frame_equal(result, df)

    @pytest.mark.parametrize(
        "start",
        [
            "2018-12-02 21:50:00+00:00",
            Timestamp("2018-12-02 21:50:00+00:00"),
            Timestamp("2018-12-02 21:50:00+00:00").to_pydatetime(),
        ],
    )
    @pytest.mark.parametrize(
        "end",
        [
            "2018-12-02 21:52:00+00:00",
            Timestamp("2018-12-02 21:52:00+00:00"),
            Timestamp("2018-12-02 21:52:00+00:00").to_pydatetime(),
        ],
    )
    def test_getitem_with_datestring_with_UTC_offset(self, start, end):
        # GH 24076
        idx = date_range(
            start="2018-12-02 14:50:00-07:00",
            end="2018-12-02 14:50:00-07:00",
            freq="1min",
        )
        df = DataFrame(1, index=idx, columns=["A"])
        result = df[start:end]
        expected = df.iloc[0:3, :]
        tm.assert_frame_equal(result, expected)

        # GH 16785
        start = str(start)
        end = str(end)
        with pytest.raises(ValueError, match="Both dates must"):
            df[start : end[:-4] + "1:00"]

        with pytest.raises(ValueError, match="The index must be timezone"):
            df = df.tz_localize(None)
            df[start:end]

    def test_slice_reduce_to_series(self):
        # GH 27516
        df = DataFrame({"A": range(24)}, index=date_range("2000", periods=24, freq="M"))
        expected = Series(
            range(12), index=date_range("2000", periods=12, freq="M"), name="A"
        )
        result = df.loc["2000", "A"]
        tm.assert_series_equal(result, expected)

d836edf1034b892625f3abf2c7dddb020de90c91
<mask token>


class TestSlicing:

    def test_string_index_series_name_converted(self):
        df = DataFrame(np.random.default_rng(2).standard_normal((10, 4)),
            index=date_range('1/1/2000', periods=10))
        result = df.loc['1/3/2000']
        assert result.name == df.index[2]
        result = df.T['1/3/2000']
        assert result.name == df.index[2]

    def test_stringified_slice_with_tz(self):
        start = '2013-01-07'
        idx = date_range(start=start, freq='1d', periods=10, tz='US/Eastern')
        df = DataFrame(np.arange(10), index=idx)
        df['2013-01-14 23:44:34.437768-05:00':]
    <mask token>

    def test_return_type_doesnt_depend_on_monotonicity_higher_reso(self):
        dti = date_range(start='2015-5-13 23:59:00', freq='min', periods=3)
        ser = Series(range(3), index=dti)
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])
        key = '2015-5-14 00:00:00'
        result = ser.loc[key]
        assert result == 1
        result = ser.iloc[::-1].loc[key]
        assert result == 1
        result2 = ser2.loc[key]
        assert result2 == 0

    def test_monotone_DTI_indexing_bug(self):
        df = DataFrame(list(range(5)))
        date_list = ['2018-01-02', '2017-02-10', '2016-03-10', '2015-03-15',
            '2014-03-16']
        date_index = DatetimeIndex(date_list)
        df['date'] = date_index
        expected = DataFrame({(0): list(range(5)), 'date': date_index})
        tm.assert_frame_equal(df, expected)
        dti = date_range('20170101 01:00:00', periods=3)
        df = DataFrame({'A': [1, 2, 3]}, index=dti[::-1])
        expected = DataFrame({'A': 1}, index=dti[-1:][::-1])
        result = df.loc['2017-01-03']
        tm.assert_frame_equal(result, expected)
        result2 = df.iloc[::-1].loc['2017-01-03']
        expected2 = expected.iloc[::-1]
        tm.assert_frame_equal(result2, expected2)

    def test_slice_year(self):
        dti = date_range(freq='B', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        result = s['2005']
        expected = s[s.index.year == 2005]
        tm.assert_series_equal(result, expected)
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        result = df.loc['2005']
        expected = df[df.index.year == 2005]
        tm.assert_frame_equal(result, expected)

    @pytest.mark.parametrize('partial_dtime', ['2019', '2019Q4', 'Dec 2019',
        '2019-12-31', '2019-12-31 23', '2019-12-31 23:59'])
    def test_slice_end_of_period_resolution(self, partial_dtime):
        dti = date_range('2019-12-31 23:59:55.999999999', periods=10, freq='s')
        ser = Series(range(10), index=dti)
        result = ser[partial_dtime]
        expected = ser.iloc[:5]
        tm.assert_series_equal(result, expected)

    def test_slice_quarter(self):
        dti = date_range(freq='D', start=datetime(2000, 6, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s['2001Q1']) == 90
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        assert len(df.loc['1Q01']) == 90

    def test_slice_month(self):
        dti = date_range(freq='D', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s['2005-11']) == 30
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        assert len(df.loc['2005-11']) == 30
        tm.assert_series_equal(s['2005-11'], s['11-2005'])

    def test_partial_slice(self):
        rng = date_range(freq='D', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-05':'2006-02']
        expected = s['20050501':'20060228']
        tm.assert_series_equal(result, expected)
        result = s['2005-05':]
        expected = s['20050501':]
        tm.assert_series_equal(result, expected)
        result = s[:'2006-02']
        expected = s[:'20060228']
        tm.assert_series_equal(result, expected)
        result = s['2005-1-1']
        assert result == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31'$"):
            s['2004-12-31']

    def test_partial_slice_daily(self):
        rng = date_range(freq='H', start=datetime(2005, 1, 31), periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-31']
        tm.assert_series_equal(result, s.iloc[:24])
        with pytest.raises(KeyError, match="^'2004-12-31 00'$"):
            s['2004-12-31 00']

    def test_partial_slice_hourly(self):
        rng = date_range(freq='min', start=datetime(2005, 1, 1, 20, 0, 0),
            periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-1']
        tm.assert_series_equal(result, s.iloc[:60 * 4])
        result = s['2005-1-1 20']
        tm.assert_series_equal(result, s.iloc[:60])
        assert s['2005-1-1 20:00'] == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31 00:15'$"):
            s['2004-12-31 00:15']

    def test_partial_slice_minutely(self):
        rng = date_range(freq='s', start=datetime(2005, 1, 1, 23, 59, 0),
            periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-1 23:59']
        tm.assert_series_equal(result, s.iloc[:60])
        result = s['2005-1-1']
        tm.assert_series_equal(result, s.iloc[:60])
        assert s[Timestamp('2005-1-1 23:59:00')] == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31 00:00:00'$"):
            s['2004-12-31 00:00:00']
    <mask token>

    def test_partial_slicing_dataframe(self):
        formats = ['%Y', '%Y-%m', '%Y-%m-%d', '%Y-%m-%d %H',
            '%Y-%m-%d %H:%M', '%Y-%m-%d %H:%M:%S']
        resolutions = ['year', 'month', 'day', 'hour', 'minute', 'second']
        for rnum, resolution in enumerate(resolutions[2:], 2):
            unit = Timedelta('1 ' + resolution)
            middate = datetime(2012, 1, 1, 0, 0, 0)
            index = DatetimeIndex([middate - unit, middate, middate + unit])
            values = [1, 2, 3]
            df = DataFrame({'a': values}, index, dtype=np.int64)
            assert df.index.resolution == resolution
            for timestamp, expected in zip(index, values):
                ts_string = timestamp.strftime(formats[rnum])
                result = df['a'][ts_string]
                assert isinstance(result, np.int64)
                assert result == expected
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]
            for fmt in formats[:rnum]:
                for element, theslice in [[0, slice(None, 1)], [1, slice(1,
                    None)]]:
                    ts_string = index[element].strftime(fmt)
                    result = df['a'][ts_string]
                    expected = df['a'][theslice]
                    tm.assert_series_equal(result, expected)
                    with pytest.raises(KeyError, match=ts_string):
                        df[ts_string]
            for fmt in formats[rnum + 1:]:
                ts_string = index[1].strftime(fmt)
                result = df['a'][ts_string]
                assert isinstance(result, np.int64)
                assert result == 2
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]
            for fmt, res in list(zip(formats, resolutions))[rnum + 1:]:
                ts = index[1] + Timedelta('1 ' + res)
                ts_string = ts.strftime(fmt)
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df['a'][ts_string]
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]
    <mask token>
    <mask token>
    <mask token>
    <mask token>

    @pytest.mark.parametrize('start', ['2018-12-02 21:50:00+00:00',
        Timestamp('2018-12-02 21:50:00+00:00'), Timestamp(
        '2018-12-02 21:50:00+00:00').to_pydatetime()])
    @pytest.mark.parametrize('end', ['2018-12-02 21:52:00+00:00', Timestamp
        ('2018-12-02 21:52:00+00:00'), Timestamp(
        '2018-12-02 21:52:00+00:00').to_pydatetime()])
    def test_getitem_with_datestring_with_UTC_offset(self, start, end):
        idx = date_range(start='2018-12-02 14:50:00-07:00', end=
            '2018-12-02 14:50:00-07:00', freq='1min')
        df = DataFrame(1, index=idx, columns=['A'])
        result = df[start:end]
        expected = df.iloc[0:3, :]
        tm.assert_frame_equal(result, expected)
        start = str(start)
        end = str(end)
        with pytest.raises(ValueError, match='Both dates must'):
            df[start:end[:-4] + '1:00']
        with pytest.raises(ValueError, match='The index must be timezone'):
            df = df.tz_localize(None)
            df[start:end]
    <mask token>

<mask token>


class TestSlicing:

    def test_string_index_series_name_converted(self):
        df = DataFrame(np.random.default_rng(2).standard_normal((10, 4)),
            index=date_range('1/1/2000', periods=10))
        result = df.loc['1/3/2000']
        assert result.name == df.index[2]
        result = df.T['1/3/2000']
        assert result.name == df.index[2]

    def test_stringified_slice_with_tz(self):
        start = '2013-01-07'
        idx = date_range(start=start, freq='1d', periods=10, tz='US/Eastern')
        df = DataFrame(np.arange(10), index=idx)
        df['2013-01-14 23:44:34.437768-05:00':]

    def test_return_type_doesnt_depend_on_monotonicity(self):
        dti = date_range(start='2015-5-13 23:59:00', freq='min', periods=3)
        ser = Series(range(3), index=dti)
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])
        key = '2015-5-14 00'
        result = ser.loc[key]
        expected = ser.iloc[1:]
        tm.assert_series_equal(result, expected)
        result = ser.iloc[::-1].loc[key]
        expected = ser.iloc[::-1][:-1]
        tm.assert_series_equal(result, expected)
        result2 = ser2.loc[key]
        expected2 = ser2.iloc[::2]
        tm.assert_series_equal(result2, expected2)

    def test_return_type_doesnt_depend_on_monotonicity_higher_reso(self):
        dti = date_range(start='2015-5-13 23:59:00', freq='min', periods=3)
        ser = Series(range(3), index=dti)
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])
        key = '2015-5-14 00:00:00'
        result = ser.loc[key]
        assert result == 1
        result = ser.iloc[::-1].loc[key]
        assert result == 1
        result2 = ser2.loc[key]
        assert result2 == 0

    def test_monotone_DTI_indexing_bug(self):
        df = DataFrame(list(range(5)))
        date_list = ['2018-01-02', '2017-02-10', '2016-03-10', '2015-03-15',
            '2014-03-16']
        date_index = DatetimeIndex(date_list)
        df['date'] = date_index
        expected = DataFrame({(0): list(range(5)), 'date': date_index})
        tm.assert_frame_equal(df, expected)
        dti = date_range('20170101 01:00:00', periods=3)
        df = DataFrame({'A': [1, 2, 3]}, index=dti[::-1])
        expected = DataFrame({'A': 1}, index=dti[-1:][::-1])
        result = df.loc['2017-01-03']
        tm.assert_frame_equal(result, expected)
        result2 = df.iloc[::-1].loc['2017-01-03']
        expected2 = expected.iloc[::-1]
        tm.assert_frame_equal(result2, expected2)

    def test_slice_year(self):
        dti = date_range(freq='B', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        result = s['2005']
        expected = s[s.index.year == 2005]
        tm.assert_series_equal(result, expected)
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        result = df.loc['2005']
        expected = df[df.index.year == 2005]
        tm.assert_frame_equal(result, expected)

    @pytest.mark.parametrize('partial_dtime', ['2019', '2019Q4', 'Dec 2019',
        '2019-12-31', '2019-12-31 23', '2019-12-31 23:59'])
    def test_slice_end_of_period_resolution(self, partial_dtime):
        dti = date_range('2019-12-31 23:59:55.999999999', periods=10, freq='s')
        ser = Series(range(10), index=dti)
        result = ser[partial_dtime]
        expected = ser.iloc[:5]
        tm.assert_series_equal(result, expected)

    def test_slice_quarter(self):
        dti = date_range(freq='D', start=datetime(2000, 6, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s['2001Q1']) == 90
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        assert len(df.loc['1Q01']) == 90

    def test_slice_month(self):
        dti = date_range(freq='D', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s['2005-11']) == 30
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        assert len(df.loc['2005-11']) == 30
        tm.assert_series_equal(s['2005-11'], s['11-2005'])

    def test_partial_slice(self):
        rng = date_range(freq='D', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-05':'2006-02']
        expected = s['20050501':'20060228']
        tm.assert_series_equal(result, expected)
        result = s['2005-05':]
        expected = s['20050501':]
        tm.assert_series_equal(result, expected)
        result = s[:'2006-02']
        expected = s[:'20060228']
        tm.assert_series_equal(result, expected)
        result = s['2005-1-1']
        assert result == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31'$"):
            s['2004-12-31']

    def test_partial_slice_daily(self):
        rng = date_range(freq='H', start=datetime(2005, 1, 31), periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-31']
        tm.assert_series_equal(result, s.iloc[:24])
        with pytest.raises(KeyError, match="^'2004-12-31 00'$"):
            s['2004-12-31 00']

    def test_partial_slice_hourly(self):
        rng = date_range(freq='min', start=datetime(2005, 1, 1, 20, 0, 0),
            periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-1']
        tm.assert_series_equal(result, s.iloc[:60 * 4])
        result = s['2005-1-1 20']
        tm.assert_series_equal(result, s.iloc[:60])
        assert s['2005-1-1 20:00'] == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31 00:15'$"):
            s['2004-12-31 00:15']

    def test_partial_slice_minutely(self):
        rng = date_range(freq='s', start=datetime(2005, 1, 1, 23, 59, 0),
            periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-1 23:59']
        tm.assert_series_equal(result, s.iloc[:60])
        result = s['2005-1-1']
        tm.assert_series_equal(result, s.iloc[:60])
        assert s[Timestamp('2005-1-1 23:59:00')] == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31 00:00:00'$"):
            s['2004-12-31 00:00:00']

    def test_partial_slice_second_precision(self):
        rng = date_range(start=datetime(2005, 1, 1, 0, 0, 59, microsecond=
            999990), periods=20, freq='US')
        s = Series(np.arange(20), rng)
        tm.assert_series_equal(s['2005-1-1 00:00'], s.iloc[:10])
        tm.assert_series_equal(s['2005-1-1 00:00:59'], s.iloc[:10])
        tm.assert_series_equal(s['2005-1-1 00:01'], s.iloc[10:])
        tm.assert_series_equal(s['2005-1-1 00:01:00'], s.iloc[10:])
        assert s[Timestamp('2005-1-1 00:00:59.999990')] == s.iloc[0]
        with pytest.raises(KeyError, match='2005-1-1 00:00:00'):
            s['2005-1-1 00:00:00']

    def test_partial_slicing_dataframe(self):
        formats = ['%Y', '%Y-%m', '%Y-%m-%d', '%Y-%m-%d %H',
            '%Y-%m-%d %H:%M', '%Y-%m-%d %H:%M:%S']
        resolutions = ['year', 'month', 'day', 'hour', 'minute', 'second']
        for rnum, resolution in enumerate(resolutions[2:], 2):
            unit = Timedelta('1 ' + resolution)
            middate = datetime(2012, 1, 1, 0, 0, 0)
            index = DatetimeIndex([middate - unit, middate, middate + unit])
            values = [1, 2, 3]
            df = DataFrame({'a': values}, index, dtype=np.int64)
            assert df.index.resolution == resolution
            for timestamp, expected in zip(index, values):
                ts_string = timestamp.strftime(formats[rnum])
                result = df['a'][ts_string]
                assert isinstance(result, np.int64)
                assert result == expected
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]
            for fmt in formats[:rnum]:
                for element, theslice in [[0, slice(None, 1)], [1, slice(1,
                    None)]]:
                    ts_string = index[element].strftime(fmt)
                    result = df['a'][ts_string]
                    expected = df['a'][theslice]
                    tm.assert_series_equal(result, expected)
                    with pytest.raises(KeyError, match=ts_string):
                        df[ts_string]
            for fmt in formats[rnum + 1:]:
                ts_string = index[1].strftime(fmt)
                result = df['a'][ts_string]
                assert isinstance(result, np.int64)
                assert result == 2
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]
            for fmt, res in list(zip(formats, resolutions))[rnum + 1:]:
                ts = index[1] + Timedelta('1 ' + res)
                ts_string = ts.strftime(fmt)
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df['a'][ts_string]
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]

    def test_partial_slicing_with_multiindex(self):
        df = DataFrame({'ACCOUNT': ['ACCT1', 'ACCT1', 'ACCT1', 'ACCT2'],
            'TICKER': ['ABC', 'MNP', 'XYZ', 'XYZ'], 'val': [1, 2, 3, 4]},
            index=date_range('2013-06-19 09:30:00', periods=4, freq='5min'))
        df_multi = df.set_index(['ACCOUNT', 'TICKER'], append=True)
        expected = DataFrame([[1]], index=Index(['ABC'], name='TICKER'),
            columns=['val'])
        result = df_multi.loc['2013-06-19 09:30:00', 'ACCT1']
        tm.assert_frame_equal(result, expected)
        expected = df_multi.loc[Timestamp('2013-06-19 09:30:00', tz=None),
            'ACCT1', 'ABC']
        result = df_multi.loc['2013-06-19 09:30:00', 'ACCT1', 'ABC']
        tm.assert_series_equal(result, expected)
        result = df_multi.loc['2013-06-19', 'ACCT1', 'ABC']
        expected = df_multi.iloc[:1].droplevel([1, 2])
        tm.assert_frame_equal(result, expected)

    def test_partial_slicing_with_multiindex_series(self):
        ser = DataFrame(np.random.default_rng(2).random((1000, 1000)),
            index=date_range('2000-1-1', periods=1000)).stack(future_stack=True
            )
        s2 = ser[:-1].copy()
        expected = s2['2000-1-4']
        result = s2[Timestamp('2000-1-4')]
        tm.assert_series_equal(result, expected)
        result = ser[Timestamp('2000-1-4')]
        expected = ser['2000-1-4']
        tm.assert_series_equal(result, expected)
        df2 = DataFrame(ser)
        expected = df2.xs('2000-1-4')
        result = df2.loc[Timestamp('2000-1-4')]
        tm.assert_frame_equal(result, expected)
    <mask token>
    <mask token>

    @pytest.mark.parametrize('start', ['2018-12-02 21:50:00+00:00',
        Timestamp('2018-12-02 21:50:00+00:00'), Timestamp(
        '2018-12-02 21:50:00+00:00').to_pydatetime()])
    @pytest.mark.parametrize('end', ['2018-12-02 21:52:00+00:00', Timestamp
        ('2018-12-02 21:52:00+00:00'), Timestamp(
        '2018-12-02 21:52:00+00:00').to_pydatetime()])
    def test_getitem_with_datestring_with_UTC_offset(self, start, end):
        idx = date_range(start='2018-12-02 14:50:00-07:00', end=
            '2018-12-02 14:50:00-07:00', freq='1min')
        df = DataFrame(1, index=idx, columns=['A'])
        result = df[start:end]
        expected = df.iloc[0:3, :]
        tm.assert_frame_equal(result, expected)
        start = str(start)
        end = str(end)
        with pytest.raises(ValueError, match='Both dates must'):
            df[start:end[:-4] + '1:00']
        with pytest.raises(ValueError, match='The index must be timezone'):
            df = df.tz_localize(None)
            df[start:end]

    def test_slice_reduce_to_series(self):
        df = DataFrame({'A': range(24)}, index=date_range('2000', periods=
            24, freq='M'))
        expected = Series(range(12), index=date_range('2000', periods=12,
            freq='M'), name='A')
        result = df.loc['2000', 'A']
        tm.assert_series_equal(result, expected)

<mask token>


class TestSlicing:

    def test_string_index_series_name_converted(self):
        df = DataFrame(np.random.default_rng(2).standard_normal((10, 4)),
            index=date_range('1/1/2000', periods=10))
        result = df.loc['1/3/2000']
        assert result.name == df.index[2]
        result = df.T['1/3/2000']
        assert result.name == df.index[2]

    def test_stringified_slice_with_tz(self):
        start = '2013-01-07'
        idx = date_range(start=start, freq='1d', periods=10, tz='US/Eastern')
        df = DataFrame(np.arange(10), index=idx)
        df['2013-01-14 23:44:34.437768-05:00':]

    def test_return_type_doesnt_depend_on_monotonicity(self):
        dti = date_range(start='2015-5-13 23:59:00', freq='min', periods=3)
        ser = Series(range(3), index=dti)
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])
        key = '2015-5-14 00'
        result = ser.loc[key]
        expected = ser.iloc[1:]
        tm.assert_series_equal(result, expected)
        result = ser.iloc[::-1].loc[key]
        expected = ser.iloc[::-1][:-1]
        tm.assert_series_equal(result, expected)
        result2 = ser2.loc[key]
        expected2 = ser2.iloc[::2]
        tm.assert_series_equal(result2, expected2)

    def test_return_type_doesnt_depend_on_monotonicity_higher_reso(self):
        dti = date_range(start='2015-5-13 23:59:00', freq='min', periods=3)
        ser = Series(range(3), index=dti)
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])
        key = '2015-5-14 00:00:00'
        result = ser.loc[key]
        assert result == 1
        result = ser.iloc[::-1].loc[key]
        assert result == 1
        result2 = ser2.loc[key]
        assert result2 == 0

    def test_monotone_DTI_indexing_bug(self):
        df = DataFrame(list(range(5)))
        date_list = ['2018-01-02', '2017-02-10', '2016-03-10', '2015-03-15',
            '2014-03-16']
        date_index = DatetimeIndex(date_list)
        df['date'] = date_index
        expected = DataFrame({(0): list(range(5)), 'date': date_index})
        tm.assert_frame_equal(df, expected)
        dti = date_range('20170101 01:00:00', periods=3)
        df = DataFrame({'A': [1, 2, 3]}, index=dti[::-1])
        expected = DataFrame({'A': 1}, index=dti[-1:][::-1])
        result = df.loc['2017-01-03']
        tm.assert_frame_equal(result, expected)
        result2 = df.iloc[::-1].loc['2017-01-03']
        expected2 = expected.iloc[::-1]
        tm.assert_frame_equal(result2, expected2)

    def test_slice_year(self):
        dti = date_range(freq='B', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        result = s['2005']
        expected = s[s.index.year == 2005]
        tm.assert_series_equal(result, expected)
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        result = df.loc['2005']
        expected = df[df.index.year == 2005]
        tm.assert_frame_equal(result, expected)

    @pytest.mark.parametrize('partial_dtime', ['2019', '2019Q4', 'Dec 2019',
        '2019-12-31', '2019-12-31 23', '2019-12-31 23:59'])
    def test_slice_end_of_period_resolution(self, partial_dtime):
        dti = date_range('2019-12-31 23:59:55.999999999', periods=10, freq='s')
        ser = Series(range(10), index=dti)
        result = ser[partial_dtime]
        expected = ser.iloc[:5]
        tm.assert_series_equal(result, expected)

    def test_slice_quarter(self):
        dti = date_range(freq='D', start=datetime(2000, 6, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s['2001Q1']) == 90
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        assert len(df.loc['1Q01']) == 90

    def test_slice_month(self):
        dti = date_range(freq='D', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s['2005-11']) == 30
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        assert len(df.loc['2005-11']) == 30
        tm.assert_series_equal(s['2005-11'], s['11-2005'])

    def test_partial_slice(self):
        rng = date_range(freq='D', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-05':'2006-02']
        expected = s['20050501':'20060228']
        tm.assert_series_equal(result, expected)
        result = s['2005-05':]
        expected = s['20050501':]
        tm.assert_series_equal(result, expected)
        result = s[:'2006-02']
        expected = s[:'20060228']
        tm.assert_series_equal(result, expected)
        result = s['2005-1-1']
        assert result == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31'$"):
            s['2004-12-31']

    def test_partial_slice_daily(self):
        rng = date_range(freq='H', start=datetime(2005, 1, 31), periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-31']
        tm.assert_series_equal(result, s.iloc[:24])
        with pytest.raises(KeyError, match="^'2004-12-31 00'$"):
            s['2004-12-31 00']

    def test_partial_slice_hourly(self):
        rng = date_range(freq='min', start=datetime(2005, 1, 1, 20, 0, 0),
            periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-1']
        tm.assert_series_equal(result, s.iloc[:60 * 4])
        result = s['2005-1-1 20']
        tm.assert_series_equal(result, s.iloc[:60])
        assert s['2005-1-1 20:00'] == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31 00:15'$"):
            s['2004-12-31 00:15']

    def test_partial_slice_minutely(self):
        rng = date_range(freq='s', start=datetime(2005, 1, 1, 23, 59, 0),
            periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-1 23:59']
        tm.assert_series_equal(result, s.iloc[:60])
        result = s['2005-1-1']
        tm.assert_series_equal(result, s.iloc[:60])
        assert s[Timestamp('2005-1-1 23:59:00')] == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31 00:00:00'$"):
            s['2004-12-31 00:00:00']

    def test_partial_slice_second_precision(self):
        rng = date_range(start=datetime(2005, 1, 1, 0, 0, 59, microsecond=
            999990), periods=20, freq='US')
        s = Series(np.arange(20), rng)
        tm.assert_series_equal(s['2005-1-1 00:00'], s.iloc[:10])
        tm.assert_series_equal(s['2005-1-1 00:00:59'], s.iloc[:10])
        tm.assert_series_equal(s['2005-1-1 00:01'], s.iloc[10:])
        tm.assert_series_equal(s['2005-1-1 00:01:00'], s.iloc[10:])
        assert s[Timestamp('2005-1-1 00:00:59.999990')] == s.iloc[0]
        with pytest.raises(KeyError, match='2005-1-1 00:00:00'):
            s['2005-1-1 00:00:00']

    def test_partial_slicing_dataframe(self):
        formats = ['%Y', '%Y-%m', '%Y-%m-%d', '%Y-%m-%d %H',
            '%Y-%m-%d %H:%M', '%Y-%m-%d %H:%M:%S']
        resolutions = ['year', 'month', 'day', 'hour', 'minute', 'second']
        for rnum, resolution in enumerate(resolutions[2:], 2):
            unit = Timedelta('1 ' + resolution)
            middate = datetime(2012, 1, 1, 0, 0, 0)
            index = DatetimeIndex([middate - unit, middate, middate + unit])
            values = [1, 2, 3]
            df = DataFrame({'a': values}, index, dtype=np.int64)
            assert df.index.resolution == resolution
            for timestamp, expected in zip(index, values):
                ts_string = timestamp.strftime(formats[rnum])
                result = df['a'][ts_string]
                assert isinstance(result, np.int64)
                assert result == expected
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]
            for fmt in formats[:rnum]:
                for element, theslice in [[0, slice(None, 1)], [1, slice(1,
                    None)]]:
                    ts_string = index[element].strftime(fmt)
                    result = df['a'][ts_string]
                    expected = df['a'][theslice]
                    tm.assert_series_equal(result, expected)
                    with pytest.raises(KeyError, match=ts_string):
                        df[ts_string]
            for fmt in formats[rnum + 1:]:
                ts_string = index[1].strftime(fmt)
                result = df['a'][ts_string]
                assert isinstance(result, np.int64)
                assert result == 2
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]
            for fmt, res in list(zip(formats, resolutions))[rnum + 1:]:
                ts = index[1] + Timedelta('1 ' + res)
                ts_string = ts.strftime(fmt)
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df['a'][ts_string]
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]

    def test_partial_slicing_with_multiindex(self):
        df = DataFrame({'ACCOUNT': ['ACCT1', 'ACCT1', 'ACCT1', 'ACCT2'],
            'TICKER': ['ABC', 'MNP', 'XYZ', 'XYZ'], 'val': [1, 2, 3, 4]},
            index=date_range('2013-06-19 09:30:00', periods=4, freq='5min'))
        df_multi = df.set_index(['ACCOUNT', 'TICKER'], append=True)
        expected = DataFrame([[1]], index=Index(['ABC'], name='TICKER'),
            columns=['val'])
        result = df_multi.loc['2013-06-19 09:30:00', 'ACCT1']
        tm.assert_frame_equal(result, expected)
        expected = df_multi.loc[Timestamp('2013-06-19 09:30:00', tz=None),
            'ACCT1', 'ABC']
        result = df_multi.loc['2013-06-19 09:30:00', 'ACCT1', 'ABC']
        tm.assert_series_equal(result, expected)
        result = df_multi.loc['2013-06-19', 'ACCT1', 'ABC']
        expected = df_multi.iloc[:1].droplevel([1, 2])
        tm.assert_frame_equal(result, expected)

    def test_partial_slicing_with_multiindex_series(self):
        ser = DataFrame(np.random.default_rng(2).random((1000, 1000)),
            index=date_range('2000-1-1', periods=1000)).stack(future_stack=True
            )
        s2 = ser[:-1].copy()
        expected = s2['2000-1-4']
        result = s2[Timestamp('2000-1-4')]
        tm.assert_series_equal(result, expected)
        result = ser[Timestamp('2000-1-4')]
        expected = ser['2000-1-4']
        tm.assert_series_equal(result, expected)
        df2 = DataFrame(ser)
        expected = df2.xs('2000-1-4')
        result = df2.loc[Timestamp('2000-1-4')]
        tm.assert_frame_equal(result, expected)

    def test_partial_slice_requires_monotonicity(self):
        ser = Series(np.arange(10), date_range('2014-01-01', periods=10))
        nonmonotonic = ser.iloc[[3, 5, 4]]
        timestamp = Timestamp('2014-01-10')
        with pytest.raises(KeyError, match=
            'Value based partial slicing on non-monotonic'):
            nonmonotonic['2014-01-10':]
        with pytest.raises(KeyError, match=
            "Timestamp\\('2014-01-10 00:00:00'\\)"):
            nonmonotonic[timestamp:]
        with pytest.raises(KeyError, match=
            'Value based partial slicing on non-monotonic'):
            nonmonotonic.loc['2014-01-10':]
        with pytest.raises(KeyError, match=
            "Timestamp\\('2014-01-10 00:00:00'\\)"):
            nonmonotonic.loc[timestamp:]

    def test_loc_datetime_length_one(self):
        df = DataFrame(columns=['1'], index=date_range(
            '2016-10-01T00:00:00', '2016-10-01T23:59:59'))
        result = df.loc[datetime(2016, 10, 1):]
        tm.assert_frame_equal(result, df)
        result = df.loc['2016-10-01T00:00:00':]
        tm.assert_frame_equal(result, df)

    @pytest.mark.parametrize('start', ['2018-12-02 21:50:00+00:00',
        Timestamp('2018-12-02 21:50:00+00:00'), Timestamp(
        '2018-12-02 21:50:00+00:00').to_pydatetime()])
    @pytest.mark.parametrize('end', ['2018-12-02 21:52:00+00:00', Timestamp
        ('2018-12-02 21:52:00+00:00'), Timestamp(
        '2018-12-02 21:52:00+00:00').to_pydatetime()])
    def test_getitem_with_datestring_with_UTC_offset(self, start, end):
        idx = date_range(start='2018-12-02 14:50:00-07:00', end=
            '2018-12-02 14:50:00-07:00', freq='1min')
        df = DataFrame(1, index=idx, columns=['A'])
        result = df[start:end]
        expected = df.iloc[0:3, :]
        tm.assert_frame_equal(result, expected)
        start = str(start)
        end = str(end)
        with pytest.raises(ValueError, match='Both dates must'):
            df[start:end[:-4] + '1:00']
        with pytest.raises(ValueError, match='The index must be timezone'):
            df = df.tz_localize(None)
            df[start:end]

    def test_slice_reduce_to_series(self):
        df = DataFrame({'A': range(24)}, index=date_range('2000', periods=
            24, freq='M'))
        expected = Series(range(12), index=date_range('2000', periods=12,
            freq='M'), name='A')
        result = df.loc['2000', 'A']
        tm.assert_series_equal(result, expected)

<mask token>
from datetime import datetime
import numpy as np
import pytest
from pandas import DataFrame, DatetimeIndex, Index, Series, Timedelta, Timestamp, date_range
import pandas._testing as tm


class TestSlicing:

    def test_string_index_series_name_converted(self):
        df = DataFrame(np.random.default_rng(2).standard_normal((10, 4)),
            index=date_range('1/1/2000', periods=10))
        result = df.loc['1/3/2000']
        assert result.name == df.index[2]
        result = df.T['1/3/2000']
        assert result.name == df.index[2]

    def test_stringified_slice_with_tz(self):
        start = '2013-01-07'
        idx = date_range(start=start, freq='1d', periods=10, tz='US/Eastern')
        df = DataFrame(np.arange(10), index=idx)
        df['2013-01-14 23:44:34.437768-05:00':]

    def test_return_type_doesnt_depend_on_monotonicity(self):
        dti = date_range(start='2015-5-13 23:59:00', freq='min', periods=3)
        ser = Series(range(3), index=dti)
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])
        key = '2015-5-14 00'
        result = ser.loc[key]
        expected = ser.iloc[1:]
        tm.assert_series_equal(result, expected)
        result = ser.iloc[::-1].loc[key]
        expected = ser.iloc[::-1][:-1]
        tm.assert_series_equal(result, expected)
        result2 = ser2.loc[key]
        expected2 = ser2.iloc[::2]
        tm.assert_series_equal(result2, expected2)

    def test_return_type_doesnt_depend_on_monotonicity_higher_reso(self):
        dti = date_range(start='2015-5-13 23:59:00', freq='min', periods=3)
        ser = Series(range(3), index=dti)
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])
        key = '2015-5-14 00:00:00'
        result = ser.loc[key]
        assert result == 1
        result = ser.iloc[::-1].loc[key]
        assert result == 1
        result2 = ser2.loc[key]
        assert result2 == 0

    def test_monotone_DTI_indexing_bug(self):
        df = DataFrame(list(range(5)))
        date_list = ['2018-01-02', '2017-02-10', '2016-03-10', '2015-03-15',
            '2014-03-16']
        date_index = DatetimeIndex(date_list)
        df['date'] = date_index
        expected = DataFrame({(0): list(range(5)), 'date': date_index})
        tm.assert_frame_equal(df, expected)
        dti = date_range('20170101 01:00:00', periods=3)
        df = DataFrame({'A': [1, 2, 3]}, index=dti[::-1])
        expected = DataFrame({'A': 1}, index=dti[-1:][::-1])
        result = df.loc['2017-01-03']
        tm.assert_frame_equal(result, expected)
        result2 = df.iloc[::-1].loc['2017-01-03']
        expected2 = expected.iloc[::-1]
        tm.assert_frame_equal(result2, expected2)

    def test_slice_year(self):
        dti = date_range(freq='B', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        result = s['2005']
        expected = s[s.index.year == 2005]
        tm.assert_series_equal(result, expected)
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        result = df.loc['2005']
        expected = df[df.index.year == 2005]
        tm.assert_frame_equal(result, expected)

    @pytest.mark.parametrize('partial_dtime', ['2019', '2019Q4', 'Dec 2019',
        '2019-12-31', '2019-12-31 23', '2019-12-31 23:59'])
    def test_slice_end_of_period_resolution(self, partial_dtime):
        dti = date_range('2019-12-31 23:59:55.999999999', periods=10, freq='s')
        ser = Series(range(10), index=dti)
        result = ser[partial_dtime]
        expected = ser.iloc[:5]
        tm.assert_series_equal(result, expected)

    def test_slice_quarter(self):
        dti = date_range(freq='D', start=datetime(2000, 6, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s['2001Q1']) == 90
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        assert len(df.loc['1Q01']) == 90

    def test_slice_month(self):
        dti = date_range(freq='D', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s['2005-11']) == 30
        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)),
            index=dti)
        assert len(df.loc['2005-11']) == 30
        tm.assert_series_equal(s['2005-11'], s['11-2005'])

    def test_partial_slice(self):
        rng = date_range(freq='D', start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-05':'2006-02']
        expected = s['20050501':'20060228']
        tm.assert_series_equal(result, expected)
        result = s['2005-05':]
        expected = s['20050501':]
        tm.assert_series_equal(result, expected)
        result = s[:'2006-02']
        expected = s[:'20060228']
        tm.assert_series_equal(result, expected)
        result = s['2005-1-1']
        assert result == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31'$"):
            s['2004-12-31']

    def test_partial_slice_daily(self):
        rng = date_range(freq='H', start=datetime(2005, 1, 31), periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-31']
        tm.assert_series_equal(result, s.iloc[:24])
        with pytest.raises(KeyError, match="^'2004-12-31 00'$"):
            s['2004-12-31 00']

    def test_partial_slice_hourly(self):
        rng = date_range(freq='min', start=datetime(2005, 1, 1, 20, 0, 0),
            periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-1']
        tm.assert_series_equal(result, s.iloc[:60 * 4])
        result = s['2005-1-1 20']
        tm.assert_series_equal(result, s.iloc[:60])
        assert s['2005-1-1 20:00'] == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31 00:15'$"):
            s['2004-12-31 00:15']

    def test_partial_slice_minutely(self):
        rng = date_range(freq='s', start=datetime(2005, 1, 1, 23, 59, 0),
            periods=500)
        s = Series(np.arange(len(rng)), index=rng)
        result = s['2005-1-1 23:59']
        tm.assert_series_equal(result, s.iloc[:60])
        result = s['2005-1-1']
        tm.assert_series_equal(result, s.iloc[:60])
        assert s[Timestamp('2005-1-1 23:59:00')] == s.iloc[0]
        with pytest.raises(KeyError, match="^'2004-12-31 00:00:00'$"):
            s['2004-12-31 00:00:00']

    def test_partial_slice_second_precision(self):
        rng = date_range(start=datetime(2005, 1, 1, 0, 0, 59, microsecond=
            999990), periods=20, freq='US')
        s = Series(np.arange(20), rng)
        tm.assert_series_equal(s['2005-1-1 00:00'], s.iloc[:10])
        tm.assert_series_equal(s['2005-1-1 00:00:59'], s.iloc[:10])
        tm.assert_series_equal(s['2005-1-1 00:01'], s.iloc[10:])
        tm.assert_series_equal(s['2005-1-1 00:01:00'], s.iloc[10:])
        assert s[Timestamp('2005-1-1 00:00:59.999990')] == s.iloc[0]
        with pytest.raises(KeyError, match='2005-1-1 00:00:00'):
            s['2005-1-1 00:00:00']

    def test_partial_slicing_dataframe(self):
        formats = ['%Y', '%Y-%m', '%Y-%m-%d', '%Y-%m-%d %H',
            '%Y-%m-%d %H:%M', '%Y-%m-%d %H:%M:%S']
        resolutions = ['year', 'month', 'day', 'hour', 'minute', 'second']
        for rnum, resolution in enumerate(resolutions[2:], 2):
            unit = Timedelta('1 ' + resolution)
            middate = datetime(2012, 1, 1, 0, 0, 0)
            index = DatetimeIndex([middate - unit, middate, middate + unit])
            values = [1, 2, 3]
            df = DataFrame({'a': values}, index, dtype=np.int64)
            assert df.index.resolution == resolution
            for timestamp, expected in zip(index, values):
                ts_string = timestamp.strftime(formats[rnum])
                result = df['a'][ts_string]
                assert isinstance(result, np.int64)
                assert result == expected
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]
            for fmt in formats[:rnum]:
                for element, theslice in [[0, slice(None, 1)], [1, slice(1,
                    None)]]:
                    ts_string = index[element].strftime(fmt)
                    result = df['a'][ts_string]
                    expected = df['a'][theslice]
                    tm.assert_series_equal(result, expected)
                    with pytest.raises(KeyError, match=ts_string):
                        df[ts_string]
            for fmt in formats[rnum + 1:]:
                ts_string = index[1].strftime(fmt)
                result = df['a'][ts_string]
                assert isinstance(result, np.int64)
                assert result == 2
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]
            for fmt, res in list(zip(formats, resolutions))[rnum + 1:]:
                ts = index[1] + Timedelta('1 ' + res)
                ts_string = ts.strftime(fmt)
                msg = f"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df['a'][ts_string]
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]

    def test_partial_slicing_with_multiindex(self):
        df = DataFrame({'ACCOUNT': ['ACCT1', 'ACCT1', 'ACCT1', 'ACCT2'],
            'TICKER': ['ABC', 'MNP', 'XYZ', 'XYZ'], 'val': [1, 2, 3, 4]},
            index=date_range('2013-06-19 09:30:00', periods=4, freq='5min'))
        df_multi = df.set_index(['ACCOUNT', 'TICKER'], append=True)
        expected = DataFrame([[1]], index=Index(['ABC'], name='TICKER'),
            columns=['val'])
        result = df_multi.loc['2013-06-19 09:30:00', 'ACCT1']
        tm.assert_frame_equal(result, expected)
        expected = df_multi.loc[Timestamp('2013-06-19 09:30:00', tz=None),
            'ACCT1', 'ABC']
        result = df_multi.loc['2013-06-19 09:30:00', 'ACCT1', 'ABC']
        tm.assert_series_equal(result, expected)
        result = df_multi.loc['2013-06-19', 'ACCT1', 'ABC']
        expected = df_multi.iloc[:1].droplevel([1, 2])
        tm.assert_frame_equal(result, expected)

    def test_partial_slicing_with_multiindex_series(self):
        ser = DataFrame(np.random.default_rng(2).random((1000, 1000)),
            index=date_range('2000-1-1', periods=1000)).stack(future_stack=True
            )
        s2 = ser[:-1].copy()
        expected = s2['2000-1-4']
        result = s2[Timestamp('2000-1-4')]
        tm.assert_series_equal(result, expected)
        result = ser[Timestamp('2000-1-4')]
        expected = ser['2000-1-4']
        tm.assert_series_equal(result, expected)
        df2 = DataFrame(ser)
        expected = df2.xs('2000-1-4')
        result = df2.loc[Timestamp('2000-1-4')]
        tm.assert_frame_equal(result, expected)

    def test_partial_slice_requires_monotonicity(self):
        ser = Series(np.arange(10), date_range('2014-01-01', periods=10))
        nonmonotonic = ser.iloc[[3, 5, 4]]
        timestamp = Timestamp('2014-01-10')
        with pytest.raises(KeyError, match=
            'Value based partial slicing on non-monotonic'):
            nonmonotonic['2014-01-10':]
        with pytest.raises(KeyError, match=
            "Timestamp\\('2014-01-10 00:00:00'\\)"):
            nonmonotonic[timestamp:]
        with pytest.raises(KeyError, match=
            'Value based partial slicing on non-monotonic'):
            nonmonotonic.loc['2014-01-10':]
        with pytest.raises(KeyError, match=
            "Timestamp\\('2014-01-10 00:00:00'\\)"):
            nonmonotonic.loc[timestamp:]

    def test_loc_datetime_length_one(self):
        df = DataFrame(columns=['1'], index=date_range(
            '2016-10-01T00:00:00', '2016-10-01T23:59:59'))
        result = df.loc[datetime(2016, 10, 1):]
        tm.assert_frame_equal(result, df)
        result = df.loc['2016-10-01T00:00:00':]
        tm.assert_frame_equal(result, df)

    @pytest.mark.parametrize('start', ['2018-12-02 21:50:00+00:00',
        Timestamp('2018-12-02 21:50:00+00:00'), Timestamp(
        '2018-12-02 21:50:00+00:00').to_pydatetime()])
    @pytest.mark.parametrize('end', ['2018-12-02 21:52:00+00:00', Timestamp
        ('2018-12-02 21:52:00+00:00'), Timestamp(
        '2018-12-02 21:52:00+00:00').to_pydatetime()])
    def test_getitem_with_datestring_with_UTC_offset(self, start, end):
        idx = date_range(start='2018-12-02 14:50:00-07:00', end=
            '2018-12-02 14:50:00-07:00', freq='1min')
        df = DataFrame(1, index=idx, columns=['A'])
        result = df[start:end]
        expected = df.iloc[0:3, :]
        tm.assert_frame_equal(result, expected)
        start = str(start)
        end = str(end)
        with pytest.raises(ValueError, match='Both dates must'):
            df[start:end[:-4] + '1:00']
        with pytest.raises(ValueError, match='The index must be timezone'):
            df = df.tz_localize(None)
            df[start:end]

    def test_slice_reduce_to_series(self):
        df = DataFrame({'A': range(24)}, index=date_range('2000', periods=
            24, freq='M'))
        expected = Series(range(12), index=date_range('2000', periods=12,
            freq='M'), name='A')
        result = df.loc['2000', 'A']
        tm.assert_series_equal(result, expected)

""" test partial slicing on Series/Frame """

from datetime import datetime

import numpy as np
import pytest

from pandas import (
    DataFrame,
    DatetimeIndex,
    Index,
    Series,
    Timedelta,
    Timestamp,
    date_range,
)
import pandas._testing as tm


class TestSlicing:
    def test_string_index_series_name_converted(self):
        # GH#1644
        df = DataFrame(
            np.random.default_rng(2).standard_normal((10, 4)),
            index=date_range("1/1/2000", periods=10),
        )

        result = df.loc["1/3/2000"]
        assert result.name == df.index[2]

        result = df.T["1/3/2000"]
        assert result.name == df.index[2]

    def test_stringified_slice_with_tz(self):
        # GH#2658
        start = "2013-01-07"
        idx = date_range(start=start, freq="1d", periods=10, tz="US/Eastern")
        df = DataFrame(np.arange(10), index=idx)
        df["2013-01-14 23:44:34.437768-05:00":]  # no exception here

    def test_return_type_doesnt_depend_on_monotonicity(self):
        # GH#24892 we get Series back regardless of whether our DTI is monotonic
        dti = date_range(start="2015-5-13 23:59:00", freq="min", periods=3)
        ser = Series(range(3), index=dti)

        # non-monotonic index
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])

        # key with resolution strictly lower than "min"
        key = "2015-5-14 00"

        # monotonic increasing index
        result = ser.loc[key]
        expected = ser.iloc[1:]
        tm.assert_series_equal(result, expected)

        # monotonic decreasing index
        result = ser.iloc[::-1].loc[key]
        expected = ser.iloc[::-1][:-1]
        tm.assert_series_equal(result, expected)

        # non-monotonic index
        result2 = ser2.loc[key]
        expected2 = ser2.iloc[::2]
        tm.assert_series_equal(result2, expected2)

    def test_return_type_doesnt_depend_on_monotonicity_higher_reso(self):
        # GH#24892 we get Series back regardless of whether our DTI is monotonic
        dti = date_range(start="2015-5-13 23:59:00", freq="min", periods=3)
        ser = Series(range(3), index=dti)

        # non-monotonic index
        ser2 = Series(range(3), index=[dti[1], dti[0], dti[2]])

        # key with resolution strictly *higher) than "min"
        key = "2015-5-14 00:00:00"

        # monotonic increasing index
        result = ser.loc[key]
        assert result == 1

        # monotonic decreasing index
        result = ser.iloc[::-1].loc[key]
        assert result == 1

        # non-monotonic index
        result2 = ser2.loc[key]
        assert result2 == 0

    def test_monotone_DTI_indexing_bug(self):
        # GH 19362
        # Testing accessing the first element in a monotonic descending
        # partial string indexing.

        df = DataFrame(list(range(5)))
        date_list = [
            "2018-01-02",
            "2017-02-10",
            "2016-03-10",
            "2015-03-15",
            "2014-03-16",
        ]
        date_index = DatetimeIndex(date_list)
        df["date"] = date_index
        expected = DataFrame({0: list(range(5)), "date": date_index})
        tm.assert_frame_equal(df, expected)

        # We get a slice because df.index's resolution is hourly and we
        #  are slicing with a daily-resolution string.  If both were daily,
        #  we would get a single item back
        dti = date_range("20170101 01:00:00", periods=3)
        df = DataFrame({"A": [1, 2, 3]}, index=dti[::-1])

        expected = DataFrame({"A": 1}, index=dti[-1:][::-1])
        result = df.loc["2017-01-03"]
        tm.assert_frame_equal(result, expected)

        result2 = df.iloc[::-1].loc["2017-01-03"]
        expected2 = expected.iloc[::-1]
        tm.assert_frame_equal(result2, expected2)

    def test_slice_year(self):
        dti = date_range(freq="B", start=datetime(2005, 1, 1), periods=500)

        s = Series(np.arange(len(dti)), index=dti)
        result = s["2005"]
        expected = s[s.index.year == 2005]
        tm.assert_series_equal(result, expected)

        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)), index=dti)
        result = df.loc["2005"]
        expected = df[df.index.year == 2005]
        tm.assert_frame_equal(result, expected)

    @pytest.mark.parametrize(
        "partial_dtime",
        [
            "2019",
            "2019Q4",
            "Dec 2019",
            "2019-12-31",
            "2019-12-31 23",
            "2019-12-31 23:59",
        ],
    )
    def test_slice_end_of_period_resolution(self, partial_dtime):
        # GH#31064
        dti = date_range("2019-12-31 23:59:55.999999999", periods=10, freq="s")

        ser = Series(range(10), index=dti)
        result = ser[partial_dtime]
        expected = ser.iloc[:5]
        tm.assert_series_equal(result, expected)

    def test_slice_quarter(self):
        dti = date_range(freq="D", start=datetime(2000, 6, 1), periods=500)

        s = Series(np.arange(len(dti)), index=dti)
        assert len(s["2001Q1"]) == 90

        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)), index=dti)
        assert len(df.loc["1Q01"]) == 90

    def test_slice_month(self):
        dti = date_range(freq="D", start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(dti)), index=dti)
        assert len(s["2005-11"]) == 30

        df = DataFrame(np.random.default_rng(2).random((len(dti), 5)), index=dti)
        assert len(df.loc["2005-11"]) == 30

        tm.assert_series_equal(s["2005-11"], s["11-2005"])

    def test_partial_slice(self):
        rng = date_range(freq="D", start=datetime(2005, 1, 1), periods=500)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["2005-05":"2006-02"]
        expected = s["20050501":"20060228"]
        tm.assert_series_equal(result, expected)

        result = s["2005-05":]
        expected = s["20050501":]
        tm.assert_series_equal(result, expected)

        result = s[:"2006-02"]
        expected = s[:"20060228"]
        tm.assert_series_equal(result, expected)

        result = s["2005-1-1"]
        assert result == s.iloc[0]

        with pytest.raises(KeyError, match=r"^'2004-12-31'$"):
            s["2004-12-31"]

    def test_partial_slice_daily(self):
        rng = date_range(freq="H", start=datetime(2005, 1, 31), periods=500)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["2005-1-31"]
        tm.assert_series_equal(result, s.iloc[:24])

        with pytest.raises(KeyError, match=r"^'2004-12-31 00'$"):
            s["2004-12-31 00"]

    def test_partial_slice_hourly(self):
        rng = date_range(freq="min", start=datetime(2005, 1, 1, 20, 0, 0), periods=500)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["2005-1-1"]
        tm.assert_series_equal(result, s.iloc[: 60 * 4])

        result = s["2005-1-1 20"]
        tm.assert_series_equal(result, s.iloc[:60])

        assert s["2005-1-1 20:00"] == s.iloc[0]
        with pytest.raises(KeyError, match=r"^'2004-12-31 00:15'$"):
            s["2004-12-31 00:15"]

    def test_partial_slice_minutely(self):
        rng = date_range(freq="s", start=datetime(2005, 1, 1, 23, 59, 0), periods=500)
        s = Series(np.arange(len(rng)), index=rng)

        result = s["2005-1-1 23:59"]
        tm.assert_series_equal(result, s.iloc[:60])

        result = s["2005-1-1"]
        tm.assert_series_equal(result, s.iloc[:60])

        assert s[Timestamp("2005-1-1 23:59:00")] == s.iloc[0]
        with pytest.raises(KeyError, match=r"^'2004-12-31 00:00:00'$"):
            s["2004-12-31 00:00:00"]

    def test_partial_slice_second_precision(self):
        rng = date_range(
            start=datetime(2005, 1, 1, 0, 0, 59, microsecond=999990),
            periods=20,
            freq="US",
        )
        s = Series(np.arange(20), rng)

        tm.assert_series_equal(s["2005-1-1 00:00"], s.iloc[:10])
        tm.assert_series_equal(s["2005-1-1 00:00:59"], s.iloc[:10])

        tm.assert_series_equal(s["2005-1-1 00:01"], s.iloc[10:])
        tm.assert_series_equal(s["2005-1-1 00:01:00"], s.iloc[10:])

        assert s[Timestamp("2005-1-1 00:00:59.999990")] == s.iloc[0]
        with pytest.raises(KeyError, match="2005-1-1 00:00:00"):
            s["2005-1-1 00:00:00"]

    def test_partial_slicing_dataframe(self):
        # GH14856
        # Test various combinations of string slicing resolution vs.
        # index resolution
        # - If string resolution is less precise than index resolution,
        # string is considered a slice
        # - If string resolution is equal to or more precise than index
        # resolution, string is considered an exact match
        formats = [
            "%Y",
            "%Y-%m",
            "%Y-%m-%d",
            "%Y-%m-%d %H",
            "%Y-%m-%d %H:%M",
            "%Y-%m-%d %H:%M:%S",
        ]
        resolutions = ["year", "month", "day", "hour", "minute", "second"]
        for rnum, resolution in enumerate(resolutions[2:], 2):
            # we check only 'day', 'hour', 'minute' and 'second'
            unit = Timedelta("1 " + resolution)
            middate = datetime(2012, 1, 1, 0, 0, 0)
            index = DatetimeIndex([middate - unit, middate, middate + unit])
            values = [1, 2, 3]
            df = DataFrame({"a": values}, index, dtype=np.int64)
            assert df.index.resolution == resolution

            # Timestamp with the same resolution as index
            # Should be exact match for Series (return scalar)
            # and raise KeyError for Frame
            for timestamp, expected in zip(index, values):
                ts_string = timestamp.strftime(formats[rnum])
                # make ts_string as precise as index
                result = df["a"][ts_string]
                assert isinstance(result, np.int64)
                assert result == expected
                msg = rf"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]

            # Timestamp with resolution less precise than index
            for fmt in formats[:rnum]:
                for element, theslice in [[0, slice(None, 1)], [1, slice(1, None)]]:
                    ts_string = index[element].strftime(fmt)

                    # Series should return slice
                    result = df["a"][ts_string]
                    expected = df["a"][theslice]
                    tm.assert_series_equal(result, expected)

                    # pre-2.0 df[ts_string] was overloaded to interpret this
                    #  as slicing along index
                    with pytest.raises(KeyError, match=ts_string):
                        df[ts_string]

            # Timestamp with resolution more precise than index
            # Compatible with existing key
            # Should return scalar for Series
            # and raise KeyError for Frame
            for fmt in formats[rnum + 1 :]:
                ts_string = index[1].strftime(fmt)
                result = df["a"][ts_string]
                assert isinstance(result, np.int64)
                assert result == 2
                msg = rf"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]

            # Not compatible with existing key
            # Should raise KeyError
            for fmt, res in list(zip(formats, resolutions))[rnum + 1 :]:
                ts = index[1] + Timedelta("1 " + res)
                ts_string = ts.strftime(fmt)
                msg = rf"^'{ts_string}'$"
                with pytest.raises(KeyError, match=msg):
                    df["a"][ts_string]
                with pytest.raises(KeyError, match=msg):
                    df[ts_string]

    def test_partial_slicing_with_multiindex(self):
        # GH 4758
        # partial string indexing with a multi-index buggy
        df = DataFrame(
            {
                "ACCOUNT": ["ACCT1", "ACCT1", "ACCT1", "ACCT2"],
                "TICKER": ["ABC", "MNP", "XYZ", "XYZ"],
                "val": [1, 2, 3, 4],
            },
            index=date_range("2013-06-19 09:30:00", periods=4, freq="5min"),
        )
        df_multi = df.set_index(["ACCOUNT", "TICKER"], append=True)

        expected = DataFrame(
            [[1]], index=Index(["ABC"], name="TICKER"), columns=["val"]
        )
        result = df_multi.loc[("2013-06-19 09:30:00", "ACCT1")]
        tm.assert_frame_equal(result, expected)

        expected = df_multi.loc[
            (Timestamp("2013-06-19 09:30:00", tz=None), "ACCT1", "ABC")
        ]
        result = df_multi.loc[("2013-06-19 09:30:00", "ACCT1", "ABC")]
        tm.assert_series_equal(result, expected)

        # partial string indexing on first level, scalar indexing on the other two
        result = df_multi.loc[("2013-06-19", "ACCT1", "ABC")]
        expected = df_multi.iloc[:1].droplevel([1, 2])
        tm.assert_frame_equal(result, expected)

    def test_partial_slicing_with_multiindex_series(self):
        # GH 4294
        # partial slice on a series mi
        ser = DataFrame(
            np.random.default_rng(2).random((1000, 1000)),
            index=date_range("2000-1-1", periods=1000),
        ).stack(future_stack=True)

        s2 = ser[:-1].copy()
        expected = s2["2000-1-4"]
        result = s2[Timestamp("2000-1-4")]
        tm.assert_series_equal(result, expected)

        result = ser[Timestamp("2000-1-4")]
        expected = ser["2000-1-4"]
        tm.assert_series_equal(result, expected)

        df2 = DataFrame(ser)
        expected = df2.xs("2000-1-4")
        result = df2.loc[Timestamp("2000-1-4")]
        tm.assert_frame_equal(result, expected)

    def test_partial_slice_requires_monotonicity(self):
        # Disallowed since 2.0 (GH 37819)
        ser = Series(np.arange(10), date_range("2014-01-01", periods=10))

        nonmonotonic = ser.iloc[[3, 5, 4]]
        timestamp = Timestamp("2014-01-10")
        with pytest.raises(
            KeyError, match="Value based partial slicing on non-monotonic"
        ):
            nonmonotonic["2014-01-10":]

        with pytest.raises(KeyError, match=r"Timestamp\('2014-01-10 00:00:00'\)"):
            nonmonotonic[timestamp:]

        with pytest.raises(
            KeyError, match="Value based partial slicing on non-monotonic"
        ):
            nonmonotonic.loc["2014-01-10":]

        with pytest.raises(KeyError, match=r"Timestamp\('2014-01-10 00:00:00'\)"):
            nonmonotonic.loc[timestamp:]

    def test_loc_datetime_length_one(self):
        # GH16071
        df = DataFrame(
            columns=["1"],
            index=date_range("2016-10-01T00:00:00", "2016-10-01T23:59:59"),
        )
        result = df.loc[datetime(2016, 10, 1) :]
        tm.assert_frame_equal(result, df)

        result = df.loc["2016-10-01T00:00:00":]
        tm.assert_frame_equal(result, df)

    @pytest.mark.parametrize(
        "start",
        [
            "2018-12-02 21:50:00+00:00",
            Timestamp("2018-12-02 21:50:00+00:00"),
            Timestamp("2018-12-02 21:50:00+00:00").to_pydatetime(),
        ],
    )
    @pytest.mark.parametrize(
        "end",
        [
            "2018-12-02 21:52:00+00:00",
            Timestamp("2018-12-02 21:52:00+00:00"),
            Timestamp("2018-12-02 21:52:00+00:00").to_pydatetime(),
        ],
    )
    def test_getitem_with_datestring_with_UTC_offset(self, start, end):
        # GH 24076
        idx = date_range(
            start="2018-12-02 14:50:00-07:00",
            end="2018-12-02 14:50:00-07:00",
            freq="1min",
        )
        df = DataFrame(1, index=idx, columns=["A"])
        result = df[start:end]
        expected = df.iloc[0:3, :]
        tm.assert_frame_equal(result, expected)

        # GH 16785
        start = str(start)
        end = str(end)
        with pytest.raises(ValueError, match="Both dates must"):
            df[start : end[:-4] + "1:00"]

        with pytest.raises(ValueError, match="The index must be timezone"):
            df = df.tz_localize(None)
            df[start:end]

    def test_slice_reduce_to_series(self):
        # GH 27516
        df = DataFrame({"A": range(24)}, index=date_range("2000", periods=24, freq="M"))
        expected = Series(
            range(12), index=date_range("2000", periods=12, freq="M"), name="A"
        )
        result = df.loc["2000", "A"]
        tm.assert_series_equal(result, expected)
