Skip to content

Commit 09e8e1a

Browse files
committed
BUG: Correctly localize naive ts strings with Series and datetimetz dtype (pandas-dev#17415)
Add whatsnew Fix lint error
1 parent f7f214b commit 09e8e1a

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,7 @@ Conversion
10271027
- Bug in :meth:`~DataFrame.astype` converting to object dtype when passed extension type classes (`DatetimeTZDtype``, ``CategoricalDtype``) rather than instances. Now a ``TypeError`` is raised when a class is passed (:issue:`17780`).
10281028
- Bug in :meth:`to_numeric` in which elements were not always being coerced to numeric when ``errors='coerce'`` (:issue:`17007`, :issue:`17125`)
10291029
- Bug in ``DataFrame`` and ``Series`` constructors where ``range`` objects are converted to ``int32`` dtype on Windows instead of ``int64`` (:issue:`16804`)
1030+
- Bug in localization of a naive, datetime string in a ``Series`` constructor with a ``datetime[ns, timezone]`` dtype (:issue:`174151`)
10301031

10311032
Indexing
10321033
^^^^^^^^

pandas/core/dtypes/cast.py

+11-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
is_integer_dtype,
1919
is_datetime_or_timedelta_dtype,
2020
is_bool_dtype, is_scalar,
21-
_string_dtypes,
21+
is_string_dtype, _string_dtypes,
2222
pandas_dtype,
2323
_ensure_int8, _ensure_int16,
2424
_ensure_int32, _ensure_int64,
@@ -998,12 +998,16 @@ def maybe_cast_to_datetime(value, dtype, errors='raise'):
998998
if is_datetime64:
999999
value = to_datetime(value, errors=errors)._values
10001000
elif is_datetime64tz:
1001-
# input has to be UTC at this point, so just
1002-
# localize
1003-
value = (to_datetime(value, errors=errors)
1004-
.tz_localize('UTC')
1005-
.tz_convert(dtype.tz)
1006-
)
1001+
is_dt_string = is_string_dtype(value)
1002+
value = to_datetime(value, errors=errors)
1003+
if is_dt_string:
1004+
# Strings here are naive, so directly localize
1005+
value = value.tz_localize(dtype.tz)
1006+
else:
1007+
# Numeric values are UTC at this point,
1008+
# so localize and convert
1009+
value = (value.tz_localize('UTC')
1010+
.tz_convert(dtype.tz))
10071011
elif is_timedelta64:
10081012
value = to_timedelta(value, errors=errors)._values
10091013
except (AttributeError, ValueError, TypeError):

pandas/tests/series/test_constructors.py

+6
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,12 @@ def test_constructor_with_datetime_tz(self):
574574
expected = Series(pd.DatetimeIndex(['NaT', 'NaT'], tz='US/Eastern'))
575575
assert_series_equal(s, expected)
576576

577+
# GH 17415: With naive string
578+
ts_naive = '2013-01-01 00:00:00'
579+
result = Series([ts_naive], dtype='datetime64[ns, CET]')
580+
expected = Series([pd.Timestamp(ts_naive, tz='CET')])
581+
assert_series_equal(result, expected)
582+
577583
def test_construction_interval(self):
578584
# construction from interval & array of intervals
579585
index = IntervalIndex.from_breaks(np.arange(3), closed='right')

0 commit comments

Comments
 (0)