diff --git a/pandas/_libs/tslib.pyx b/pandas/_libs/tslib.pyx index a09f4321c0d3c..d320bfdbe3022 100644 --- a/pandas/_libs/tslib.pyx +++ b/pandas/_libs/tslib.pyx @@ -598,7 +598,8 @@ cpdef array_to_datetime( is_same_offsets = len(out_tzoffset_vals) == 1 if not is_same_offsets: raise ValueError( - "cannot parse datetimes with mixed time zones unless `utc=True`" + "Mixed timezones detected. Pass utc=True in to_datetime " + "or tz='UTC' in DatetimeIndex to convert to a common timezone." ) elif state.found_naive or state.found_other: # e.g. test_to_datetime_mixed_awareness_mixed_types @@ -610,7 +611,7 @@ cpdef array_to_datetime( if not tz_compare(tz_out, tz_out2): # e.g. test_to_datetime_mixed_tzs_mixed_types raise ValueError( - "Mixed timezones detected. pass utc=True in to_datetime " + "Mixed timezones detected. Pass utc=True in to_datetime " "or tz='UTC' in DatetimeIndex to convert to a common timezone." ) # e.g. test_to_datetime_mixed_types_matching_tzs diff --git a/pandas/_libs/tslibs/strptime.pyx b/pandas/_libs/tslibs/strptime.pyx index cd2475830b013..5c9f1c770ea7f 100644 --- a/pandas/_libs/tslibs/strptime.pyx +++ b/pandas/_libs/tslibs/strptime.pyx @@ -503,7 +503,8 @@ def array_strptime( is_same_offsets = len(out_tzoffset_vals) == 1 if not is_same_offsets or (state.found_naive or state.found_other): raise ValueError( - "cannot parse datetimes with mixed time zones unless `utc=True`" + "Mixed timezones detected. Pass utc=True in to_datetime " + "or tz='UTC' in DatetimeIndex to convert to a common timezone." ) elif tz_out is not None: # GH#55693 @@ -512,7 +513,8 @@ def array_strptime( if not tz_compare(tz_out, tz_out2): # e.g. test_to_datetime_mixed_offsets_with_utc_false_removed raise ValueError( - "cannot parse datetimes with mixed time zones unless `utc=True`" + "Mixed timezones detected. Pass utc=True in to_datetime " + "or tz='UTC' in DatetimeIndex to convert to a common timezone." ) # e.g. test_guess_datetime_format_with_parseable_formats else: @@ -523,7 +525,8 @@ def array_strptime( if tz_out and (state.found_other or state.found_naive_str): # found_other indicates a tz-naive int, float, dt64, or date raise ValueError( - "cannot parse datetimes with mixed time zones unless `utc=True`" + "Mixed timezones detected. Pass utc=True in to_datetime " + "or tz='UTC' in DatetimeIndex to convert to a common timezone." ) if infer_reso: diff --git a/pandas/core/tools/datetimes.py b/pandas/core/tools/datetimes.py index e64b175cea218..c416db4083f9a 100644 --- a/pandas/core/tools/datetimes.py +++ b/pandas/core/tools/datetimes.py @@ -932,7 +932,8 @@ def to_datetime( >>> pd.to_datetime( ... ["2020-10-25 02:00 +0200", "2020-10-25 04:00 +0100"] ... ) # doctest: +SKIP - ValueError: cannot parse datetimes with mixed time zones unless `utc=True` + ValueError: Mixed timezones detected. Pass utc=True in to_datetime + or tz='UTC' in DatetimeIndex to convert to a common timezone. - To create a :class:`Series` with mixed offsets and ``object`` dtype, please use :meth:`Series.apply` and :func:`datetime.datetime.strptime`: @@ -951,7 +952,8 @@ def to_datetime( >>> pd.to_datetime( ... ["2020-01-01 01:00:00-01:00", datetime(2020, 1, 1, 3, 0)] ... ) # doctest: +SKIP - ValueError: cannot parse datetimes with mixed time zones unless `utc=True` + ValueError: Mixed timezones detected. Pass utc=True in to_datetime + or tz='UTC' in DatetimeIndex to convert to a common timezone. | diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py index 009723fc42360..48bbfc1a9f646 100644 --- a/pandas/tests/indexes/datetimes/test_constructors.py +++ b/pandas/tests/indexes/datetimes/test_constructors.py @@ -296,7 +296,7 @@ def test_construction_index_with_mixed_timezones(self): tm.assert_index_equal(result, exp, exact=True) assert not isinstance(result, DatetimeIndex) - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): DatetimeIndex(["2013-11-02 22:00-05:00", "2013-11-03 22:00-06:00"]) diff --git a/pandas/tests/tools/test_to_datetime.py b/pandas/tests/tools/test_to_datetime.py index 3e617138c4a6a..42764c121e3d2 100644 --- a/pandas/tests/tools/test_to_datetime.py +++ b/pandas/tests/tools/test_to_datetime.py @@ -463,7 +463,7 @@ def test_to_datetime_parse_tzname_or_tzoffset_utc_false_removed( self, fmt, dates, expected_dates ): # GH#13486, GH#50887, GH#57275 - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime(dates, format=fmt) @@ -646,7 +646,7 @@ def test_to_datetime_mixed_dt_and_str_with_format_mixed_offsets_utc_false_remove args = ["2000-01-01 01:00:00", "2000-01-01 02:00:00+00:00"] ts1 = constructor(args[0]) ts2 = args[1] - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime([ts1, ts2], format=fmt, utc=False) @@ -679,7 +679,7 @@ def test_to_datetime_mixed_offsets_with_none_tz_utc_false_removed( ): # https://github.com/pandas-dev/pandas/issues/50071 # GH#57275 - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime( @@ -1152,7 +1152,7 @@ def test_to_datetime_different_offsets_removed(self, cache): ts_string_1 = "March 1, 2018 12:00:00+0400" ts_string_2 = "March 1, 2018 12:00:00+0500" arr = [ts_string_1] * 5 + [ts_string_2] * 5 - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime(arr, cache=cache) @@ -1509,7 +1509,7 @@ def test_to_datetime_coerce(self): "March 1, 2018 12:00:00+0500", "20100240", ] - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime(ts_strings, errors="coerce") @@ -1581,7 +1581,7 @@ def test_iso_8601_strings_with_same_offset(self): def test_iso_8601_strings_with_different_offsets_removed(self): # GH#17697, GH#11736, GH#50887, GH#57275 ts_strings = ["2015-11-18 15:30:00+05:30", "2015-11-18 16:30:00+06:30", NaT] - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime(ts_strings) @@ -1608,7 +1608,7 @@ def test_mixed_offsets_with_native_datetime_utc_false_raises(self): ser = Series(vals) assert all(ser[i] is vals[i] for i in range(len(vals))) # GH#40111 - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime(ser) @@ -1673,7 +1673,7 @@ def test_to_datetime_fixed_offset(self): ) def test_to_datetime_mixed_offsets_with_utc_false_removed(self, date): # GH#50887, GH#57275 - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime(date, utc=False) @@ -3463,7 +3463,7 @@ def test_to_datetime_with_empty_str_utc_false_format_mixed(): def test_to_datetime_with_empty_str_utc_false_offsets_and_format_mixed(): # GH#50887, GH#57275 - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime( @@ -3479,7 +3479,7 @@ def test_to_datetime_mixed_tzs_mixed_types(): arr = [ts, dtstr] msg = ( - "Mixed timezones detected. pass utc=True in to_datetime or tz='UTC' " + "Mixed timezones detected. Pass utc=True in to_datetime or tz='UTC' " "in DatetimeIndex to convert to a common timezone" ) with pytest.raises(ValueError, match=msg): @@ -3578,7 +3578,7 @@ def test_to_datetime_mixed_awareness_mixed_types(aware_val, naive_val, naive_fir to_datetime(vec, utc=True) else: - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime(vec) @@ -3586,7 +3586,7 @@ def test_to_datetime_mixed_awareness_mixed_types(aware_val, naive_val, naive_fir to_datetime(vec, utc=True) if both_strs: - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): to_datetime(vec, format="mixed") with pytest.raises(ValueError, match=msg): diff --git a/pandas/tests/tslibs/test_array_to_datetime.py b/pandas/tests/tslibs/test_array_to_datetime.py index 89328e4bb0032..35b72c9bb2887 100644 --- a/pandas/tests/tslibs/test_array_to_datetime.py +++ b/pandas/tests/tslibs/test_array_to_datetime.py @@ -200,7 +200,7 @@ def test_parsing_different_timezone_offsets(): data = ["2015-11-18 15:30:00+05:30", "2015-11-18 15:30:00+06:30"] data = np.array(data, dtype=object) - msg = "cannot parse datetimes with mixed time zones unless `utc=True`" + msg = "Mixed timezones detected. Pass utc=True in to_datetime" with pytest.raises(ValueError, match=msg): tslib.array_to_datetime(data)