diff options
author | Mark Wiebe <mwiebe@enthought.com> | 2011-05-24 19:05:22 -0500 |
---|---|---|
committer | Mark Wiebe <mwiebe@enthought.com> | 2011-05-24 19:05:22 -0500 |
commit | 6b8ad91154f90e26fb3428f023dab98e858c2b72 (patch) | |
tree | 58713db27f521943607d465256d40aac6ac19104 | |
parent | feb6c2c956b834376e0f1bb752d67ec050fde879 (diff) | |
download | numpy-6b8ad91154f90e26fb3428f023dab98e858c2b72.tar.gz |
ENH: Cleaning up object <-> datetime conversions
-rw-r--r-- | numpy/core/src/multiarray/_datetime.h | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/arraytypes.c.src | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/datetime.c | 31 | ||||
-rw-r--r-- | numpy/core/tests/test_datetime.py | 12 |
4 files changed, 44 insertions, 3 deletions
diff --git a/numpy/core/src/multiarray/_datetime.h b/numpy/core/src/multiarray/_datetime.h index 1f835ebff..84fb6fd9a 100644 --- a/numpy/core/src/multiarray/_datetime.h +++ b/numpy/core/src/multiarray/_datetime.h @@ -139,7 +139,7 @@ convert_pydatetime_to_datetimestruct(PyObject *obj, npy_datetimestruct *out); * Returns -1 on error, 0 on success. */ NPY_NO_EXPORT int -convert_pyobject_to_datetime(PyObject *obj, PyArray_DatetimeMetaData *meta, +convert_pyobject_to_datetime(PyArray_DatetimeMetaData *meta, PyObject *obj, npy_datetime *out); /* diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index 4fe5ea19e..80bd59636 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -1110,7 +1110,7 @@ DATETIME_setitem(PyObject *op, char *ov, PyArrayObject *ap) { } /* Convert the object into a NumPy datetime */ - if (convert_pyobject_to_datetime(op, meta, &temp) < 0) { + if (convert_pyobject_to_datetime(meta, op, &temp) < 0) { return -1; } diff --git a/numpy/core/src/multiarray/datetime.c b/numpy/core/src/multiarray/datetime.c index 02a5a4d59..accadf7c5 100644 --- a/numpy/core/src/multiarray/datetime.c +++ b/numpy/core/src/multiarray/datetime.c @@ -610,6 +610,10 @@ convert_datetime_to_datetimestruct(PyArray_DatetimeMetaData *meta, if (meta->events > 1) { out->event = dt % meta->events; dt = dt / meta->events; + if (out->event < 0) { + out->event += meta->events; + --dt; + } } /* TODO: Change to a mechanism that avoids the potential overflow */ @@ -2479,7 +2483,7 @@ invalid_time: * Returns -1 on error, 0 on success. */ NPY_NO_EXPORT int -convert_pyobject_to_datetime(PyObject *obj, PyArray_DatetimeMetaData *meta, +convert_pyobject_to_datetime(PyArray_DatetimeMetaData *meta, PyObject *obj, npy_datetime *out) { if (PyBytes_Check(obj) || PyUnicode_Check(obj)) { @@ -2525,6 +2529,31 @@ convert_pyobject_to_datetime(PyObject *obj, PyArray_DatetimeMetaData *meta, *out = PyLong_AsLongLong(obj); return 0; } + /* Could be a tuple with event number in the second entry */ + else if (PyTuple_Check(obj) && PyTuple_Size(obj) == 2) { + int event, event_old; + if (convert_pyobject_to_datetime(meta, PyTuple_GET_ITEM(obj, 0), + out) < 0) { + return -1; + } + event = (int)PyInt_AsLong(PyTuple_GET_ITEM(obj, 1)); + if (event == -1 && PyErr_Occurred()) { + return -1; + } + if (event < 0 || event >= meta->events) { + PyErr_SetString(PyExc_ValueError, "event value for NumPy " + "datetime is out of range"); + return -1; + } + /* Replace the event with the one from the tuple */ + event_old = *out % meta->events; + if (event_old < 0) { + event_old += meta->events; + } + *out = *out - event_old + event; + + return 0; + } /* TODO datetime64 scalars require conversion else if (PyArray_IsScalar(op, Datetime)) { } diff --git a/numpy/core/tests/test_datetime.py b/numpy/core/tests/test_datetime.py index ddbc8eba2..46fcdc0d9 100644 --- a/numpy/core/tests/test_datetime.py +++ b/numpy/core/tests/test_datetime.py @@ -96,6 +96,18 @@ class TestDateTime(TestCase): np.dtype('m8[s]'), np.dtype('m8[as]')) + """ + def test_pyobject_conversion(self): + # All datetime types should be able to roundtrip through object + a = np.array([-1020040340, -2942398, -1, 0, 1, 234523453, 1199164176], + dtype=np.int64) + for unit in ['M8[as]', 'M8[16fs]', 'M8[ps]', 'M8[us]', + 'M8[as//12]', 'M8[us//16]', 'M8[D]', 'M8[D]//4', + 'M8[W]', 'M8[M]', 'M8[Y]']: + assert_equal(a.view(dtype=unit).astype(object).astype(unit), + a.view(dtype=unit)) + """ + def test_hours(self): t = np.ones(3, dtype='M8[s]') t[0] = 60*60*24 + 60*60*10 |