diff --git a/doc/source/whatsnew/v1.5.3.rst b/doc/source/whatsnew/v1.5.3.rst index b6c1c857717c7..763f9f87194d5 100644 --- a/doc/source/whatsnew/v1.5.3.rst +++ b/doc/source/whatsnew/v1.5.3.rst @@ -33,7 +33,6 @@ Bug fixes Other ~~~~~ - -- .. --------------------------------------------------------------------------- .. _whatsnew_153.contributors: diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 62b0ea5307e41..d0eed405c944c 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -671,7 +671,7 @@ Timezones ^^^^^^^^^ - Bug in :meth:`Series.astype` and :meth:`DataFrame.astype` with object-dtype containing multiple timezone-aware ``datetime`` objects with heterogeneous timezones to a :class:`DatetimeTZDtype` incorrectly raising (:issue:`32581`) - Bug in :func:`to_datetime` was failing to parse date strings with timezone name when ``format`` was specified with ``%Z`` (:issue:`49748`) -- +- Better error message when passing invalid values to ``ambiguous`` parameter in :meth:`Timestamp.tz_localize` (:issue:`49565`) Numeric ^^^^^^^ diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index f987a2feb2717..f25114c273bcf 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -6,8 +6,8 @@ construction requirements, we need to do object instantiation in python (see Timestamp class below). This will serve as a C extension type that shadows the python class, where we do any heavy lifting. """ -import warnings +import warnings cimport cython import numpy as np @@ -1946,8 +1946,11 @@ default 'raise' >>> pd.NaT.tz_localize() NaT """ - if ambiguous == "infer": - raise ValueError("Cannot infer offset with only one time.") + if not isinstance(ambiguous, bool) and ambiguous not in {"NaT", "raise"}: + raise ValueError( + "'ambiguous' parameter must be one of: " + "True, False, 'NaT', 'raise' (default)" + ) nonexistent_options = ("raise", "NaT", "shift_forward", "shift_backward") if nonexistent not in nonexistent_options and not PyDelta_Check(nonexistent): diff --git a/pandas/tests/scalar/timestamp/test_timezones.py b/pandas/tests/scalar/timestamp/test_timezones.py index 3ebffaad23910..d7db99333cd03 100644 --- a/pandas/tests/scalar/timestamp/test_timezones.py +++ b/pandas/tests/scalar/timestamp/test_timezones.py @@ -6,6 +6,7 @@ datetime, timedelta, ) +import re import dateutil from dateutil.tz import ( @@ -102,7 +103,10 @@ def test_tz_localize_ambiguous(self): ts_no_dst = ts.tz_localize("US/Eastern", ambiguous=False) assert (ts_no_dst.value - ts_dst.value) / 1e9 == 3600 - msg = "Cannot infer offset with only one time" + msg = re.escape( + "'ambiguous' parameter must be one of: " + "True, False, 'NaT', 'raise' (default)" + ) with pytest.raises(ValueError, match=msg): ts.tz_localize("US/Eastern", ambiguous="infer") @@ -182,8 +186,8 @@ def test_tz_localize_ambiguous_compat(self): pytz_zone = "Europe/London" dateutil_zone = "dateutil/Europe/London" - result_pytz = naive.tz_localize(pytz_zone, ambiguous=0) - result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=0) + result_pytz = naive.tz_localize(pytz_zone, ambiguous=False) + result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=False) assert result_pytz.value == result_dateutil.value assert result_pytz.value == 1382835600000000000 @@ -194,8 +198,8 @@ def test_tz_localize_ambiguous_compat(self): assert str(result_pytz) == str(result_dateutil) # 1 hour difference - result_pytz = naive.tz_localize(pytz_zone, ambiguous=1) - result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=1) + result_pytz = naive.tz_localize(pytz_zone, ambiguous=True) + result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=True) assert result_pytz.value == result_dateutil.value assert result_pytz.value == 1382832000000000000 @@ -357,7 +361,6 @@ def test_astimezone(self, tzstr): @td.skip_if_windows def test_tz_convert_utc_with_system_utc(self): - # from system utc to real utc ts = Timestamp("2001-01-05 11:56", tz=timezones.maybe_get_tz("dateutil/UTC")) # check that the time hasn't changed.