@@ -505,144 +505,134 @@ cpdef array_to_datetime(
505
505
result = np.empty(n, dtype = " M8[ns]" )
506
506
iresult = result.view(" i8" )
507
507
508
- try :
509
- for i in range (n):
510
- val = values[i]
511
-
512
- try :
513
- if checknull_with_nat_and_na(val):
514
- iresult[i] = NPY_NAT
508
+ for i in range (n):
509
+ val = values[i]
515
510
516
- elif PyDateTime_Check(val):
517
- if val.tzinfo is not None :
518
- found_tz = True
519
- else :
520
- found_naive = True
521
- tz_out = convert_timezone(
522
- val.tzinfo,
523
- tz_out,
524
- found_naive,
525
- found_tz,
526
- utc_convert,
527
- )
528
- result[i] = parse_pydatetime(val, & dts, utc_convert)
511
+ try :
512
+ if checknull_with_nat_and_na(val):
513
+ iresult[i] = NPY_NAT
529
514
530
- elif PyDate_Check(val):
531
- iresult[i] = pydate_to_dt64(val, & dts)
532
- check_dts_bounds(& dts)
515
+ elif PyDateTime_Check(val):
516
+ if val.tzinfo is not None :
517
+ found_tz = True
518
+ else :
519
+ found_naive = True
520
+ tz_out = convert_timezone(
521
+ val.tzinfo,
522
+ tz_out,
523
+ found_naive,
524
+ found_tz,
525
+ utc_convert,
526
+ )
527
+ result[i] = parse_pydatetime(val, & dts, utc_convert)
528
+
529
+ elif PyDate_Check(val):
530
+ iresult[i] = pydate_to_dt64(val, & dts)
531
+ check_dts_bounds(& dts)
533
532
534
- elif is_datetime64_object(val):
535
- iresult[i] = get_datetime64_nanos(val, NPY_FR_ns)
533
+ elif is_datetime64_object(val):
534
+ iresult[i] = get_datetime64_nanos(val, NPY_FR_ns)
536
535
537
- elif is_integer_object(val) or is_float_object(val):
538
- # these must be ns unit by-definition
536
+ elif is_integer_object(val) or is_float_object(val):
537
+ # these must be ns unit by-definition
539
538
540
- if val != val or val == NPY_NAT:
541
- iresult[i] = NPY_NAT
542
- elif is_raise or is_ignore:
543
- iresult[i] = val
544
- else :
545
- # coerce
546
- # we now need to parse this as if unit='ns'
547
- # we can ONLY accept integers at this point
548
- # if we have previously (or in future accept
549
- # datetimes/strings, then we must coerce)
550
- try :
551
- iresult[i] = cast_from_unit(val, " ns" )
552
- except OverflowError :
553
- iresult[i] = NPY_NAT
554
-
555
- elif isinstance (val, str ):
556
- # string
557
- if type (val) is not str :
558
- # GH#32264 np.str_ object
559
- val = str (val)
560
-
561
- if len (val) == 0 or val in nat_strings:
539
+ if val != val or val == NPY_NAT:
540
+ iresult[i] = NPY_NAT
541
+ elif is_raise or is_ignore:
542
+ iresult[i] = val
543
+ else :
544
+ # coerce
545
+ # we now need to parse this as if unit='ns'
546
+ # we can ONLY accept integers at this point
547
+ # if we have previously (or in future accept
548
+ # datetimes/strings, then we must coerce)
549
+ try :
550
+ iresult[i] = cast_from_unit(val, " ns" )
551
+ except OverflowError :
562
552
iresult[i] = NPY_NAT
563
- continue
564
553
565
- string_to_dts_failed = string_to_dts(
566
- val, & dts, & out_bestunit, & out_local,
567
- & out_tzoffset, False , None , False
568
- )
569
- if string_to_dts_failed:
570
- # An error at this point is a _parsing_ error
571
- # specifically _not_ OutOfBoundsDatetime
572
- if parse_today_now(val, & iresult[i], utc):
573
- continue
574
-
575
- try :
576
- py_dt = parse_datetime_string(val,
577
- dayfirst = dayfirst,
578
- yearfirst = yearfirst)
579
- # If the dateutil parser returned tzinfo, capture it
580
- # to check if all arguments have the same tzinfo
581
- tz = py_dt.utcoffset()
582
-
583
- except (ValueError , OverflowError ):
584
- if is_coerce:
585
- iresult[i] = NPY_NAT
586
- continue
587
- raise TypeError (
588
- f" invalid string coercion to datetime "
589
- f" for \" {val}\" , at position {i}"
590
- )
554
+ elif isinstance (val, str ):
555
+ # string
556
+ if type (val) is not str :
557
+ # GH#32264 np.str_ object
558
+ val = str (val)
591
559
592
- if tz is not None :
593
- seen_datetime_offset = True
594
- # dateutil timezone objects cannot be hashed, so
595
- # store the UTC offsets in seconds instead
596
- out_tzoffset_vals.add(tz.total_seconds())
597
- else :
598
- # Add a marker for naive string, to track if we are
599
- # parsing mixed naive and aware strings
600
- out_tzoffset_vals.add(" naive" )
601
-
602
- _ts = convert_datetime_to_tsobject(py_dt, None )
603
- iresult[i] = _ts.value
604
- if not string_to_dts_failed:
605
- # No error reported by string_to_dts, pick back up
606
- # where we left off
607
- value = npy_datetimestruct_to_datetime(NPY_FR_ns, & dts)
608
- if out_local == 1 :
609
- seen_datetime_offset = True
610
- # Store the out_tzoffset in seconds
611
- # since we store the total_seconds of
612
- # dateutil.tz.tzoffset objects
613
- out_tzoffset_vals.add(out_tzoffset * 60. )
614
- tz = timezone(timedelta(minutes = out_tzoffset))
615
- value = tz_localize_to_utc_single(value, tz)
616
- out_local = 0
617
- out_tzoffset = 0
618
- else :
619
- # Add a marker for naive string, to track if we are
620
- # parsing mixed naive and aware strings
621
- out_tzoffset_vals.add(" naive" )
622
- iresult[i] = value
623
- check_dts_bounds(& dts)
560
+ if len (val) == 0 or val in nat_strings:
561
+ iresult[i] = NPY_NAT
562
+ continue
624
563
625
- else :
626
- if is_coerce:
627
- iresult[i] = NPY_NAT
564
+ string_to_dts_failed = string_to_dts(
565
+ val, & dts, & out_bestunit, & out_local,
566
+ & out_tzoffset, False , None , False
567
+ )
568
+ if string_to_dts_failed:
569
+ # An error at this point is a _parsing_ error
570
+ # specifically _not_ OutOfBoundsDatetime
571
+ if parse_today_now(val, & iresult[i], utc):
572
+ continue
573
+
574
+ py_dt = parse_datetime_string(val,
575
+ dayfirst = dayfirst,
576
+ yearfirst = yearfirst)
577
+ # If the dateutil parser returned tzinfo, capture it
578
+ # to check if all arguments have the same tzinfo
579
+ tz = py_dt.utcoffset()
580
+
581
+ if tz is not None :
582
+ seen_datetime_offset = True
583
+ # dateutil timezone objects cannot be hashed, so
584
+ # store the UTC offsets in seconds instead
585
+ out_tzoffset_vals.add(tz.total_seconds())
628
586
else :
629
- raise TypeError (f" {type(val)} is not convertible to datetime" )
587
+ # Add a marker for naive string, to track if we are
588
+ # parsing mixed naive and aware strings
589
+ out_tzoffset_vals.add(" naive" )
630
590
631
- except OutOfBoundsDatetime as ex:
632
- ex.args = (f" {ex}, at position {i}" ,)
633
- if is_coerce:
634
- iresult[i] = NPY_NAT
635
- continue
636
- raise
591
+ _ts = convert_datetime_to_tsobject(py_dt, None )
592
+ iresult[i] = _ts.value
593
+ else :
594
+ # No error reported by string_to_dts, pick back up
595
+ # where we left off
596
+ value = npy_datetimestruct_to_datetime(NPY_FR_ns, & dts)
597
+ if out_local == 1 :
598
+ seen_datetime_offset = True
599
+ # Store the out_tzoffset in seconds
600
+ # since we store the total_seconds of
601
+ # dateutil.tz.tzoffset objects
602
+ out_tzoffset_vals.add(out_tzoffset * 60. )
603
+ tz = timezone(timedelta(minutes = out_tzoffset))
604
+ value = tz_localize_to_utc_single(value, tz)
605
+ out_local = 0
606
+ out_tzoffset = 0
607
+ else :
608
+ # Add a marker for naive string, to track if we are
609
+ # parsing mixed naive and aware strings
610
+ out_tzoffset_vals.add(" naive" )
611
+ iresult[i] = value
612
+ check_dts_bounds(& dts)
637
613
638
- except OutOfBoundsDatetime:
639
- if is_raise:
640
- raise
614
+ else :
615
+ raise TypeError (f" {type(val)} is not convertible to datetime" )
641
616
642
- return ignore_errors_out_of_bounds_fallback(values), tz_out
617
+ except (OutOfBoundsDatetime,) as ex:
618
+ ex.args = (f" {ex}, at position {i}" ,)
619
+ if is_coerce:
620
+ iresult[i] = NPY_NAT
621
+ continue
622
+ elif is_raise:
623
+ raise
624
+ if isinstance (ex, OutOfBoundsDatetime):
625
+ return ignore_errors_out_of_bounds_fallback(values), tz_out
626
+ return values, None
643
627
644
- except TypeError :
645
- return _array_to_datetime_object(values, errors, dayfirst, yearfirst)
628
+ except (TypeError , OverflowError , ValueError ) as ex:
629
+ ex.args = (f" {ex}, at position {i}" ,)
630
+ if is_coerce:
631
+ iresult[i] = NPY_NAT
632
+ continue
633
+ elif is_raise:
634
+ raise
635
+ return values, None
646
636
647
637
if seen_datetime_offset and not utc_convert:
648
638
# GH#17697
0 commit comments