@@ -69,7 +69,9 @@ This file implements string parsing and creation for NumPy datetime.
6969int parse_iso_8601_datetime (const char * str , int len , int want_exc ,
7070 npy_datetimestruct * out ,
7171 NPY_DATETIMEUNIT * out_bestunit ,
72- int * out_local , int * out_tzoffset ) {
72+ int * out_local , int * out_tzoffset ,
73+ char * inferred_format , int * format_len ) {
74+ int fmt_idx = 0 ;
7375 int year_leap = 0 ;
7476 int i , numdigits ;
7577 const char * substr ;
@@ -104,6 +106,8 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
104106 while (sublen > 0 && isspace (* substr )) {
105107 ++ substr ;
106108 -- sublen ;
109+ inferred_format [fmt_idx ] = ' ' ;
110+ ++ fmt_idx ;
107111 }
108112
109113 /* Leading '-' sign for negative year */
@@ -125,6 +129,10 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
125129
126130 substr += 4 ;
127131 sublen -= 4 ;
132+ inferred_format [fmt_idx ] = '%' ;
133+ ++ fmt_idx ;
134+ inferred_format [fmt_idx ] = 'Y' ;
135+ ++ fmt_idx ;
128136 }
129137
130138 /* Negate the year if necessary */
@@ -156,6 +164,8 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
156164 ymd_sep = valid_ymd_sep [i ];
157165 ++ substr ;
158166 -- sublen ;
167+ inferred_format [fmt_idx ] = ymd_sep ;
168+ ++ fmt_idx ;
159169 /* Cannot have trailing separator */
160170 if (sublen == 0 || !isdigit (* substr )) {
161171 goto parse_error ;
@@ -183,6 +193,11 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
183193 goto error ;
184194 }
185195
196+ inferred_format [fmt_idx ] = '%' ;
197+ ++ fmt_idx ;
198+ inferred_format [fmt_idx ] = 'm' ;
199+ ++ fmt_idx ;
200+
186201 /* Next character must be the separator, start of day, or end of string */
187202 if (sublen == 0 ) {
188203 bestunit = NPY_FR_M ;
@@ -201,6 +216,8 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
201216 if (* substr != ymd_sep || sublen == 1 ) {
202217 goto parse_error ;
203218 }
219+ inferred_format [fmt_idx ] = * substr ;
220+ ++ fmt_idx ;
204221 ++ substr ;
205222 -- sublen ;
206223 }
@@ -230,6 +247,11 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
230247 goto error ;
231248 }
232249
250+ inferred_format [fmt_idx ] = '%' ;
251+ ++ fmt_idx ;
252+ inferred_format [fmt_idx ] = 'd' ;
253+ ++ fmt_idx ;
254+
233255 /* Next character must be a 'T', ' ', or end of string */
234256 if (sublen == 0 ) {
235257 if (out_local != NULL ) {
@@ -242,6 +264,8 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
242264 if ((* substr != 'T' && * substr != ' ' ) || sublen == 1 ) {
243265 goto parse_error ;
244266 }
267+ inferred_format [fmt_idx ] = * substr ;
268+ ++ fmt_idx ;
245269 ++ substr ;
246270 -- sublen ;
247271
@@ -269,6 +293,11 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
269293 }
270294 }
271295
296+ inferred_format [fmt_idx ] = '%' ;
297+ ++ fmt_idx ;
298+ inferred_format [fmt_idx ] = 'H' ;
299+ ++ fmt_idx ;
300+
272301 /* Next character must be a ':' or the end of the string */
273302 if (sublen == 0 ) {
274303 if (!hour_was_2_digits ) {
@@ -279,6 +308,8 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
279308 }
280309
281310 if (* substr == ':' ) {
311+ inferred_format [fmt_idx ] = ':' ;
312+ ++ fmt_idx ;
282313 has_hms_sep = 1 ;
283314 ++ substr ;
284315 -- sublen ;
@@ -315,6 +346,11 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
315346 goto parse_error ;
316347 }
317348
349+ inferred_format [fmt_idx ] = '%' ;
350+ ++ fmt_idx ;
351+ inferred_format [fmt_idx ] = 'M' ;
352+ ++ fmt_idx ;
353+
318354 if (sublen == 0 ) {
319355 bestunit = NPY_FR_m ;
320356 goto finish ;
@@ -323,6 +359,8 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
323359 /* If we make it through this condition block, then the next
324360 * character is a digit. */
325361 if (has_hms_sep && * substr == ':' ) {
362+ inferred_format [fmt_idx ] = ':' ;
363+ ++ fmt_idx ;
326364 ++ substr ;
327365 -- sublen ;
328366 /* Cannot have a trailing ':' */
@@ -356,15 +394,27 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
356394 goto parse_error ;
357395 }
358396
397+ inferred_format [fmt_idx ] = '%' ;
398+ ++ fmt_idx ;
399+ inferred_format [fmt_idx ] = 'S' ;
400+ ++ fmt_idx ;
401+
359402 /* Next character may be a '.' indicating fractional seconds */
360403 if (sublen > 0 && * substr == '.' ) {
361404 ++ substr ;
362405 -- sublen ;
406+ inferred_format [fmt_idx ] = '.' ;
407+ ++ fmt_idx ;
363408 } else {
364409 bestunit = NPY_FR_s ;
365410 goto parse_timezone ;
366411 }
367412
413+ inferred_format [fmt_idx ] = '%' ;
414+ ++ fmt_idx ;
415+ inferred_format [fmt_idx ] = 'f' ;
416+ ++ fmt_idx ;
417+
368418 /* PARSE THE MICROSECONDS (0 to 6 digits) */
369419 numdigits = 0 ;
370420 for (i = 0 ; i < 6 ; ++ i ) {
@@ -430,6 +480,8 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
430480 while (sublen > 0 && isspace (* substr )) {
431481 ++ substr ;
432482 -- sublen ;
483+ inferred_format [fmt_idx ] = ' ' ;
484+ ++ fmt_idx ;
433485 }
434486
435487 if (sublen == 0 ) {
@@ -439,6 +491,10 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
439491
440492 /* UTC specifier */
441493 if (* substr == 'Z' ) {
494+ inferred_format [fmt_idx ] = '%' ;
495+ ++ fmt_idx ;
496+ inferred_format [fmt_idx ] = 'Z' ;
497+ ++ fmt_idx ;
442498 /* "Z" should be equivalent to tz offset "+00:00" */
443499 if (out_local != NULL ) {
444500 * out_local = 1 ;
@@ -455,6 +511,10 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
455511 -- sublen ;
456512 }
457513 } else if (* substr == '-' || * substr == '+' ) {
514+ inferred_format [fmt_idx ] = '%' ;
515+ ++ fmt_idx ;
516+ inferred_format [fmt_idx ] = 'z' ;
517+ ++ fmt_idx ;
458518 /* Time zone offset */
459519 int offset_neg = 0 , offset_hour = 0 , offset_minute = 0 ;
460520
@@ -538,6 +598,8 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
538598 while (sublen > 0 && isspace (* substr )) {
539599 ++ substr ;
540600 -- sublen ;
601+ inferred_format [fmt_idx ] = ' ' ;
602+ ++ fmt_idx ;
541603 }
542604
543605 if (sublen != 0 ) {
@@ -548,6 +610,7 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc,
548610 if (out_bestunit != NULL ) {
549611 * out_bestunit = bestunit ;
550612 }
613+ * format_len = fmt_idx ;
551614 return 0 ;
552615
553616parse_error :
0 commit comments