Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -737,6 +737,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="125min")
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