Skip to content

Commit b835ca2

Browse files
authored
REF: simplify to_datetime, annotations (#40156)
1 parent 9ee5c1b commit b835ca2

File tree

1 file changed

+63
-41
lines changed

1 file changed

+63
-41
lines changed

pandas/core/tools/datetimes.py

+63-41
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ def _convert_listlike_datetimes(
284284
tz: Optional[Timezone] = None,
285285
unit: Optional[str] = None,
286286
errors: Optional[str] = None,
287-
infer_datetime_format: Optional[bool] = None,
287+
infer_datetime_format: bool = False,
288288
dayfirst: Optional[bool] = None,
289289
yearfirst: Optional[bool] = None,
290290
exact: bool = True,
@@ -305,7 +305,7 @@ def _convert_listlike_datetimes(
305305
None or string of the frequency of the passed data
306306
errors : string
307307
error handing behaviors from to_datetime, 'raise', 'coerce', 'ignore'
308-
infer_datetime_format : boolean
308+
infer_datetime_format : bool, default False
309309
inferring format behavior from to_datetime
310310
dayfirst : boolean
311311
dayfirst parsing behavior from to_datetime
@@ -413,17 +413,16 @@ def _convert_listlike_datetimes(
413413
require_iso8601 = not infer_datetime_format
414414
format = None
415415

416-
tz_parsed = None
417416
result = None
418417

419418
if format is not None:
420419
try:
421420
# shortcut formatting here
422421
if format == "%Y%m%d":
422+
# pass orig_arg as float-dtype may have been converted to
423+
# datetime64[ns]
424+
orig_arg = ensure_object(orig_arg)
423425
try:
424-
# pass orig_arg as float-dtype may have been converted to
425-
# datetime64[ns]
426-
orig_arg = ensure_object(orig_arg)
427426
result = _attempt_YYYYMMDD(orig_arg, errors=errors)
428427
except (ValueError, TypeError, OutOfBoundsDatetime) as err:
429428
raise ValueError(
@@ -432,36 +431,12 @@ def _convert_listlike_datetimes(
432431

433432
# fallback
434433
if result is None:
435-
try:
436-
result, timezones = array_strptime(
437-
arg, format, exact=exact, errors=errors
438-
)
439-
if "%Z" in format or "%z" in format:
440-
return _return_parsed_timezone_results(
441-
result, timezones, tz, name
442-
)
443-
except OutOfBoundsDatetime:
444-
if errors == "raise":
445-
raise
446-
elif errors == "coerce":
447-
result = np.empty(arg.shape, dtype="M8[ns]")
448-
iresult = result.view("i8")
449-
iresult.fill(iNaT)
450-
else:
451-
result = arg
452-
except ValueError:
453-
# if format was inferred, try falling back
454-
# to array_to_datetime - terminate here
455-
# for specified formats
456-
if not infer_datetime_format:
457-
if errors == "raise":
458-
raise
459-
elif errors == "coerce":
460-
result = np.empty(arg.shape, dtype="M8[ns]")
461-
iresult = result.view("i8")
462-
iresult.fill(iNaT)
463-
else:
464-
result = arg
434+
result = _array_strptime_with_fallback(
435+
arg, name, tz, format, exact, errors, infer_datetime_format
436+
)
437+
if result is not None:
438+
return result
439+
465440
except ValueError as e:
466441
# Fallback to try to convert datetime objects if timezone-aware
467442
# datetime objects are found without passing `utc=True`
@@ -485,16 +460,63 @@ def _convert_listlike_datetimes(
485460
allow_object=True,
486461
)
487462

488-
if tz_parsed is not None:
489-
# We can take a shortcut since the datetime64 numpy array
490-
# is in UTC
491-
dta = DatetimeArray(result, dtype=tz_to_dtype(tz_parsed))
492-
return DatetimeIndex._simple_new(dta, name=name)
463+
if tz_parsed is not None:
464+
# We can take a shortcut since the datetime64 numpy array
465+
# is in UTC
466+
dta = DatetimeArray(result, dtype=tz_to_dtype(tz_parsed))
467+
return DatetimeIndex._simple_new(dta, name=name)
493468

494469
utc = tz == "utc"
495470
return _box_as_indexlike(result, utc=utc, name=name)
496471

497472

473+
def _array_strptime_with_fallback(
474+
arg,
475+
name,
476+
tz,
477+
fmt: str,
478+
exact: bool,
479+
errors: Optional[str],
480+
infer_datetime_format: bool,
481+
) -> Optional[Index]:
482+
"""
483+
Call array_strptime, with fallback behavior depending on 'errors'.
484+
"""
485+
utc = tz == "utc"
486+
487+
try:
488+
result, timezones = array_strptime(arg, fmt, exact=exact, errors=errors)
489+
if "%Z" in fmt or "%z" in fmt:
490+
return _return_parsed_timezone_results(result, timezones, tz, name)
491+
except OutOfBoundsDatetime:
492+
if errors == "raise":
493+
raise
494+
elif errors == "coerce":
495+
result = np.empty(arg.shape, dtype="M8[ns]")
496+
iresult = result.view("i8")
497+
iresult.fill(iNaT)
498+
else:
499+
result = arg
500+
except ValueError:
501+
# if fmt was inferred, try falling back
502+
# to array_to_datetime - terminate here
503+
# for specified formats
504+
if not infer_datetime_format:
505+
if errors == "raise":
506+
raise
507+
elif errors == "coerce":
508+
result = np.empty(arg.shape, dtype="M8[ns]")
509+
iresult = result.view("i8")
510+
iresult.fill(iNaT)
511+
else:
512+
result = arg
513+
else:
514+
# Indicates to the caller to fallback to objects_to_datetime64ns
515+
return None
516+
517+
return _box_as_indexlike(result, utc=utc, name=name)
518+
519+
498520
def _adjust_to_origin(arg, origin, unit):
499521
"""
500522
Helper function for to_datetime.

0 commit comments

Comments
 (0)