From f2971e47cf9f0bc11026fc75473c85e893cbd5e0 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Wed, 29 Nov 2017 08:51:03 -0800 Subject: [PATCH 1/2] remove unused arguments from np_datetime_strings --- pandas/_libs/src/datetime.pxd | 16 +- .../_libs/src/datetime/np_datetime_strings.c | 235 +----------------- .../_libs/src/datetime/np_datetime_strings.h | 24 +- pandas/_libs/src/ujson/python/objToJSON.c | 3 +- 4 files changed, 19 insertions(+), 259 deletions(-) diff --git a/pandas/_libs/src/datetime.pxd b/pandas/_libs/src/datetime.pxd index 6e5d8b82c118f..d919fca09c006 100644 --- a/pandas/_libs/src/datetime.pxd +++ b/pandas/_libs/src/datetime.pxd @@ -7,9 +7,6 @@ from cpython cimport PyUnicode_Check, PyUnicode_AsASCIIString cdef extern from "numpy/ndarrayobject.h": ctypedef int64_t npy_datetime -cdef extern from "numpy/npy_common.h": - ctypedef unsigned char npy_bool - cdef extern from "datetime/np_datetime.h": ctypedef enum PANDAS_DATETIMEUNIT: PANDAS_FR_Y @@ -37,11 +34,9 @@ cdef extern from "datetime/np_datetime.h": cdef extern from "datetime/np_datetime_strings.h": - int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, + int parse_iso_8601_datetime(char *str, int len, pandas_datetimestruct *out, - int *out_local, int *out_tzoffset, - PANDAS_DATETIMEUNIT *out_bestunit, - npy_bool *out_special) + int *out_local, int *out_tzoffset) cdef inline int _string_to_dts(object val, pandas_datetimestruct* dts, int* out_local, int* out_tzoffset) except? -1: @@ -62,11 +57,8 @@ cdef inline int _cstring_to_dts(char *val, int length, pandas_datetimestruct* dts, int* out_local, int* out_tzoffset) except? -1: cdef: - npy_bool special - PANDAS_DATETIMEUNIT out_bestunit int result - result = parse_iso_8601_datetime(val, length, PANDAS_FR_ns, - dts, out_local, out_tzoffset, - &out_bestunit, &special) + result = parse_iso_8601_datetime(val, length, + dts, out_local, out_tzoffset) return result diff --git a/pandas/_libs/src/datetime/np_datetime_strings.c b/pandas/_libs/src/datetime/np_datetime_strings.c index 1ff4f08cf3c9d..713d50c0f808b 100644 --- a/pandas/_libs/src/datetime/np_datetime_strings.c +++ b/pandas/_libs/src/datetime/np_datetime_strings.c @@ -36,24 +36,6 @@ This file implements string parsing and creation for NumPy datetime. /* Platform-specific time_t typedef */ typedef time_t NPY_TIME_T; -/* We *do* want these symbols, but for Cython, not for C. - Fine in Mac OSX, but Linux complains. - -static void _suppress_unused_variable_warning(void) { - int x = days_per_month_table[0][0]; - x = x; - - int y = _month_offset[0][0]; - y = y; - - char *z = _datetime_strings[0]; - z = z; -} */ - -/* Exported as DATETIMEUNITS in multiarraymodule.c */ -static char *_datetime_strings[PANDAS_DATETIME_NUMUNITS] = { - "Y", "M", "W", "D", "h", "m", "s", "ms", "us", "ns", "ps", "fs", "as", -}; /* * Wraps `localtime` functionality for multiple platforms. This * converts a time value to a time structure in the local timezone. @@ -100,72 +82,6 @@ static int get_localtime(NPY_TIME_T *ts, struct tm *tms) { } -/* - * Converts a datetimestruct in UTC to a datetimestruct in local time, - * also returning the timezone offset applied. - * - * Returns 0 on success, -1 on failure. - */ -static int convert_datetimestruct_utc_to_local( - pandas_datetimestruct *out_dts_local, const pandas_datetimestruct *dts_utc, - int *out_timezone_offset) { - NPY_TIME_T rawtime = 0, localrawtime; - struct tm tm_; - npy_int64 year_correction = 0; - - /* Make a copy of the input 'dts' to modify */ - *out_dts_local = *dts_utc; - - /* HACK: Use a year < 2038 for later years for small time_t */ - if (sizeof(NPY_TIME_T) == 4 && out_dts_local->year >= 2038) { - if (is_leapyear(out_dts_local->year)) { - /* 2036 is a leap year */ - year_correction = out_dts_local->year - 2036; - out_dts_local->year -= year_correction; - } else { - /* 2037 is not a leap year */ - year_correction = out_dts_local->year - 2037; - out_dts_local->year -= year_correction; - } - } - - /* - * Convert everything in 'dts' to a time_t, to minutes precision. - * This is POSIX time, which skips leap-seconds, but because - * we drop the seconds value from the pandas_datetimestruct, everything - * is ok for this operation. - */ - rawtime = (time_t)get_datetimestruct_days(out_dts_local) * 24 * 60 * 60; - rawtime += dts_utc->hour * 60 * 60; - rawtime += dts_utc->min * 60; - - /* localtime converts a 'time_t' into a local 'struct tm' */ - if (get_localtime(&rawtime, &tm_) < 0) { - return -1; - } - - /* Copy back all the values except seconds */ - out_dts_local->min = tm_.tm_min; - out_dts_local->hour = tm_.tm_hour; - out_dts_local->day = tm_.tm_mday; - out_dts_local->month = tm_.tm_mon + 1; - out_dts_local->year = tm_.tm_year + 1900; - - /* Extract the timezone offset that was applied */ - rawtime /= 60; - localrawtime = (time_t)get_datetimestruct_days(out_dts_local) * 24 * 60; - localrawtime += out_dts_local->hour * 60; - localrawtime += out_dts_local->min; - - *out_timezone_offset = localrawtime - rawtime; - - /* Reapply the year 2038 year correction HACK */ - out_dts_local->year += year_correction; - - return 0; -} - - /* * Parses (almost) standard ISO 8601 date strings. The differences are: * @@ -182,8 +98,6 @@ static int convert_datetimestruct_utc_to_local( * omitted, each component must be 2 digits if it appears. (GH-10041) * * 'str' must be a NULL-terminated string, and 'len' must be its length. - * 'unit' should contain -1 if the unit is unknown, or the unit - * which will be used if it is. * * 'out' gets filled with the parsed date-time. * 'out_local' gets set to 1 if the parsed time contains timezone, @@ -193,24 +107,15 @@ static int convert_datetimestruct_utc_to_local( * to 0 otherwise. The values 'now' and 'today' don't get counted * as local, and neither do UTC +/-#### timezone offsets, because * they aren't using the computer's local timezone offset. - * 'out_bestunit' gives a suggested unit based on the amount of - * resolution provided in the string, or -1 for NaT. - * 'out_special' gets set to 1 if the parsed time was 'today', - * 'now', or ''/'NaT'. For 'today', the unit recommended is - * 'D', for 'now', the unit recommended is 's', and for 'NaT' - * the unit recommended is 'Y'. * * Returns 0 on success, -1 on failure. */ -int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, +int parse_iso_8601_datetime(char *str, int len, pandas_datetimestruct *out, - int *out_local, int *out_tzoffset, - PANDAS_DATETIMEUNIT *out_bestunit, - npy_bool *out_special) { + int *out_local, int *out_tzoffset) { int year_leap = 0; int i, numdigits; char *substr, sublen; - PANDAS_DATETIMEUNIT bestunit; /* If year-month-day are separated by a valid separator, * months/days without leading zeroes will be parsed @@ -256,8 +161,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, out->month = tm_.tm_mon + 1; out->day = tm_.tm_mday; - bestunit = PANDAS_FR_D; - /* * Indicate that this was a special value, and * is a date (unit 'D'). @@ -265,12 +168,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, if (out_local != NULL) { *out_local = 0; } - if (out_bestunit != NULL) { - *out_bestunit = bestunit; - } - if (out_special != NULL) { - *out_special = 1; - } return 0; } @@ -287,8 +184,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, meta.base = PANDAS_FR_s; meta.num = 1; - bestunit = PANDAS_FR_s; - /* * Indicate that this was a special value, and * use 's' because the time() function has resolution @@ -297,21 +192,10 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, if (out_local != NULL) { *out_local = 0; } - if (out_bestunit != NULL) { - *out_bestunit = bestunit; - } - if (out_special != NULL) { - *out_special = 1; - } return convert_datetime_to_datetimestruct(&meta, rawtime, out); } - /* Anything else isn't a special value */ - if (out_special != NULL) { - *out_special = 0; - } - substr = str; sublen = len; @@ -354,7 +238,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, if (out_local != NULL) { *out_local = 0; } - bestunit = PANDAS_FR_Y; goto finish; } @@ -405,7 +288,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, if (out_local != NULL) { *out_local = 0; } - bestunit = PANDAS_FR_M; goto finish; } @@ -446,7 +328,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, if (out_local != NULL) { *out_local = 0; } - bestunit = PANDAS_FR_D; goto finish; } @@ -482,7 +363,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, if (!hour_was_2_digits) { goto parse_error; } - bestunit = PANDAS_FR_h; goto finish; } @@ -498,7 +378,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, if (!hour_was_2_digits) { goto parse_error; } - bestunit = PANDAS_FR_h; goto parse_timezone; } @@ -522,7 +401,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, } if (sublen == 0) { - bestunit = PANDAS_FR_m; goto finish; } @@ -537,7 +415,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, } } else if (!has_hms_sep && isdigit(*substr)) { } else { - bestunit = PANDAS_FR_m; goto parse_timezone; } @@ -565,7 +442,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, ++substr; --sublen; } else { - bestunit = PANDAS_FR_s; goto parse_timezone; } @@ -582,11 +458,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, } if (sublen == 0 || !isdigit(*substr)) { - if (numdigits > 3) { - bestunit = PANDAS_FR_us; - } else { - bestunit = PANDAS_FR_ms; - } goto parse_timezone; } @@ -603,11 +474,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, } if (sublen == 0 || !isdigit(*substr)) { - if (numdigits > 3) { - bestunit = PANDAS_FR_ps; - } else { - bestunit = PANDAS_FR_ns; - } goto parse_timezone; } @@ -623,12 +489,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, } } - if (numdigits > 3) { - bestunit = PANDAS_FR_as; - } else { - bestunit = PANDAS_FR_fs; - } - parse_timezone: /* trim any whitepsace between time/timeezone */ while (sublen > 0 && isspace(*substr)) { @@ -745,10 +605,6 @@ int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, } finish: - if (out_bestunit != NULL) { - *out_bestunit = bestunit; - } - return 0; parse_error: @@ -819,38 +675,24 @@ int get_datetime_iso_8601_strlen(int local, PANDAS_DATETIMEUNIT base) { /* * Converts an pandas_datetimestruct to an (almost) ISO 8601 - * NULL-terminated string. If the string fits in the space exactly, - * it leaves out the NULL terminator and returns success. + * NULL-terminated string using timezone Z (UTC). If the string fits in + * the space exactly, it leaves out the NULL terminator and returns success. * * The differences from ISO 8601 are the 'NaT' string, and * the number of year digits is >= 4 instead of strictly 4. * - * If 'local' is non-zero, it produces a string in local time with - * a +-#### timezone offset, otherwise it uses timezone Z (UTC). - * * 'base' restricts the output to that unit. Set 'base' to * -1 to auto-detect a base after which all the values are zero. * - * 'tzoffset' is used if 'local' is enabled, and 'tzoffset' is - * set to a value other than -1. This is a manual override for - * the local time zone to use, as an offset in minutes. - * * Returns 0 on success, -1 on failure (for example if the output * string was too short). */ int make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, - int local, PANDAS_DATETIMEUNIT base, int tzoffset) { - pandas_datetimestruct dts_local; - int timezone_offset = 0; + PANDAS_DATETIMEUNIT base) { char *substr = outstr, sublen = outlen; int tmplen; - /* Only do local time within a reasonable year range */ - if ((dts->year <= 1800 || dts->year >= 10000) && tzoffset == -1) { - local = 0; - } - /* * Print weeks with the same precision as days. * @@ -861,26 +703,6 @@ int make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, base = PANDAS_FR_D; } - /* Use the C API to convert from UTC to local time */ - if (local && tzoffset == -1) { - if (convert_datetimestruct_utc_to_local(&dts_local, dts, - &timezone_offset) < 0) { - return -1; - } - - /* Set dts to point to our local time instead of the UTC time */ - dts = &dts_local; - } else if (local) { - // Use the manually provided tzoffset. - // Make a copy of the pandas_datetimestruct we can modify. - dts_local = *dts; - dts = &dts_local; - - /* Set and apply the required timezone offset */ - timezone_offset = tzoffset; - add_minutes_to_datetimestruct(dts, timezone_offset); - } - /* YEAR */ /* * Can't use PyOS_snprintf, because it always produces a '\0' @@ -1144,48 +966,13 @@ int make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, sublen -= 3; add_time_zone: - if (local) { - /* Add the +/- sign */ - if (sublen < 1) { - goto string_too_short; - } - if (timezone_offset < 0) { - substr[0] = '-'; - timezone_offset = -timezone_offset; - } else { - substr[0] = '+'; - } - substr += 1; - sublen -= 1; - - /* Add the timezone offset */ - if (sublen < 1) { - goto string_too_short; - } - substr[0] = (char)((timezone_offset / (10 * 60)) % 10 + '0'); - if (sublen < 2) { - goto string_too_short; - } - substr[1] = (char)((timezone_offset / 60) % 10 + '0'); - if (sublen < 3) { - goto string_too_short; - } - substr[2] = (char)(((timezone_offset % 60) / 10) % 10 + '0'); - if (sublen < 4) { - goto string_too_short; - } - substr[3] = (char)((timezone_offset % 60) % 10 + '0'); - substr += 4; - sublen -= 4; - } else { - /* UTC "Zulu" time */ - if (sublen < 1) { - goto string_too_short; - } - substr[0] = 'Z'; - substr += 1; - sublen -= 1; + /* UTC "Zulu" time */ + if (sublen < 1) { + goto string_too_short; } + substr[0] = 'Z'; + substr += 1; + sublen -= 1; /* Add a NULL terminator, and return */ if (sublen > 0) { diff --git a/pandas/_libs/src/datetime/np_datetime_strings.h b/pandas/_libs/src/datetime/np_datetime_strings.h index 4c248129b68c3..ef7fe200aa58e 100644 --- a/pandas/_libs/src/datetime/np_datetime_strings.h +++ b/pandas/_libs/src/datetime/np_datetime_strings.h @@ -38,8 +38,6 @@ This file implements string parsing and creation for NumPy datetime. * day according to local time) and "Now" (current time in UTC). * * 'str' must be a NULL-terminated string, and 'len' must be its length. - * 'unit' should contain -1 if the unit is unknown, or the unit - * which will be used if it is. * * 'out' gets filled with the parsed date-time. * 'out_local' gets whether returned value contains timezone. 0 for UTC, 1 for local time. @@ -48,23 +46,14 @@ This file implements string parsing and creation for NumPy datetime. * to 0 otherwise. The values 'now' and 'today' don't get counted * as local, and neither do UTC +/-#### timezone offsets, because * they aren't using the computer's local timezone offset. - * 'out_bestunit' gives a suggested unit based on the amount of - * resolution provided in the string, or -1 for NaT. - * 'out_special' gets set to 1 if the parsed time was 'today', - * 'now', or ''/'NaT'. For 'today', the unit recommended is - * 'D', for 'now', the unit recommended is 's', and for 'NaT' - * the unit recommended is 'Y'. * * Returns 0 on success, -1 on failure. */ int parse_iso_8601_datetime(char *str, int len, - PANDAS_DATETIMEUNIT unit, pandas_datetimestruct *out, int *out_local, - int *out_tzoffset, - PANDAS_DATETIMEUNIT *out_bestunit, - npy_bool *out_special); + int *out_tzoffset); /* * Provides a string length to use for converting datetime @@ -75,23 +64,16 @@ get_datetime_iso_8601_strlen(int local, PANDAS_DATETIMEUNIT base); /* * Converts an pandas_datetimestruct to an (almost) ISO 8601 - * NULL-terminated string. - * - * If 'local' is non-zero, it produces a string in local time with - * a +-#### timezone offset, otherwise it uses timezone Z (UTC). + * NULL-terminated string using timezone Z (UTC). * * 'base' restricts the output to that unit. Set 'base' to * -1 to auto-detect a base after which all the values are zero. * - * 'tzoffset' is used if 'local' is enabled, and 'tzoffset' is - * set to a value other than -1. This is a manual override for - * the local time zone to use, as an offset in minutes. - * * Returns 0 on success, -1 on failure (for example if the output * string was too short). */ int make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, - int local, PANDAS_DATETIMEUNIT base, int tzoffset); + PANDAS_DATETIMEUNIT base); #endif // PANDAS__LIBS_SRC_DATETIME_NP_DATETIME_STRINGS_H_ diff --git a/pandas/_libs/src/ujson/python/objToJSON.c b/pandas/_libs/src/ujson/python/objToJSON.c index c8a29cd949c3c..7856a762563f4 100644 --- a/pandas/_libs/src/ujson/python/objToJSON.c +++ b/pandas/_libs/src/ujson/python/objToJSON.c @@ -455,8 +455,7 @@ static void *PandasDateTimeStructToJSON(pandas_datetimestruct *dts, return NULL; } - if (!make_iso_8601_datetime(dts, GET_TC(tc)->cStr, *_outLen, 0, base, - -1)) { + if (!make_iso_8601_datetime(dts, GET_TC(tc)->cStr, *_outLen, base)) { PRINTMARK(); *_outLen = strlen(GET_TC(tc)->cStr); return GET_TC(tc)->cStr; From f6989456659a348d880ad10266edfac90c9dac3c Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Wed, 29 Nov 2017 13:17:50 -0800 Subject: [PATCH 2/2] cpplint fixup --- pandas/_libs/src/datetime/np_datetime_strings.c | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/_libs/src/datetime/np_datetime_strings.c b/pandas/_libs/src/datetime/np_datetime_strings.c index 713d50c0f808b..eeac8ca44b9b1 100644 --- a/pandas/_libs/src/datetime/np_datetime_strings.c +++ b/pandas/_libs/src/datetime/np_datetime_strings.c @@ -689,7 +689,6 @@ int get_datetime_iso_8601_strlen(int local, PANDAS_DATETIMEUNIT base) { */ int make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, PANDAS_DATETIMEUNIT base) { - char *substr = outstr, sublen = outlen; int tmplen;