diff --git a/pandas/_libs/src/vendored/numpy/datetime/np_datetime.c b/pandas/_libs/src/vendored/numpy/datetime/np_datetime.c index 934c54fafb634..f854f7b9210d8 100644 --- a/pandas/_libs/src/vendored/numpy/datetime/np_datetime.c +++ b/pandas/_libs/src/vendored/numpy/datetime/np_datetime.c @@ -710,355 +710,121 @@ void pandas_datetime_to_datetimestruct(npy_datetime dt, NPY_DATETIMEUNIT base, void pandas_timedelta_to_timedeltastruct(npy_timedelta td, NPY_DATETIMEUNIT base, pandas_timedeltastruct *out) { - npy_int64 frac; - npy_int64 sfrac; - npy_int64 ifrac; - int sign; - npy_int64 per_day; - npy_int64 per_sec; - /* Initialize the output to all zeros */ memset(out, 0, sizeof(pandas_timedeltastruct)); - switch (base) { - case NPY_FR_ns: - - per_day = 86400000000000LL; - per_sec = 1000LL * 1000LL * 1000LL; - - // put frac in seconds - if (td < 0 && td % per_sec != 0) - frac = td / per_sec - 1; - else - frac = td / per_sec; - - if (frac < 0) { - sign = -1; - - // even fraction - if ((-frac % 86400LL) != 0) { - out->days = -frac / 86400LL + 1; - frac += 86400LL * out->days; - } else { - frac = -frac; - } - } else { - sign = 1; - out->days = 0; - } - - if (frac >= 86400) { - out->days += frac / 86400LL; - frac -= out->days * 86400LL; - } - - if (frac >= 3600) { - out->hrs = (npy_int32)(frac / 3600LL); - frac -= out->hrs * 3600LL; - } else { - out->hrs = 0; - } - - if (frac >= 60) { - out->min = (npy_int32)(frac / 60LL); - frac -= out->min * 60LL; - } else { - out->min = 0; - } - - if (frac >= 0) { - out->sec = (npy_int32)frac; - frac -= out->sec; - } else { - out->sec = 0; - } + const npy_int64 sec_per_hour = 3600; + const npy_int64 sec_per_min = 60; - sfrac = (out->hrs * 3600LL + out->min * 60LL + out->sec) * per_sec; - - if (sign < 0) - out->days = -out->days; - - ifrac = td - (out->days * per_day + sfrac); - - if (ifrac != 0) { - out->ms = (npy_int32)(ifrac / (1000LL * 1000LL)); - ifrac -= out->ms * 1000LL * 1000LL; - out->us = (npy_int32)(ifrac / 1000LL); - ifrac -= out->us * 1000LL; - out->ns = (npy_int32)ifrac; - } else { - out->ms = 0; - out->us = 0; - out->ns = 0; - } + switch (base) { + case NPY_FR_W: + out->days = 7 * td; break; - - case NPY_FR_us: - - per_day = 86400000000LL; - per_sec = 1000LL * 1000LL; - - // put frac in seconds - if (td < 0 && td % per_sec != 0) - frac = td / per_sec - 1; - else - frac = td / per_sec; - - if (frac < 0) { - sign = -1; - - // even fraction - if ((-frac % 86400LL) != 0) { - out->days = -frac / 86400LL + 1; - frac += 86400LL * out->days; - } else { - frac = -frac; - } - } else { - sign = 1; - out->days = 0; - } - - if (frac >= 86400) { - out->days += frac / 86400LL; - frac -= out->days * 86400LL; - } - - if (frac >= 3600) { - out->hrs = (npy_int32)(frac / 3600LL); - frac -= out->hrs * 3600LL; - } else { - out->hrs = 0; - } - - if (frac >= 60) { - out->min = (npy_int32)(frac / 60LL); - frac -= out->min * 60LL; - } else { - out->min = 0; - } - - if (frac >= 0) { - out->sec = (npy_int32)frac; - frac -= out->sec; - } else { - out->sec = 0; - } - - sfrac = (out->hrs * 3600LL + out->min * 60LL + out->sec) * per_sec; - - if (sign < 0) - out->days = -out->days; - - ifrac = td - (out->days * per_day + sfrac); - - if (ifrac != 0) { - out->ms = (npy_int32)(ifrac / 1000LL); - ifrac -= out->ms * 1000LL; - out->us = (npy_int32)(ifrac / 1L); - ifrac -= out->us * 1L; - out->ns = (npy_int32)ifrac; - } else { - out->ms = 0; - out->us = 0; - out->ns = 0; - } + case NPY_FR_D: + out->days = td; break; - + case NPY_FR_h: + out->days = td / 24LL; + td -= out->days * 24LL; + out->hrs = (npy_int32)td; + break; + case NPY_FR_m: + out->days = td / 1440LL; + td -= out->days * 1440LL; + out->hrs = (npy_int32)(td / 60LL); + td -= out->hrs * 60LL; + out->min = (npy_int32)td; + break; + case NPY_FR_s: case NPY_FR_ms: - - per_day = 86400000LL; - per_sec = 1000LL; - - // put frac in seconds - if (td < 0 && td % per_sec != 0) - frac = td / per_sec - 1; - else - frac = td / per_sec; - - if (frac < 0) { - sign = -1; - - // even fraction - if ((-frac % 86400LL) != 0) { - out->days = -frac / 86400LL + 1; - frac += 86400LL * out->days; - } else { - frac = -frac; - } - } else { - sign = 1; - out->days = 0; - } - - if (frac >= 86400) { - out->days += frac / 86400LL; - frac -= out->days * 86400LL; - } - - if (frac >= 3600) { - out->hrs = (npy_int32)(frac / 3600LL); - frac -= out->hrs * 3600LL; - } else { - out->hrs = 0; - } - - if (frac >= 60) { - out->min = (npy_int32)(frac / 60LL); - frac -= out->min * 60LL; - } else { - out->min = 0; - } - - if (frac >= 0) { - out->sec = (npy_int32)frac; - frac -= out->sec; - } else { - out->sec = 0; - } - - sfrac = (out->hrs * 3600LL + out->min * 60LL + out->sec) * per_sec; - - if (sign < 0) - out->days = -out->days; - - ifrac = td - (out->days * per_day + sfrac); - - if (ifrac != 0) { - out->ms = (npy_int32)ifrac; - out->us = 0; - out->ns = 0; + case NPY_FR_us: + case NPY_FR_ns: { + const npy_int64 sec_per_day = 86400; + npy_int64 per_sec; + if (base == NPY_FR_s) { + per_sec = 1; + } else if (base == NPY_FR_ms) { + per_sec = 1000; + } else if (base == NPY_FR_us) { + per_sec = 1000000; } else { - out->ms = 0; - out->us = 0; - out->ns = 0; + per_sec = 1000000000; } - break; - - case NPY_FR_s: - // special case where we can simplify many expressions bc per_sec=1 - - per_day = 86400LL; - per_sec = 1L; + const npy_int64 per_day = sec_per_day * per_sec; + npy_int64 frac; // put frac in seconds if (td < 0 && td % per_sec != 0) frac = td / per_sec - 1; else frac = td / per_sec; + const int sign = frac < 0 ? -1 : 1; if (frac < 0) { - sign = -1; - // even fraction - if ((-frac % 86400LL) != 0) { - out->days = -frac / 86400LL + 1; - frac += 86400LL * out->days; + if ((-frac % sec_per_day) != 0) { + out->days = -frac / sec_per_day + 1; + frac += sec_per_day * out->days; } else { frac = -frac; } - } else { - sign = 1; - out->days = 0; } - if (frac >= 86400) { - out->days += frac / 86400LL; - frac -= out->days * 86400LL; + if (frac >= sec_per_day) { + out->days += frac / sec_per_day; + frac -= out->days * sec_per_day; } - if (frac >= 3600) { - out->hrs = (npy_int32)(frac / 3600LL); - frac -= out->hrs * 3600LL; - } else { - out->hrs = 0; + if (frac >= sec_per_hour) { + out->hrs = (npy_int32)(frac / sec_per_hour); + frac -= out->hrs * sec_per_hour; } - if (frac >= 60) { - out->min = (npy_int32)(frac / 60LL); - frac -= out->min * 60LL; - } else { - out->min = 0; + if (frac >= sec_per_min) { + out->min = (npy_int32)(frac / sec_per_min); + frac -= out->min * sec_per_min; } if (frac >= 0) { out->sec = (npy_int32)frac; frac -= out->sec; - } else { - out->sec = 0; } - sfrac = (out->hrs * 3600LL + out->min * 60LL + out->sec) * per_sec; - if (sign < 0) out->days = -out->days; - ifrac = td - (out->days * per_day + sfrac); - - if (ifrac != 0) { - out->ms = 0; - out->us = 0; - out->ns = 0; - } else { - out->ms = 0; - out->us = 0; - out->ns = 0; + if (base > NPY_FR_s) { + const npy_int64 sfrac = + (out->hrs * sec_per_hour + out->min * sec_per_min + out->sec) * + per_sec; + + npy_int64 ifrac = td - (out->days * per_day + sfrac); + + if (base == NPY_FR_ms) { + out->ms = (npy_int32)ifrac; + } else if (base == NPY_FR_us) { + out->ms = (npy_int32)(ifrac / 1000LL); + ifrac = ifrac % 1000LL; + out->us = (npy_int32)ifrac; + } else if (base == NPY_FR_ns) { + out->ms = (npy_int32)(ifrac / (1000LL * 1000LL)); + ifrac = ifrac % (1000LL * 1000LL); + out->us = (npy_int32)(ifrac / 1000LL); + ifrac = ifrac % 1000LL; + out->ns = (npy_int32)ifrac; + } } - break; - - case NPY_FR_m: - - out->days = td / 1440LL; - td -= out->days * 1440LL; - out->hrs = (npy_int32)(td / 60LL); - td -= out->hrs * 60LL; - out->min = (npy_int32)td; - - out->sec = 0; - out->ms = 0; - out->us = 0; - out->ns = 0; - break; - - case NPY_FR_h: - out->days = td / 24LL; - td -= out->days * 24LL; - out->hrs = (npy_int32)td; - - out->min = 0; - out->sec = 0; - out->ms = 0; - out->us = 0; - out->ns = 0; - break; - - case NPY_FR_D: - out->days = td; - out->hrs = 0; - out->min = 0; - out->sec = 0; - out->ms = 0; - out->us = 0; - out->ns = 0; - break; - - case NPY_FR_W: - out->days = 7 * td; - out->hrs = 0; - out->min = 0; - out->sec = 0; - out->ms = 0; - out->us = 0; - out->ns = 0; - break; + } break; default: PyErr_SetString(PyExc_RuntimeError, "NumPy timedelta metadata is corrupted with " "invalid base unit"); + break; } - out->seconds = out->hrs * 3600 + out->min * 60 + out->sec; + out->seconds = + (npy_int32)(out->hrs * sec_per_hour + out->min * sec_per_min + out->sec); out->microseconds = out->ms * 1000 + out->us; out->nanoseconds = out->ns; }