summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wiebe <mwiebe@enthought.com>2011-05-24 19:05:22 -0500
committerMark Wiebe <mwiebe@enthought.com>2011-05-24 19:05:22 -0500
commit6b8ad91154f90e26fb3428f023dab98e858c2b72 (patch)
tree58713db27f521943607d465256d40aac6ac19104
parentfeb6c2c956b834376e0f1bb752d67ec050fde879 (diff)
downloadnumpy-6b8ad91154f90e26fb3428f023dab98e858c2b72.tar.gz
ENH: Cleaning up object <-> datetime conversions
-rw-r--r--numpy/core/src/multiarray/_datetime.h2
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src2
-rw-r--r--numpy/core/src/multiarray/datetime.c31
-rw-r--r--numpy/core/tests/test_datetime.py12
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