Skip to content

Commit 3b632d9

Browse files
authored
DEPR: silently ignoring unrecognized timezones (#51477)
* DEPR: silently ignoring unrecognized timezones * catch to_datetime cases
1 parent b02728c commit 3b632d9

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

doc/source/whatsnew/v2.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,7 @@ Other API changes
838838
Deprecations
839839
~~~~~~~~~~~~
840840
- Deprecated parsing datetime strings with system-local timezone to ``tzlocal``, pass a ``tz`` keyword or explicitly call ``tz_localize`` instead (:issue:`50791`)
841+
- Deprecated silently dropping unrecognized timezones when parsing strings to datetimes (:issue:`18702`)
841842
- Deprecated argument ``infer_datetime_format`` in :func:`to_datetime` and :func:`read_csv`, as a strict version of it is now the default (:issue:`48621`)
842843
- Deprecated behavior of :func:`to_datetime` with ``unit`` when parsing strings, in a future version these will be parsed as datetimes (matching unit-less behavior) instead of cast to floats. To retain the old behavior, cast strings to numeric types before calling :func:`to_datetime` (:issue:`50735`)
843844
- Deprecated :func:`pandas.io.sql.execute` (:issue:`50185`)

pandas/_libs/tslibs/parsing.pyx

+24-1
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,18 @@ cdef datetime dateutil_parse(
722722
f'Parsed string "{timestr}" gives an invalid tzoffset, '
723723
"which must be between -timedelta(hours=24) and timedelta(hours=24)"
724724
)
725+
elif res.tzname is not None:
726+
# e.g. "1994 Jan 15 05:16 FOO" where FOO is not recognized
727+
# GH#18702
728+
warnings.warn(
729+
f'Parsed string "{timestr}" included an un-recognized timezone '
730+
f'"{res.tzname}". Dropping unrecognized timezones is deprecated; '
731+
"in a future version this will raise. Instead pass the string "
732+
"without the timezone, then use .tz_localize to convert to a "
733+
"recognized timezone.",
734+
FutureWarning,
735+
stacklevel=find_stack_level()
736+
)
725737

726738
out_bestunit[0] = attrname_to_npy_unit[reso]
727739
return ret
@@ -865,6 +877,8 @@ def guess_datetime_format(dt_str: str, bint dayfirst=False) -> str | None:
865877
datetime format string (for `strftime` or `strptime`),
866878
or None if it can't be guessed.
867879
"""
880+
cdef:
881+
NPY_DATETIMEUNIT out_bestunit
868882
day_attribute_and_format = (("day",), "%d", 2)
869883

870884
# attr name, format, padding (if any)
@@ -895,8 +909,17 @@ def guess_datetime_format(dt_str: str, bint dayfirst=False) -> str | None:
895909
datetime_attrs_to_format.remove(day_attribute_and_format)
896910
datetime_attrs_to_format.insert(0, day_attribute_and_format)
897911

912+
# same default used by dateutil
913+
default = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
898914
try:
899-
parsed_datetime = du_parse(dt_str, dayfirst=dayfirst)
915+
parsed_datetime = dateutil_parse(
916+
dt_str,
917+
default=default,
918+
dayfirst=dayfirst,
919+
yearfirst=False,
920+
ignoretz=False,
921+
out_bestunit=&out_bestunit,
922+
)
900923
except (ValueError, OverflowError, InvalidOperation):
901924
# In case the datetime can't be parsed, its format cannot be guessed
902925
return None

pandas/tests/tools/test_to_datetime.py

+16
Original file line numberDiff line numberDiff line change
@@ -3595,3 +3595,19 @@ def test_to_datetime_mixed_not_necessarily_iso8601_coerce(errors, expected):
35953595
# https://github.com/pandas-dev/pandas/issues/50411
35963596
result = to_datetime(["2020-01-01", "01-01-2000"], format="ISO8601", errors=errors)
35973597
tm.assert_index_equal(result, expected)
3598+
3599+
3600+
def test_ignoring_unknown_tz_deprecated():
3601+
# GH#18702, GH#51476
3602+
dtstr = "2014 Jan 9 05:15 FAKE"
3603+
msg = 'un-recognized timezone "FAKE". Dropping unrecognized timezones is deprecated'
3604+
with tm.assert_produces_warning(FutureWarning, match=msg):
3605+
res = Timestamp(dtstr)
3606+
assert res == Timestamp(dtstr[:-5])
3607+
3608+
with tm.assert_produces_warning(FutureWarning):
3609+
res = to_datetime(dtstr)
3610+
assert res == to_datetime(dtstr[:-5])
3611+
with tm.assert_produces_warning(FutureWarning):
3612+
res = to_datetime([dtstr])
3613+
tm.assert_index_equal(res, to_datetime([dtstr[:-5]]))

0 commit comments

Comments
 (0)