@@ -34,15 +34,21 @@ from pandas._libs.tslibs.nattype cimport (
3434 c_nat_strings as nat_strings,
3535)
3636from pandas._libs.tslibs.np_datetime cimport (
37+ NPY_DATETIMEUNIT,
3738 NPY_FR_ns,
3839 check_dts_bounds,
3940 npy_datetimestruct,
4041 npy_datetimestruct_to_datetime,
4142 pydate_to_dt64,
4243 pydatetime_to_dt64,
44+ string_to_dts,
4345)
4446from pandas._libs.tslibs.timestamps cimport _Timestamp
45- from pandas._libs.util cimport is_datetime64_object
47+ from pandas._libs.util cimport (
48+ is_datetime64_object,
49+ is_float_object,
50+ is_integer_object,
51+ )
4652
4753cnp.import_array()
4854
@@ -89,6 +95,7 @@ def array_strptime(
8995 exact : matches must be exact if True, search if False
9096 errors : string specifying error handling, {'raise', 'ignore', 'coerce'}
9197 """
98+ from pandas._libs.tslibs.parsing import format_is_iso
9299
93100 cdef:
94101 Py_ssize_t i, n = len (values)
@@ -106,6 +113,9 @@ def array_strptime(
106113 bint found_naive = False
107114 bint found_tz = False
108115 tzinfo tz_out = None
116+ bint iso_format = fmt is not None and format_is_iso(fmt)
117+ NPY_DATETIMEUNIT out_bestunit
118+ int out_local = 0 , out_tzoffset = 0
109119
110120 assert is_raise or is_ignore or is_coerce
111121
@@ -185,9 +195,50 @@ def array_strptime(
185195 elif is_datetime64_object(val):
186196 iresult[i] = get_datetime64_nanos(val, NPY_FR_ns)
187197 continue
198+ elif (
199+ (is_integer_object(val) or is_float_object(val))
200+ and (val != val or val == NPY_NAT)
201+ ):
202+ iresult[i] = NPY_NAT
203+ continue
188204 else :
189205 val = str (val)
190206
207+ if (iso_format and not (fmt == " %Y%m%d " and len (val) != 8 )):
208+ # There is a fast-path for ISO8601-formatted strings.
209+ # BUT for %Y%m%d, it only works if the string is 8-digits long.
210+ string_to_dts_failed = string_to_dts(
211+ val, & dts, & out_bestunit, & out_local,
212+ & out_tzoffset, False , fmt, exact
213+ )
214+ if string_to_dts_failed:
215+ # An error at this point is a _parsing_ error
216+ # specifically _not_ OutOfBoundsDatetime
217+ if is_coerce:
218+ iresult[i] = NPY_NAT
219+ continue
220+ raise ValueError (
221+ f" time data \" {val}\" at position {i} doesn't "
222+ f" match format \" {fmt}\" "
223+ )
224+ # No error reported by string_to_dts, pick back up
225+ # where we left off
226+ value = npy_datetimestruct_to_datetime(NPY_FR_ns, & dts)
227+ if out_local == 1 :
228+ # Store the out_tzoffset in seconds
229+ # since we store the total_seconds of
230+ # dateutil.tz.tzoffset objects
231+ # out_tzoffset_vals.add(out_tzoffset * 60.)
232+ tz = timezone(timedelta(minutes = out_tzoffset))
233+ result_timezone[i] = tz
234+ # value = tz_localize_to_utc_single(value, tz)
235+ out_local = 0
236+ out_tzoffset = 0
237+ iresult[i] = value
238+ check_dts_bounds(& dts)
239+
240+ continue
241+
191242 # exact matching
192243 if exact:
193244 found = format_regex.match(val)
0 commit comments