@@ -84,6 +84,10 @@ from pandas._libs.util cimport (
84
84
)
85
85
86
86
from pandas._libs.tslib import array_to_datetime
87
+ from pandas._libs.tslibs import (
88
+ OutOfBoundsDatetime,
89
+ OutOfBoundsTimedelta,
90
+ )
87
91
from pandas._libs.tslibs.period import Period
88
92
89
93
from pandas._libs.missing cimport (
@@ -1652,7 +1656,8 @@ def infer_datetimelike_array(arr: ndarray[object]) -> tuple[str, bool]:
1652
1656
# convert *every* string array
1653
1657
if len (objs):
1654
1658
try :
1655
- array_to_datetime(objs, errors = " raise" )
1659
+ # require_iso8601 as in maybe_infer_to_datetimelike
1660
+ array_to_datetime(objs, errors = " raise" , require_iso8601 = True )
1656
1661
return " datetime" , seen_str
1657
1662
except (ValueError , TypeError ):
1658
1663
pass
@@ -2334,7 +2339,8 @@ def maybe_convert_objects(ndarray[object] objects,
2334
2339
bint convert_timedelta = False ,
2335
2340
bint convert_period = False ,
2336
2341
bint convert_interval = False ,
2337
- bint convert_to_nullable_integer = False ) -> "ArrayLike":
2342
+ bint convert_to_nullable_integer = False ,
2343
+ object dtype_if_all_nat = None ) -> "ArrayLike":
2338
2344
"""
2339
2345
Type inference function-- convert object array to proper dtype
2340
2346
@@ -2363,6 +2369,8 @@ def maybe_convert_objects(ndarray[object] objects,
2363
2369
convert_to_nullable_integer : bool , default False
2364
2370
If an array-like object contains only integer values (and NaN ) is
2365
2371
encountered , whether to convert and return an IntegerArray.
2372
+ dtype_if_all_nat : np.dtype , ExtensionDtype , or None , default None
2373
+ Dtype to cast to if we have all-NaT.
2366
2374
2367
2375
Returns
2368
2376
-------
@@ -2431,8 +2439,12 @@ def maybe_convert_objects(ndarray[object] objects,
2431
2439
seen.float_ = True
2432
2440
elif is_timedelta(val):
2433
2441
if convert_timedelta:
2434
- itimedeltas[i] = convert_to_timedelta64(val, " ns" ).view(" i8" )
2435
2442
seen.timedelta_ = True
2443
+ try :
2444
+ itimedeltas[i] = convert_to_timedelta64(val, " ns" ).view(" i8" )
2445
+ except OutOfBoundsTimedelta:
2446
+ seen.object_ = True
2447
+ break
2436
2448
else :
2437
2449
seen.object_ = True
2438
2450
break
@@ -2469,8 +2481,12 @@ def maybe_convert_objects(ndarray[object] objects,
2469
2481
break
2470
2482
else :
2471
2483
seen.datetime_ = True
2472
- idatetimes[i] = convert_to_tsobject(
2473
- val, None , None , 0 , 0 ).value
2484
+ try :
2485
+ idatetimes[i] = convert_to_tsobject(
2486
+ val, None , None , 0 , 0 ).value
2487
+ except OutOfBoundsDatetime:
2488
+ seen.object_ = True
2489
+ break
2474
2490
else :
2475
2491
seen.object_ = True
2476
2492
break
@@ -2558,8 +2574,13 @@ def maybe_convert_objects(ndarray[object] objects,
2558
2574
elif seen.nat_:
2559
2575
if not seen.numeric_:
2560
2576
if convert_datetime and convert_timedelta:
2561
- # TODO: array full of NaT ambiguity resolve here needed
2562
- pass
2577
+ dtype = dtype_if_all_nat
2578
+ if dtype is not None :
2579
+ # otherwise we keep object dtype
2580
+ result = _infer_all_nats(
2581
+ dtype, datetimes, timedeltas
2582
+ )
2583
+
2563
2584
elif convert_datetime:
2564
2585
result = datetimes
2565
2586
elif convert_timedelta:
@@ -2598,8 +2619,13 @@ def maybe_convert_objects(ndarray[object] objects,
2598
2619
elif seen.nat_:
2599
2620
if not seen.numeric_:
2600
2621
if convert_datetime and convert_timedelta:
2601
- # TODO: array full of NaT ambiguity resolve here needed
2602
- pass
2622
+ dtype = dtype_if_all_nat
2623
+ if dtype is not None :
2624
+ # otherwise we keep object dtype
2625
+ result = _infer_all_nats(
2626
+ dtype, datetimes, timedeltas
2627
+ )
2628
+
2603
2629
elif convert_datetime:
2604
2630
result = datetimes
2605
2631
elif convert_timedelta:
@@ -2630,6 +2656,26 @@ def maybe_convert_objects(ndarray[object] objects,
2630
2656
return objects
2631
2657
2632
2658
2659
+ cdef _infer_all_nats(dtype, ndarray datetimes, ndarray timedeltas):
2660
+ """
2661
+ If we have all-NaT values, cast these to the given dtype.
2662
+ """
2663
+ if isinstance (dtype, np.dtype):
2664
+ if dtype == " M8[ns]" :
2665
+ result = datetimes
2666
+ elif dtype == " m8[ns]" :
2667
+ result = timedeltas
2668
+ else :
2669
+ raise ValueError (dtype)
2670
+ else :
2671
+ # ExtensionDtype
2672
+ cls = dtype.construct_array_type()
2673
+ i8vals = np.empty(len (datetimes), dtype = " i8" )
2674
+ i8vals.fill(NPY_NAT)
2675
+ result = cls (i8vals, dtype = dtype)
2676
+ return result
2677
+
2678
+
2633
2679
class NoDefault (Enum ):
2634
2680
# We make this an Enum
2635
2681
# 1) because it round-trips through pickle correctly (see GH#40397)
0 commit comments