diff --git a/pandas/_libs/tslibs/src/datetime/np_datetime.c b/pandas/_libs/tslibs/src/datetime/np_datetime.c index 2bac6c720c3b6..3a84adf083292 100644 --- a/pandas/_libs/tslibs/src/datetime/np_datetime.c +++ b/pandas/_libs/tslibs/src/datetime/np_datetime.c @@ -27,6 +27,7 @@ This file is derived from NumPy 1.7. See NUMPY_LICENSE.txt #include #include "np_datetime.h" +#include "datetime.h" const npy_datetimestruct _AS_MIN_DTS = { 1969, 12, 31, 23, 59, 50, 776627, 963145, 224193}; @@ -374,35 +375,33 @@ int convert_pydatetime_to_datetimestruct(PyObject *dtobj, npy_datetimestruct *out) { // Assumes that obj is a valid datetime object PyObject *tmp; - PyObject *obj = (PyObject*)dtobj; /* Initialize the output to all zeros */ memset(out, 0, sizeof(npy_datetimestruct)); out->month = 1; out->day = 1; - out->year = PyLong_AsLong(PyObject_GetAttrString(obj, "year")); - out->month = PyLong_AsLong(PyObject_GetAttrString(obj, "month")); - out->day = PyLong_AsLong(PyObject_GetAttrString(obj, "day")); + PyDateTime_IMPORT; - // TODO(anyone): If we can get PyDateTime_IMPORT to work, we could use - // PyDateTime_Check here, and less verbose attribute lookups. - - /* Check for time attributes (if not there, return success as a date) */ - if (!PyObject_HasAttrString(obj, "hour") || - !PyObject_HasAttrString(obj, "minute") || - !PyObject_HasAttrString(obj, "second") || - !PyObject_HasAttrString(obj, "microsecond")) { - return 0; + if (!PyDate_Check(dtobj)) { + PyErr_SetString(PyExc_TypeError, "Expected date object"); + return NULL; } + PyDateTime_Date *dateobj = (PyDateTime_Date*)dtobj; + + out->year = PyDateTime_GET_YEAR(dateobj); + out->month = PyDateTime_GET_MONTH(dateobj); + out->day = PyDateTime_GET_DAY(dateobj); + out->hour = PyDateTime_DATE_GET_HOUR(dateobj); - out->hour = PyLong_AsLong(PyObject_GetAttrString(obj, "hour")); - out->min = PyLong_AsLong(PyObject_GetAttrString(obj, "minute")); - out->sec = PyLong_AsLong(PyObject_GetAttrString(obj, "second")); - out->us = PyLong_AsLong(PyObject_GetAttrString(obj, "microsecond")); + if (PyDateTime_Check(dateobj)) { + PyDateTime_DateTime* obj = (PyDateTime_DateTime*)dateobj; + out->min = PyDateTime_DATE_GET_MINUTE(obj); + out->sec = PyDateTime_DATE_GET_SECOND(obj); + out->us = PyDateTime_DATE_GET_MICROSECOND(obj); - if (PyObject_HasAttrString(obj, "tzinfo")) { - PyObject *offset = extract_utc_offset(obj); + // TODO(py3.10): in py3.10 we can use PyDateTime_DATE_GET_TZINFO + PyObject *offset = extract_utc_offset((PyObject*)obj); /* Apply the time zone offset if datetime obj is tz-aware */ if (offset != NULL) { if (offset == Py_None) {