Skip to content

Commit 632eabd

Browse files
committed
update nanoseconds_to_delta for large number
1 parent fd92889 commit 632eabd

File tree

1 file changed

+82
-1
lines changed

1 file changed

+82
-1
lines changed

Modules/_datetimemodule.c

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2340,7 +2340,88 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
23402340
static PyObject *
23412341
nanoseconds_to_delta(PyObject *pyns)
23422342
{
2343-
return new_delta(0, 0, 0, PyLong_AsLong(pyns), 1);
2343+
int d, s, us, ns_rem;
2344+
PyObject *py_total_us = NULL, *py_ns_rem_obj = NULL;
2345+
PyObject *py_total_s = NULL, *py_us_rem_obj = NULL;
2346+
PyObject *py_d_final = NULL, *py_s_rem_obj = NULL;
2347+
PyObject *PY_NS_PER_US_CONST = NULL;
2348+
PyObject *result = NULL;
2349+
PyObject *temp_tuple = NULL;
2350+
2351+
PyObject *current_mod = NULL;
2352+
datetime_state *st = GET_CURRENT_STATE(current_mod);
2353+
if (st == NULL) {
2354+
// GET_CURRENT_STATE already sets error if module import fails
2355+
return NULL;
2356+
}
2357+
2358+
PY_NS_PER_US_CONST = PyLong_FromLong(1000L);
2359+
if (PY_NS_PER_US_CONST == NULL) {
2360+
goto Done;
2361+
}
2362+
2363+
// Nanoseconds to total_microseconds and ns_remainder
2364+
temp_tuple = checked_divmod(pyns, PY_NS_PER_US_CONST);
2365+
if (temp_tuple == NULL) {
2366+
goto Done;
2367+
}
2368+
py_total_us = Py_NewRef(PyTuple_GET_ITEM(temp_tuple, 0));
2369+
py_ns_rem_obj = Py_NewRef(PyTuple_GET_ITEM(temp_tuple, 1));
2370+
Py_DECREF(temp_tuple);
2371+
temp_tuple = NULL;
2372+
2373+
ns_rem = PyLong_AsInt(py_ns_rem_obj);
2374+
if (ns_rem == -1 && PyErr_Occurred()) {
2375+
goto Done;
2376+
}
2377+
2378+
// Total_microseconds to total_seconds and us_remainder
2379+
temp_tuple = checked_divmod(py_total_us, CONST_US_PER_SECOND(st));
2380+
if (temp_tuple == NULL) {
2381+
goto Done;
2382+
}
2383+
py_total_s = Py_NewRef(PyTuple_GET_ITEM(temp_tuple, 0));
2384+
py_us_rem_obj = Py_NewRef(PyTuple_GET_ITEM(temp_tuple, 1));
2385+
Py_DECREF(temp_tuple);
2386+
temp_tuple = NULL;
2387+
2388+
us = PyLong_AsInt(py_us_rem_obj);
2389+
if (us == -1 && PyErr_Occurred()) {
2390+
goto Done;
2391+
}
2392+
2393+
// Total_seconds to total_days and s_remainder
2394+
temp_tuple = checked_divmod(py_total_s, CONST_SEC_PER_DAY(st));
2395+
if (temp_tuple == NULL) {
2396+
goto Done;
2397+
}
2398+
py_d_final = Py_NewRef(PyTuple_GET_ITEM(temp_tuple, 0));
2399+
py_s_rem_obj = Py_NewRef(PyTuple_GET_ITEM(temp_tuple, 1));
2400+
Py_DECREF(temp_tuple);
2401+
temp_tuple = NULL;
2402+
2403+
s = PyLong_AsInt(py_s_rem_obj);
2404+
if (s == -1 && PyErr_Occurred()) {
2405+
goto Done;
2406+
}
2407+
2408+
d = PyLong_AsInt(py_d_final);
2409+
if (d == -1 && PyErr_Occurred()) {
2410+
goto Done;
2411+
}
2412+
result = new_delta(d, s, us, ns_rem, 1); // Ensure normalization
2413+
2414+
Done:
2415+
Py_XDECREF(py_total_us);
2416+
Py_XDECREF(py_ns_rem_obj);
2417+
Py_XDECREF(py_total_s);
2418+
Py_XDECREF(py_us_rem_obj);
2419+
Py_XDECREF(py_d_final);
2420+
Py_XDECREF(py_s_rem_obj);
2421+
Py_XDECREF(PY_NS_PER_US_CONST);
2422+
Py_XDECREF(temp_tuple);
2423+
RELEASE_CURRENT_STATE(st, current_mod);
2424+
return result;
23442425
}
23452426

23462427
static PyObject *

0 commit comments

Comments
 (0)