Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ Other Deprecations
- Deprecated using ``epoch`` date format in :meth:`DataFrame.to_json` and :meth:`Series.to_json`, use ``iso`` instead. (:issue:`57063`)
- Deprecated allowing ``fill_value`` that cannot be held in the original dtype (excepting NA values for integer and bool dtypes) in :meth:`Series.unstack` and :meth:`DataFrame.unstack` (:issue:`12189`, :issue:`53868`)
- Deprecated allowing ``fill_value`` that cannot be held in the original dtype (excepting NA values for integer and bool dtypes) in :meth:`Series.shift` and :meth:`DataFrame.shift` (:issue:`53802`)
- Deprecated allowing strings representing full dates in :meth:`DataFrame.at_time` and :meth:`Series.at_time` (:issue:`50839`)
- Deprecated backward-compatibility behavior for :meth:`DataFrame.select_dtypes` matching "str" dtype when ``np.object_`` is specified (:issue:`61916`)
- Deprecated option "future.no_silent_downcasting", as it is no longer used. In a future version accessing this option will raise (:issue:`59502`)
- Deprecated silent casting of non-datetime 'other' to datetime in :meth:`Series.combine_first` (:issue:`62931`)
Expand Down
32 changes: 31 additions & 1 deletion pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,37 @@ def indexer_at_time(self, time, asof: bool = False) -> npt.NDArray[np.intp]:
if isinstance(time, str):
from dateutil.parser import parse

time = parse(time).time()
orig = time
try:
alt = to_time(time)
except ValueError:
warnings.warn(
# GH#50839
f"The string '{orig}' cannot be parsed using pd.core.tools.to_time "
f"and in a future version will raise. "
"Use an unambiguous time string format or explicitly cast to "
"`datetime.time` before calling.",
Pandas4Warning,
stacklevel=find_stack_level(),
)
time = parse(time).time()
else:
try:
time = parse(time).time()
except ValueError:
# e.g. '23550' raises dateutil.parser._parser.ParserError
time = alt
if alt != time:
warnings.warn(
# GH#50839
f"The string '{orig}' is currently parsed as {time} "
f"but in a future version will be parsed as {alt}, consistent"
"with `between_time` behavior. To avoid this warning, "
"use an unambiguous string format or explicitly cast to "
"`datetime.time` before calling.",
Pandas4Warning,
stacklevel=find_stack_level(),
)

if time.tzinfo:
if self.tz is None:
Expand Down
19 changes: 19 additions & 0 deletions pandas/tests/frame/methods/test_at_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import pytest

from pandas._libs.tslibs import timezones
from pandas.errors import Pandas4Warning

from pandas import (
DataFrame,
Expand Down Expand Up @@ -132,3 +133,21 @@ def test_at_time_datetimeindex(self):
tm.assert_frame_equal(result, expected)
tm.assert_frame_equal(result, expected2)
assert len(result) == 4

def test_at_time_ambiguous_format_deprecation(self):
# GH#50839
rng = date_range("1/1/2000", "1/5/2000", freq="5min")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we test with less data? (like end at 1/2/2000)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, will update

ts = DataFrame(list(range(len(rng))), index=rng)

msg1 = "The string '.*' cannot be parsed"
with tm.assert_produces_warning(Pandas4Warning, match=msg1):
ts.at_time("2022-12-12 00:00:00")
with tm.assert_produces_warning(Pandas4Warning, match=msg1):
ts.at_time("2022-12-12 00:00:00 +09:00")
with tm.assert_produces_warning(Pandas4Warning, match=msg1):
ts.at_time("2022-12-12 00:00:00.000000")

# The dateutil parser raises on these, so we can give the future behavior
# immediately using pd.core.tools.to_time
ts.at_time("235500")
ts.at_time("115500PM")
5 changes: 3 additions & 2 deletions pandas/tests/generic/test_finalize.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

from copy import deepcopy
from datetime import time
import operator
import re

Expand Down Expand Up @@ -280,12 +281,12 @@
(
pd.Series,
(1, pd.date_range("2000", periods=4)),
operator.methodcaller("at_time", "12:00"),
operator.methodcaller("at_time", time(12)),
),
(
pd.DataFrame,
({"A": [1, 1, 1, 1]}, pd.date_range("2000", periods=4)),
operator.methodcaller("at_time", "12:00"),
operator.methodcaller("at_time", time(12)),
),
(
pd.Series,
Expand Down
Loading