-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
BUG: pandas.to_datetime() does not respect exact format string with ISO8601 #49333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 19 commits
45f82c3
e473adb
a6ea6d0
8fede1f
2e21e71
afc4d96
12721b0
0531967
a571753
e814a2e
19c34f8
70fb820
eb50dfb
ac61ac5
0dd7407
4d35ea7
3acfdf6
f3060c9
7310e13
b18ade7
3ceb1ee
bde5ef9
080f018
031e0e3
01e8bd1
c1e6bc2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -69,7 +69,8 @@ This file implements string parsing and creation for NumPy datetime. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int parse_iso_8601_datetime(const char *str, int len, int want_exc, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
npy_datetimestruct *out, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NPY_DATETIMEUNIT *out_bestunit, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int *out_local, int *out_tzoffset) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int *out_local, int *out_tzoffset, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const char* format, int format_len, int exact) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
WillAyd marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int year_leap = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int i, numdigits; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const char *substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -104,19 +105,30 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while (sublen > 0 && isspace(*substr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think clang-format will automatically enforce this style for you There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried
so I've gone with that for now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think this control flow would work more universally and avoid logic pitfalls / segfaults (see other comment) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != ' ') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* Leading '-' sign for negative year */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (*substr == '-') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '-') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (sublen == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* PARSE THE YEAR (4 digits) */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 2 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Current code has undefined behavior and a possible segfault if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In practice that shouldn't be possible - this function's only used internally, and pandas/pandas/_libs/tslibs/parsing.pyx Lines 886 to 903 in 57d8d3a
would return false if the format were for example There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea what you will find with C is that you want to be extremely explicit. Even if it's not possible today, if someone refactors the code and it does happen things become very difficult to debug. Our error checking in some of our extensions is really loose, which is why our internal code is relatively difficult to refactor |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '%') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != 'Y') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) format_len -= 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
out->year = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (sublen >= 4 && isdigit(substr[0]) && isdigit(substr[1]) && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
isdigit(substr[2]) && isdigit(substr[3])) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -139,6 +151,9 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (out_local != NULL) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*out_local = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bestunit = NPY_FR_Y; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto finish; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -156,13 +171,20 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ymd_sep = valid_ymd_sep[i]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != ymd_sep) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* Cannot have trailing separator */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (sublen == 0 || !isdigit(*substr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* PARSE THE MONTH */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 2 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '%') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != 'm') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) format_len -= 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* First digit required */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
out->month = (*substr - '0'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -190,6 +212,9 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!has_ymd_sep) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (out_local != NULL) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*out_local = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -203,9 +228,16 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != ymd_sep) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* PARSE THE DAY */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 2 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '%') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != 'd') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) format_len -= 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* First digit required */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!isdigit(*substr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -235,17 +267,27 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (out_local != NULL) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*out_local = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MarcoGorelli marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bestunit = NPY_FR_D; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto finish; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ((*substr != 'T' && *substr != ' ') || sublen == 1) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != *substr) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* PARSE THE HOURS */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 2 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '%') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != 'H') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) format_len -= 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* First digit required */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!isdigit(*substr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -274,6 +316,9 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!hour_was_2_digits) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bestunit = NPY_FR_h; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto finish; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -286,6 +331,9 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (sublen == 0 || !isdigit(*substr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != ':') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else if (!isdigit(*substr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!hour_was_2_digits) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -294,6 +342,10 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* PARSE THE MINUTES */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 2 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '%') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != 'M') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) format_len -= 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* First digit required */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
out->min = (*substr - '0'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -317,12 +369,18 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (sublen == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bestunit = NPY_FR_m; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto finish; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* If we make it through this condition block, then the next | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* character is a digit. */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (has_hms_sep && *substr == ':') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != ':') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* Cannot have a trailing ':' */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -335,6 +393,10 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* PARSE THE SECONDS */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 2 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '%') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != 'S') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) format_len -= 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* First digit required */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
out->sec = (*substr - '0'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -360,12 +422,19 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (sublen > 0 && *substr == '.') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '.') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bestunit = NPY_FR_s; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_timezone; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* PARSE THE MICROSECONDS (0 to 6 digits) */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 2 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '%') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != 'f') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) format_len -= 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
numdigits = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (i = 0; i < 6; ++i) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
out->us *= 10; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -430,15 +499,25 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while (sublen > 0 && isspace(*substr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != ' ') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (sublen == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Unlike NumPy, treating no time zone as naive | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto finish; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* UTC specifier */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (*substr == 'Z') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 2 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '%') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != 'Z') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) format_len -= 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* "Z" should be equivalent to tz offset "+00:00" */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (out_local != NULL) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*out_local = 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -449,12 +528,19 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (sublen == 1) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto finish; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else if (*substr == '-' || *substr == '+') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 2 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != '%') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != 'z') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) format_len -= 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* Time zone offset */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int offset_neg = 0, offset_hour = 0, offset_minute = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -538,9 +624,12 @@ int parse_iso_8601_datetime(const char *str, int len, int want_exc, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while (sublen > 0 && isspace(*substr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++substr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
--sublen; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len < 1 && exact) goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len && *format++ != ' ') goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (format_len) --format_len; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (sublen != 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ((sublen != 0) || (format_len != 0)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goto parse_error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Orthogonal to this but if you want to work more with the C codebase I think we should just replace
get_c_string_buf_and_size
withPyUnicode_AsUTF8AndSize
directly; the former might have served a purpose with the Py2/3 transition but is just an unnecessary layer at this point