diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 1b0a045dca180..ce0ea7bca55cd 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -1905,13 +1905,16 @@ def std( def sequence_to_datetimes( - data, allow_object: bool = False + data, allow_object: bool = False, require_iso8601: bool = False ) -> Union[np.ndarray, DatetimeArray]: """ Parse/convert the passed data to either DatetimeArray or np.ndarray[object]. """ result, tz, freq = sequence_to_dt64ns( - data, allow_object=allow_object, allow_mixed=True + data, + allow_object=allow_object, + allow_mixed=True, + require_iso8601=require_iso8601, ) if result.dtype == object: return result @@ -1932,6 +1935,7 @@ def sequence_to_dt64ns( *, allow_object: bool = False, allow_mixed: bool = False, + require_iso8601: bool = False, ): """ Parameters @@ -1949,6 +1953,8 @@ def sequence_to_dt64ns( data contains more than one timezone. allow_mixed : bool, default False Interpret integers as timestamps when datetime objects are also present. + require_iso8601 : bool, default False + Only consider ISO-8601 formats when parsing strings. Returns ------- @@ -2017,6 +2023,7 @@ def sequence_to_dt64ns( yearfirst=yearfirst, allow_object=allow_object, allow_mixed=allow_mixed, + require_iso8601=require_iso8601, ) if tz and inferred_tz: # two timezones: convert to intended from base UTC repr @@ -2083,8 +2090,8 @@ def objects_to_datetime64ns( yearfirst, utc=False, errors="raise", - require_iso8601=False, - allow_object=False, + require_iso8601: bool = False, + allow_object: bool = False, allow_mixed: bool = False, ): """ diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index f5ec6616659ba..743dd2eafc9c9 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -1520,40 +1520,25 @@ def maybe_infer_to_datetimelike(value: Union[np.ndarray, List]): def try_datetime(v: np.ndarray) -> ArrayLike: # Coerce to datetime64, datetime64tz, or in corner cases # object[datetimes] - from pandas.core.arrays.datetimes import ( - DatetimeArray, - objects_to_datetime64ns, - tz_to_dtype, - ) + from pandas.core.arrays.datetimes import sequence_to_datetimes try: # GH#19671 we pass require_iso8601 to be relatively strict # when parsing strings. - vals, tz = objects_to_datetime64ns( - v, - require_iso8601=True, - dayfirst=False, - yearfirst=False, - allow_object=True, - ) + dta = sequence_to_datetimes(v, require_iso8601=True, allow_object=True) except (ValueError, TypeError): # e.g. is not convertible to datetime return v.reshape(shape) else: - # we might have a sequence of the same-datetimes with tz's - # if so coerce to a DatetimeIndex; if they are not the same, - # then these stay as object dtype, xref GH#19671 - - if vals.dtype == object: + if dta.dtype == object or dta.tz is None: + # GH#19671 if we have mixed timezones we may have object-dtype + # here. # This is reachable bc allow_object=True, means we cast things # to mixed-tz datetime objects (mostly). Only 1 test # relies on this behavior, see GH#40111 - return vals.reshape(shape) - - dta = DatetimeArray._simple_new(vals.view("M8[ns]"), dtype=tz_to_dtype(tz)) - if dta.tz is None: - # TODO(EA2D): conditional reshape kludge unnecessary with 2D EAs - return dta._ndarray.reshape(shape) + # FIXME: conditional reshape is kludgy + return np.asarray(dta).reshape(shape) + # otherwise we have dt64tz return dta def try_timedelta(v: np.ndarray) -> np.ndarray: