summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2009-08-27 18:45:22 +0000
committerTravis Oliphant <oliphant@enthought.com>2009-08-27 18:45:22 +0000
commitaff438e441b05a5f20287bb1b283f120be802ed9 (patch)
tree0d2e64d237c14ba635fbadcd6f9eb3d6c6623f22 /numpy/core
parenteb602697b501d67613639a1e65f6a40cc4852087 (diff)
downloadnumpy-aff438e441b05a5f20287bb1b283f120be802ed9.tar.gz
Trying to get to compile prior to merging changes from trunk. Coercions still need to be written.
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/include/numpy/ndarrayobject.h11
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src129
-rw-r--r--numpy/core/src/multiarray/descriptor.c33
-rw-r--r--numpy/core/src/multiarray/parse_datetime.c2957
4 files changed, 608 insertions, 2522 deletions
diff --git a/numpy/core/include/numpy/ndarrayobject.h b/numpy/core/include/numpy/ndarrayobject.h
index 7978cb719..69774053b 100644
--- a/numpy/core/include/numpy/ndarrayobject.h
+++ b/numpy/core/include/numpy/ndarrayobject.h
@@ -581,8 +581,15 @@ typedef struct {
} PyArray_DatetimeMetaData;
typedef struct {
- int year, month, day, hour, min, sec, ms, us, ns, ps, fs, as;
-} npy_datestruct;
+ npy_longlong year;
+ int month, day, hour, min, sec, us, ps, as;
+} npy_datetimestruct;
+
+typedef struct {
+ npy_longlong day;
+ int sec, us, ps, as;
+} npy_timedeltastruct;
+
#define PyDataType_GetDatetimeMetaData(descr) ((PyArray_DatetimeMetaData *)(PyCObject_AsVoidPtr(PyDict_GetItemString(((PyArray_Descr *)descr)->metadata, NPY_METADATA_DTSTR))))
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index e7cf607ab..db5668ef6 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -153,30 +153,56 @@ static int
number of events is a Python integer
*/
+
/* Return a Python Datetime Object from a number representing the number of
units since the epoch (1970-01-01T00:00:00Z) ignoring leap seconds.
*/
-NPY_NO_EXPORT PyObject *
+
+static PyObject *
PyDateTime_FromNormalized(npy_datetime val, NPY_DATETIME_UNIT base)
{
- npy_datestruct ydate;
+ npy_datetimestruct ydate;
+
+ /* Must be here to use PyDateTime_FromDateAndTime */
+ PyDateTime_IMPORT;
/* We just truncate the unused variables and don't wory about overflow */
- _datetime_to_datestruct(val, base, &ydate);
-
+ PyArray_DateTimeToDatetimeStruct(val, base, &ydate);
+
+ /* FIXME?: We discard ydate.ns, ydate.ps, ydate.fs, and ydate.as */
+ return PyDateTime_FromDateAndTime(ydate.year, ydate.month, ydate.day,
+ ydate.hour, ydate.min, ydate.sec,
+ ydate.us);
}
+/* We also can lose precision and range here. Ignored.
+ Don't use this function if you care.
+ */
+
+static PyObject *
+PyTimeDelta_FromNormalized(npy_timedelta val, NPY_DATETIME_UNIT base)
+{
+ npy_timedeltastruct td;
+
+ PyDateTime_IMPORT;
+
+ PyArray_TimedeltatoTimedeltaStruct(val, base, &td);
+
+ /* We discard td.ps and td.as */
+
+ return PyDelta_FromDSU(td.day, td.sec, td.ms);
+}
+
static PyObject *
PyDatetime_FromInt64(datetime val, PyArray_Descr *descr)
{
PyArray_DatetimeMetaData *meta;
- PyObject *obj;
meta = PyDataType_GetDatetimeMetaData(descr);
- datetime normalized;
if (meta->events > 1) {
int events, rem, div;
+ PyObject *obj;
obj = PyTuple_New(2);
events = meta->events;
div = val / events;
@@ -202,8 +228,7 @@ PyDatetime_FromInt64(datetime val, PyArray_Descr *descr)
/* Normalization and then conversion to Datetime */
/* FIXME? : Check for Overflow... */
- normalized = val * meta->num;
- return PyDatetime_FromNormalized(normalized, meta->base);
+ return PyDatetime_FromNormalized(val*meta->num, meta->base);
}
@@ -211,10 +236,11 @@ static PyObject *
PyTimedelta_FromInt64(timedelta val, PyArray_Descr *descr)
{
PyArray_DatetimeMetaData *meta;
- meta = PyDataType_GetDatetimeMetaData(meta);
+ meta = PyDataType_GetDatetimeMetaData(descr);
if (meta->events > 1) {
int events, rem, div;
+ PyObject *obj;
obj = PyTuple_New(2);
events = meta->events;
div = val / events;
@@ -229,21 +255,87 @@ PyTimedelta_FromInt64(timedelta val, PyArray_Descr *descr)
}
return obj;
}
+
+ /* FIXME? : Check for Overflow */
+ return PyTimeDelta_FromNormalized(val*meta->num, meta->base);
+}
+
+
+
+static npy_datetime
+PyDateTime_AsNormalized(PyObject *obj, NPY_DATETIME_UNIT base)
+{
+ npy_datetimestruct ydate;
+
+ /* Must be here to use PyDateTime_FromDateAndTime */
+ PyDateTime_IMPORT;
+
+ if (!PyDateTime_Check(obj) && !PyDate_Check(obj)) {
+ PyErr_SetString(PyExc_ValueError, "Must be a datetime.date or datetime.datetime object");
+ return -1;
+ }
+
+ ydate.year = PyDateTime_GET_YEAR(obj);
+ ydate.month = PyDateTime_GET_MONTH(obj);
+ ydate.day = PyDateTime_GET_DAY(obj);
+
+ if (PyDateTime_Check(obj)) {
+ ydate.hour = PyDateTime_GET_HOUR(obj);
+ ydate.min = PyDateTime_GET_MINUTE(obj);
+ ydate.sec = PyDateTime_GET_SECOND(obj);
+ ydate.us = PyDateTime_GET_MICROSECOND(obj);
+ }
+ else {
+ ydate.hour = 0;
+ ydate.min = 0;
+ ydate.sec = 0;
+ ydate.us = 0;
+ }
+
+ ydate.ps = 0;
+ ydate.as = 0;
+
+ /* We just truncate the unused variables and don't wory about overflow */
+ return PyArray_DateTimeStructToDatetime(&ydate, base);
+}
+
+static npy_timedelta
+PyTimeDelta_AsNormalized(Pyobject *obj, NPY_DATETIME_UNIT base)
+{
+ npy_timedeltastruct td;
+
+ PyDateTime_IMPORT;
+
+ if (!PyDelta_Check(obj)) {
+ PyErr_SetString(PyExc_ValueError, "Must be a datetime.timedelta object");
+ return -1;
+ }
+
+ td.day = ((PyDateTime_Delta *)obj)->days;
+ td.sec = ((PyDateTime_Delta *)obj)->seconds;
+ td.us = ((PyDateTime_Delta *)obj)->microseconds;
+ td.ps = 0;
+ td.as = 0;
+
+ return PyArray_TimedeltaStructToTimedelta(base, &td);
}
+
/* These expect:
* a 2-tuple if meta->events > 1 (baseobj, num-counts)
- * an integer if NPY_DATETIMEUNIT > NPY_FR_us
- * a datetime object
+ * where baseobj is a datetime object or a timedelta object
+ * respectively.
*/
-static datetime
+static npy_datetime
PyDatetime_AsInt64(PyObject *obj, PyArray_Descr *descr)
{
PyArray_DatetimeMetaData *meta;
- meta = PyDataType_GetDatetimeMetaData(meta);
+ npy_datetime res;
+
+ meta = PyDataType_GetDatetimeMetaData(descr);
if (meta->events > 1) {
datetime tmp;
@@ -258,7 +350,10 @@ PyDatetime_AsInt64(PyObject *obj, PyArray_Descr *descr)
tmp += MyPyLong_AsLongLong(PyTuple_GETITEM(obj, 1));
if (PyErr_Occurred()) return -1;
return tmp;
- }
+ }
+
+ res = PyDatetime_AsNormalized(obj, meta->base);
+ return res / meta->num;
}
@@ -266,7 +361,7 @@ static timedelta
PyTimedelta_AsInt64(PyObject *obj, PyArray_Descr *descr)
{
PyArray_DatetimeMetaData *meta;
- meta = PyDataType_GetDatetimeMetaData(meta);
+ meta = PyDataType_GetDatetimeMetaData(descr);
if (meta->events > 1) {
timedelta tmp;
@@ -282,8 +377,12 @@ PyTimedelta_AsInt64(PyObject *obj, PyArray_Descr *descr)
if (PyErr_Occurred()) return -1;
return tmp;
}
+
+ res = PyTimedelta_AsNormalized(obj, meta->base);
+ return res / meta->num;
}
+
/* Always return DateTime Object after normalizing to basic units (or a tuple
if meta->events > 1):
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c
index d8b228df9..03e93ec24 100644
--- a/numpy/core/src/multiarray/descriptor.c
+++ b/numpy/core/src/multiarray/descriptor.c
@@ -505,23 +505,22 @@ static NPY_DATETIMEUNIT
return unit;
}
-static int *_multiples_table[] = {
- [12, 52, 365],
- [NPY_FR_M, NPY_FR_W, NPY_FR_D],
- [4, 30, 720],
- [NPY_FR_W, NPY_FR_D, NPY_FR_h],
- [5, 7, 168, 10080],
- [NPY_FR_B, NPY_FR_D, NPY_FR_h, NPY_FR_m],
- [24, 1440, 86400],
- [NPY_FR_h, NPY_FR_m, NPY_FR_s],
- [24, 1440, 86400],
- [NPY_FR_h, NPY_FR_m, NPY_FR_s],
- [60, 3600, -1],
- [NPY_FR_m, NPY_FR_s, -1],
- [60, 60000, -1],
- [NPY_FR_s, NPY_FR_ms, -1],
- [1000, 1000000, -1],
- [-1, -1, -1]
+static int _multiples_table[16][4] = {
+ {12, 52, 365}, /* NPY_FR_Y */
+ {NPY_FR_M, NPY_FR_W, NPY_FR_D},
+ {4, 30, 720}, /* NPY_FR_M */
+ {NPY_FR_W, NPY_FR_D, NPY_FR_h},
+ {5, 7, 168, 10080}, /* NPY_FR_W */
+ {NPY_FR_B, NPY_FR_D, NPY_FR_h, NPY_FR_m},
+ {24, 1440, 86400}, /* NPY_FR_B */
+ {NPY_FR_h, NPY_FR_m, NPY_FR_s},
+ {24, 1440, 86400}, /* NPY_FR_D */
+ {NPY_FR_h, NPY_FR_m, NPY_FR_s},
+ {60, 3600}, /* NPY_FR_h */
+ {NPY_FR_m, NPY_FR_s},
+ {60, 60000}, /* NPY_FR_m */
+ {NPY_FR_s, NPY_FR_ms},
+ {1000, 1000000}, /* >=NPY_FR_s */
};
diff --git a/numpy/core/src/multiarray/parse_datetime.c b/numpy/core/src/multiarray/parse_datetime.c
index 7ec1fc392..6705790b9 100644
--- a/numpy/core/src/multiarray/parse_datetime.c
+++ b/numpy/core/src/multiarray/parse_datetime.c
@@ -9,8 +9,6 @@
* Assuming Gregorian calendar was always in effect (proleptic Gregorian calendar)
*/
-#define DAYS_EPOCH 719162
-
/* Calendar Structure for Parsing Long -> Date */
typedef struct {
int year, month, day;
@@ -56,18 +54,19 @@ is_leapyear(register long year)
/* Return the day of the week for the given absolute date. */
+/* Monday is 0 and Sunday is 6 */
static int
-day_of_week(register long absdate)
+day_of_week(npy_longlong absdate)
{
- int day_of_week;
+ /* Add in four for the Thursday on Jan 1, 1970 (epoch offset)*/
+ absdate += 4
- // Add in three for the Thursday on Jan 1, 1970 (epoch offset)
- if (absdate >= 0)
- day_of_week = (absdate + 4) % 7;
- else
- day_of_week = 6 - ((-absdate + 2) % 7);
-
- return day_of_week;
+ if (absdate >= 0) {
+ return absdate % 7;
+ }
+ else {
+ return 6 + (absdate + 1) % 7
+ }
}
/* Return the year offset, that is the absolute date of the day
@@ -76,11 +75,12 @@ day_of_week(register long absdate)
static npy_longlong
year_offset(register npy_longlong year)
{
- year-=1970;
- if ((year+1969) >= 0 || -1/4 == -1)
- return year*365 + year/4 - year/100 + year/400;
+ /* Note that 477 == 1969/4 - 1969/100 + 1969/400 */
+ year--;
+ if (year >= 0 || -1/4 == -1)
+ return (year-1969)*365 + year/4 - year/100 + year/400 - 477;
else
- return year*365 + (year-3)/4 - (year-99)/100 + (year-399)/400;
+ return (year-1969)*365 + (year-3)/4 - (year-99)/100 + (year-399)/400 - 477;
}
/* Modified version of mxDateTime function
@@ -90,7 +90,7 @@ year_offset(register npy_longlong year)
* day -1 is Dec 31, 1969, day 0 is Jan 1, 1970, day 1 is Jan 2, 1970
*/
static npy_longlong
-absdays_from_ymd(int year, int month, int day)
+days_from_ymd(int year, int month, int day)
{
/* Calculate the absolute date */
@@ -134,28 +134,18 @@ absdays_from_ymd(int year, int month, int day)
/* Returns absolute seconds from an hour, minute, and second
*/
-static npy_longlong
-abssecs_from_hms(int hour, int minute, int second)
-{
- /* Needs to perform checks for valid times */
+#define secs_from_hms(hour, min, sec) ((hour)*3600 + (min)*60 + (sec))
- Py_AssertWithArg(hour >=0 && hour <= 23,
- PyExc_ValueError,
- "hour out of range (0-23): %i",
- hour);
-
- Py_AssertWithArg(minute >=0 && minute <= 59,
- PyExc_ValueError,
- "minute out of range (0-59): %i",
- minute);
-
- Py_AssertWithArg(second >=0 && second <= 59,
- PyExc_ValueError,
- "second out of range (0-59): %i",
- second);
-
- return hour * 3600 + minute * 60 + second;
-}
+/* Takes a number of days since Jan 1, 1970 (positive or negative)
+ * and returns the year. month, and day in the proleptic
+ * Gregorian calendar
+ *
+ * Examples:
+ *
+ * -1 returns 1969, 12, 31
+ * 0 returns 1970, 1, 1
+ * 1 returns 1970, 1, 2
+ */
static ymdstruct
days_to_ymdstruct(npy_datetime dlong)
@@ -167,6 +157,7 @@ days_to_ymdstruct(npy_datetime dlong)
int month = 1, day = 1;
int *monthoffset;
+ dlong += 1
/* Approximate year */
year = 1970 + dlong / 365.2425;
@@ -229,263 +220,225 @@ seconds_to_hmsstruct(npy_longlong dlong)
return hms;
}
-
/*
====================================================
- == End of section borrowed from mx.DateTime ==
+ == End of section adapted from mx.DateTime ==
====================================================
*/
+
/*==================================================
-// Parsing datetime/datestring to long
+// Parsing DateTime struct and returns a date-time number
// =================================================
-// Takes a datetime object and a string as frequency
-// Returns the number of (frequency) since Jan 1, 1970
+ Structure is assumed to be already normalized
*/
-static
-npy_longlong datetime_to_long(PyObject* datetime, int frequency)
-{
- int year = 0, month = 0, day = 0, hour = 0,
- minute = 0, second = 0, microsecond = 0;
-
- // Get the time units from PyDateTime
- year = PyDateTime_GET_YEAR(datetime);
- month = PyDateTime_GET_MONTH(datetime);
- day = PyDateTime_GET_DAY(datetime);
-
- minute = PyDateTime_DATE_GET_MINUTE(datetime);
- second = PyDateTime_DATE_GET_SECOND(datetime);
- microsecond = PyDateTime_DATE_GET_MICROSECOND(datetime);
-
- // The return value
- npy_longlong result = 0;
-
- // The absolute number of days since 1970
- npy_longlong absdays = absdays_from_ymd(year, month, day);
-
- // These calculations depend on the frequency
-
- if (frequency == NPY_FR_Y) {
- result = year - 1970;
- } else if (frequency == NPY_FR_M) {
- result = (year - 1970) * 12 + month - 1;
- } else if (frequency == NPY_FR_W) {
- // 4 day offset for post 1970 to get correct week
- int dotw = day_of_week(absdays);
- if (absdays >= 0)
- result = (absdays + 4) / 7;
- else
- result = (absdays - dotw)/ 7;
- } else if (frequency == NPY_FR_B) {
- int dotw = day_of_week(absdays);
- // Post epoch
- if (year >= 1970) {
- // To get to Sunday, Jan 4, 1970
- // number of weeks * 5 + dotw [0-6] - Saturdays + 1 for offset
- if (absdays > 2)
- result = ((absdays - dotw) / 7) * 5 + dotw - (dotw / 6) + 1;
- else
- result = dotw - 4 - (dotw / 6);
- // Pre epoch
- } else {
- // To get beyond Sunday, Dec 28, 1969
- if (absdays < -4) {
- // Offset by 1 for Sundays
- if (dotw)
- result = ((absdays + 7 - dotw) / 7) * 5 - (6 - dotw) - 3;
- else
- result = ((absdays + 7 - dotw) / 7) * 5 - (6 - dotw) - 2;
- } else {
- // Offset by 1 for Sundays
- if (dotw)
- result = -4 + dotw;
- else
- result = -3; // Sunday, Dec 28, 1969
- }
- }
- } else if (frequency == NPY_FR_D) {
- result = absdays;
- } else if (frequency == NPY_FR_h) {
- result = absdays * 24 + hour;
- } else if (frequency == NPY_FR_m) {
- result = absdays * 1440 + hour * 60 + minute;
- } else if (frequency == NPY_FR_s) {
- result = absdays * 86400LL + abssecs_from_hms(hour, minute, second);
- } else if (frequency == NPY_FR_ms) {
- result = absdays * 86400000LL + abssecs_from_hms(hour, minute, second) * 1000LL
- + (microsecond / 1000LL);
- } else if (frequency == NPY_FR_us) {
- result = absdays * 86400000000LL + abssecs_from_hms(hour, minute, second) * 1000000LL
- + microsecond;
- }
- // Starting from here, we need extra units (ns, ps, fs, as)
- // for correct precision: datetime doesn't include beyond microsecond
- else if (frequency == NPY_FR_ns) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
- result = 0;
- } else if (frequency == NPY_FR_ps) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
- result = 0;
- } else if (frequency == NPY_FR_fs) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
- result = 0;
- } else if (frequency == NPY_FR_as) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
- result = 0;
- } else {
- // Throw some Not Valid Frequency error here
- result = -1;
- }
-
- return result;
-}
-// Takes a string object as the date, and a string as frequency,
-// parses that into a datetime and passes the datetime object
-// to datetime_to_long
-// Returns the number of (frequency) since Jan 1, 1970
-static
-npy_longlong datestring_to_long(PyObject *string, int frequency)
+/*NUMPY_API
+ * Create a datetime value from a filled datetime struct and resolution unit.
+ */
+NPY_NO_EXPORT npy_datetime
+PyArray_DatetimeStructToDatetime(NPY_DATETIME_UNIT fr, npy_datetimestruct *d)
{
- // Send to datetime_to_long
- PyObject *datetime = NULL;
- npy_longlong result = 0;
+ npy_datetime ret;
+ npy_longlong days; /* The absolute number of days since Jan 1, 1970 */
- // Make the string into a tuple for the callback function
- PyObject *string_arg = PyTuple_New(1);
- PyTuple_SET_ITEM(string_arg, 0, string);
- Py_INCREF(string);
+ if (fr > NPY_FR_M) days = days_from_ymd(d->year, d->month, d->day);
- // Parse the string into a datetime object
- datetime = PyEval_CallObject(callback, string_arg);
-
- Py_DECREF(string_arg);
-
- // If the parsing worked, send the datetime and frequency
- // to datetime_to_long
- if (datetime)
- {
- result = datetime_to_long(datetime, frequency);
+ if (fr == NPY_FR_Y) {
+ ret = d->year - 1970;
+ }
+ else if (fr == NPY_FR_M) {
+ ret = (d->year - 1970) * 12 + s.month - 1;
+ }
+ else if (fr == NPY_FR_W) { /* This is just 7-days for now. */
+ if (days >= 0)
+ ret = days / 7;
+ else
+ ret = (days - 6) / 7;
+ }
+ else if (fr == NPY_FR_B) {
+ npy_longlong x;
+ if (dotw > 4) ret = 0; /* Invalid business day */
+ else {
+ if (days >= 0) { /* offset to adjust first week */
+ x = days - 4;
+ }
+ else {
+ x = days - 2;
+ }
+ ret = 2 + (x / 7) * 5 + x % 7;
}
- else
- {
- PyErr_SetString(PyExc_TypeError, "error processing datetime");
- //return NULL;
- //Return bad stuff
- result = -1;
+ }
+ else if (fr == NPY_FR_D) {
+ ret = days;
+ }
+ else if (fr == NPY_FR_h) {
+ ret = days * 24 + d->hour;
+ }
+ else if (fr == NPY_FR_m) {
+ ret = days * 1440 + d->hour * 60 + d->min;
+ }
+ else if (fr == NPY_FR_s) {
+ ret = days * 86400 + secs_from_hms(d->hour, d->min, d->sec);
+ }
+ else if (fr == NPY_FR_ms) {
+ ret = days * 86400000 + secs_from_hms(d->hour, d->min, d->sec) * 1000
+ + (d->us / 1000);
+ }
+ else if (fr == NPY_FR_us) {
+ npy_int64 num = 86400 * 1000 * 1000;
+ ret = days * num + secs_from_hms(d->hour, d->minute, d->second) * 1000000
+ + d->us;
+ }
+ else if (fr == NPY_FR_ns) {
+ npy_int64 num = 86400 * 1000 * 1000 * 1000;
+ ret = days * num + secs_from_hms(d->hour, d->minute, d->second) * 1000000000
+ + d->us * 1000 + (d->ps / 1000);
+ }
+ else if (fr == NPY_FR_ps) {
+ npy_int64 num2 = 1000 * 1000 * 1000 * 1000;
+ npy_int64 num1 = 86400 * num2;
+ ret = days * num1 + secs_from_hms(d->hour, d->minute, d->second) * num2;
+ + d->us * 1000000 + d->ps;
+ }
+ else if (fr == NPY_FR_fs) { /* only 2.6 hours */
+ npy_int64 num2 = 1000000 * 1000000 * 1000;
+ /* get number of seconds as a postive or negative number */
+ if (days >= 0) {
+ ret = secs_from_hms(d->hour, d->minute, d->second);
}
-
- return result;
-}
-
-// This is the callable wrapper for datestring/datetime_to_long
-// Decides if the arguments are a string or a datetime object
-// and passes them to the correct datestring/datetime function
-// Returns a PyLong generated from the appropriate function
-static PyObject *
-date_to_long(PyObject *self, PyObject *args)
-{
- PyObject *date_arg = NULL; // string or datetime
- PyObject *freq_arg = NULL; // frequency as string
- PyObject *result = NULL; // long result
-
- int freq = NPY_FR_ERR; // freq_arg is a PyObject to be parsed to freq
-
- // macro PyDateTime_IMPORT must be invoked for PyDateTime_Check
- PyDateTime_IMPORT;
-
- // Make sure the callback function is set
- // ! This doesn't check to make sure it's the right callback function
- // ! This should all be done in some init script
- if (!PyCallable_Check(callback))
- {
- PyErr_SetString(PyExc_TypeError, "callback not set.");
- return NULL;
+ else {
+ ret = ((d->hour - 24)*3600 + d->minute*60 + d->second);
}
-
- // Parse out date_arg & freq_arg
- if (!PyArg_ParseTuple(args, "OO", &date_arg, &freq_arg))
- {
- return NULL;
+ ret = ret * num2 + d->us * 1000000000 + d->ps * 1000 + (d->as / 1000);
+ }
+ else if (fr == NPY_FR_as) { /* only 9.2 secs */
+ npy_int64 num1 = 1000000 * 1000000;
+ npy_int64 num2 = num1 * 1000000;
+
+ if (days >= 0) {
+ ret = d->second;
}
-
- // Make sure frequency is not NULL
- if (!freq_arg)
- {
- PyErr_SetString(PyExc_TypeError, "frequency not set.");
- return NULL;
+ else {
+ ret = d->second - 60;
}
+ ret = ret * num2 + d->us * num1 + d->ps * 1000000 + d->as;
+ }
+ else { /* Shouldn't get here */
+ PyErr_SetString(PyExc_ValueError, "invalid internal frequency");
+ ret = -1;
+ }
- // Parse out frequency into an int so we can use it easily
- if ((freq = _unit_from_str(PyString_AsString(freq_arg))) == NPY_FR_ERR)
- {
- // If the frequency is invalid, set an error and return null
- PyErr_SetString(PyExc_TypeError, "invalid frequency.");
- return NULL;
- }
+ return ret;
+}
- // Make sure date_arg is not NULL
- if (!date_arg)
- {
- PyErr_SetString(PyExc_TypeError, "no date provided.");
- return NULL;
- }
+/* Uses Average values when frequency is Y, M, or B */
- // Decide if the date_arg is a string or a datetime
- if (PyString_Check(date_arg))
- {
- // XXX PyINCREF here?
- // date_arg is a string, so return datestring_to_long
- result = PyLong_FromLongLong(datestring_to_long(date_arg, freq));
- }
- else if (PyDateTime_Check(date_arg))
- {
- // XXX PyINCREF here?
- // date_arg is a datetime, so return datetime_to_long
- result = PyLong_FromLongLong(datetime_to_long(date_arg, freq));
+#define _DAYS_PER_MONTH 30.436875
+#define _DAYS_PER_YEAR 365.2425
+
+/*NUMPY_API
+ * Create a timdelta value from a filled timedelta struct and resolution unit.
+ */
+NPY_NO_EXPORT npy_datetime
+PyArray_TimedeltaStructToTimedelta(NPY_DATETIME_UNIT fr, npy_timedeltastruct *d)
+{
+ npy_datetime ret;
+
+ if (fr == NPY_FR_Y) {
+ ret = d->day / _DAYS_PER_YEAR;
+ }
+ else if (fr == NPY_FR_M) {
+ ret = d->day / _DAYS_PER_MONTH;
+ }
+ else if (fr == NPY_FR_W) { /* This is just 7-days for now. */
+ if (d->day >= 0) {
+ ret = d->day / 7;
}
- else
- {
- // date_arg is neither a string, nor a datetime
- PyErr_SetString(PyExc_TypeError, "invalid date type");
- return NULL;
+ else {
+ ret = (d->day - 6) / 7;
}
+ }
+ else if (fr == NPY_FR_B) {
+ /* What is the meaning of a relative Business day?
+
+ This assumes you want to take the day difference and
+ convert it to business-day difference (removing 2 every 7).
+ */
+ ret = (d->day / 7) * 5 + d->day % 7;
+ }
+ else if (fr == NPY_FR_D) {
+ ret = d->day;
+ }
+ else if (fr == NPY_FR_h) {
+ ret = d->day + d->sec / 3600;
+ }
+ else if (fr == NPY_FR_m) {
+ ret = d->day * 1440 + d->sec / 60;
+ }
+ else if (fr == NPY_FR_s) {
+ ret = d->day * 86400 + d->sec;
+ }
+ else if (fr == NPY_FR_ms) {
+ ret = d->day * 86400000 + d->sec * 1000 + d->us / 1000;
+ }
+ else if (fr == NPY_FR_us) {
+ npy_int64 num = 86400 * 1000 * 1000;
+ ret = d->day * num + d->sec * 1000000 + d->us
+ }
+ else if (fr == NPY_FR_ns) {
+ npy_int64 num = 86400 * 1000 * 1000 * 1000;
+ ret = d->day * num + d->sec * 1000000000 + d->us * 1000 + (d->ps / 1000);
+ }
+ else if (fr == NPY_FR_ps) {
+ npy_int64 num2 = 1000 * 1000 * 1000 * 1000;
+ npy_int64 num1 = 86400 * num2;
+ ret = d->day * num1 + d->sec * num2 + d->us * 1000000 + d->ps;
+ }
+ else if (fr == NPY_FR_fs) { /* only 2.6 hours */
+ npy_int64 num2 = 1000000 * 1000000 * 1000;
+ ret = d->sec * num2 + d->us * 1000000000 + d->ps * 1000 + (d->as / 1000);
+ }
+ else if (fr == NPY_FR_as) { /* only 9.2 secs */
+ npy_int64 num1 = 1000000 * 1000000;
+ npy_int64 num2 = num1 * 1000000;
+ ret = d->sec * num2 + d->us * num1 + d->ps * 1000000 + d->as;
+ }
+ else { /* Shouldn't get here */
+ PyErr_SetString(PyExc_ValueError, "invalid internal frequency");
+ ret = -1;
+ }
- if (PyErr_Occurred())
- return NULL;
-
- return result;
+ return ret;
}
-/*
-//==================================================
-// Parsing long to datetime/datestring
-// =================================================
-// Takes a npy_longlong value and a frequency
-// Returns a datestruct formatted with the correct calendar values
-*/
-static void
-datetime_to_datestruct(npy_datetime val, NPY_DATETIME_UNIT fr, npy_datestruct *result)
+
+/*NUMPY_API
+ * Fill the datetime struct from the value and resolution unit.
+ */
+NPY_NO_EXPORT void
+PyArray_DatetimeToDatetimeStruct(npy_datetime val, NPY_DATETIME_UNIT fr,
+ npy_datetimestruct *result)
{
int year = 1970, month = 1, day = 1,
hour = 0, min = 0, sec = 0,
- ms = 0, us = 0, ns = 0,
- ps = 0, fs = 0, as = 0;
+ us = 0, ps = 0, as = 0;
+ npy_int64 tmp;
ymdstruct ymd;
hmsstruct hms;
/* Note that what looks like val / N and val % N for positive numbers maps to
- [val + (N-1)] / N and [N-1 + (val+1) % N] for negative numbers (with the 2nd
+ [val - (N-1)] / N and [N-1 + (val+1) % N] for negative numbers (with the 2nd
value, the remainder, being positive in both cases).
*/
- if (frequency == NPY_FR_Y) {
+ if (fr == NPY_FR_Y) {
year = 1970 + val;
}
- else if (frequency == NPY_FR_M) {
+ else if (fr == NPY_FR_M) {
if (val >= 0) {
year = 1970 + val / 12;
month = val % 12 + 1;
@@ -495,14 +448,14 @@ datetime_to_datestruct(npy_datetime val, NPY_DATETIME_UNIT fr, npy_datestruct *r
month = 12 + (val + 1)% 12;
}
}
- else if (frequency == NPY_FR_W) {
+ else if (fr == NPY_FR_W) {
/* A week is the same as 7 days */
ymd = days_to_ymdstruct(val * 7);
year = ymd.year;
month = ymd.month;
day = ymd.day;
}
- else if (frequency == NPY_FR_B) { /* Number of business days since Thursday, 1-1-70 */
+ else if (fr == NPY_FR_B) { /* Number of business days since Thursday, 1-1-70 */
npy_longlong absdays;
/* A buisness day is M T W Th F (i.e. all but Sat and Sun.) */
/* Convert the business day to the number of actual days.
@@ -523,13 +476,13 @@ datetime_to_datestruct(npy_datetime val, NPY_DATETIME_UNIT fr, npy_datestruct *r
month = ymd.month;
day = ymd.day;
}
- else if (frequency == NPY_FR_D) {
+ else if (fr == NPY_FR_D) {
ymd = days_to_ymdstruct(val);
year = ymd.year;
month = ymd.month;
day = ymd.day;
}
- else if (frequency == NPY_FR_h) {
+ else if (fr == NPY_FR_h) {
if (val >= 0) {
ymd = days_to_ymdstruct(val / 24);
hour = val % 24;
@@ -542,7 +495,7 @@ datetime_to_datestruct(npy_datetime val, NPY_DATETIME_UNIT fr, npy_datestruct *r
month = ymd.month;
day = ymd.day;
}
- else if (frequency == NPY_FR_m) {
+ else if (fr == NPY_FR_m) {
if (val >= 0) {
ymd = days_to_ymdstruct(val / 1440);
min = val % 1440;
@@ -558,8 +511,7 @@ datetime_to_datestruct(npy_datetime val, NPY_DATETIME_UNIT fr, npy_datestruct *r
hour = hms.hour;
min = hms.min;
}
- else if (frequency == NPY_FR_s) {
- hmsstruct hms;
+ else if (fr == NPY_FR_s) {
if (val >= 0) {
ymd = days_to_ymdstruct(val / 86400);
sec = val % 86400;
@@ -568,7 +520,7 @@ datetime_to_datestruct(npy_datetime val, NPY_DATETIME_UNIT fr, npy_datestruct *r
ymd = days_to_ymdstruct((val - 86399) / 86400);
sec = 86399 + (val + 1) % 86400;
}
- hms = secondss_to_hmsstruct(val);
+ hms = seconds_to_hmsstruct(val);
year = ymd.year;
month = ymd.month;
day = ymd.day;
@@ -576,17 +528,17 @@ datetime_to_datestruct(npy_datetime val, NPY_DATETIME_UNIT fr, npy_datestruct *r
min = hms.min;
sec = hms.sec;
}
- else if (frequency == NPY_FR_ms) {
+ else if (fr == NPY_FR_ms) {
if (val >= 0) {
ymd = days_to_ymdstruct(val / 86400000);
- ms = val % 86400000
+ tmp = val % 86400000
}
else {
ymd = days_to_ymdstruct((val - 86399999) / 86400000);
- ms = 86399999 + (val + 1) % 86399999;
+ tmp = 86399999 + (val + 1) % 86399999;
}
- hms = seconds_to_hmsstruct(msec / 1000);
- msec = msec % 1000;
+ hms = seconds_to_hmsstruct(tmp / 1000);
+ us = (tmp % 1000)*1000;
year = ymd.year;
month = ymd.month;
day = ymd.day;
@@ -594,2258 +546,287 @@ datetime_to_datestruct(npy_datetime val, NPY_DATETIME_UNIT fr, npy_datestruct *r
min = hms.min;
sec = hms.sec;
}
- else if (frequency == NPY_FR_us) {
+ else if (fr == NPY_FR_us) {
+ npy_int64 num1, num2;
+ num1 = 86400 * 1000 * 1000;
+ num2 = num1 - 1;
if (val >= 0) {
- ymd = days_to_ymdstruct(val / 86400000000LL);
- hms = seconds_to_hmsstruct(val / 1000000LL);
- msec = (val / 1000) % 1000;
- usec = val % 1000LL;
+ ymd = days_to_ymdstruct(val / num1);
+ tmp = val % num1;
}
else {
- ymd = days_to_ymdstruct((val - 86399999999LL) / 86400000000LL);
- hms = seconds_to_hmsstruct((val - 999999LL) / 1000000LL);
- usec = ((1000000LL + (val % 1000000)) % 1000000);
- msec = usec / 1000;
- usec = usec % 1000;
+ ymd = days_to_ymdstruct((val - num2)/ num1);
+ tmp = num2 + (val + 1) % num1;
}
+ hms = seconds_to_hmsstruct(tmp / 1000000);
+ us = tmp % 1000000;
year = ymd.year;
month = ymd.month;
day = ymd.day;
hour = hms.hour;
- min = hms.min;
- sec = hms.sec;
+ min = hms.min;
+ sec = hms.sec;
}
- else if (frequency == NPY_FR_ns) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
+ else if (fr == NPY_FR_ns) {
+ npy_int64 num1, num2, num3;
+ num1 = 86400 * 1000 * 1000 * 1000;
+ num2 = num1 - 1;
+ num3 = 1000000 * 1000000;
+ if (val >= 0) {
+ ymd = days_to_ymdstruct(val / num1);
+ tmp = val % num1;
+ }
+ else {
+ ymd = days_to_ymdstruct((val - num2)/ num1);
+ tmp = num2 + (val + 1) % num1;
+ }
+ hms = seconds_to_hmsstruct(tmp / 1000000000);
+ tmp = tmp % 1000000000;
+ us = tmp / 1000;
+ ps = (tmp % 1000) * 1000;
+ year = ymd.year;
+ month = ymd.month;
+ day = ymd.day;
+ hour = hms.hour;
+ min = hms.min;
+ sec = hms.sec;
}
- else if (frequency == NPY_FR_ps) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
+ else if (fr == NPY_FR_ps) {
+ npy_int64 num1, num2, num3;
+ num3 = 1000000000 * 1000;
+ num1 = 86400 * num3;
+ num2 = num1 - 1;
+
+ if (val >= 0) {
+ ymd = days_to_ymdstruct(val / num1);
+ tmp = val % num1;
+ }
+ else {
+ ymd = days_to_ymdstruct((val - num2)/ num1);
+ tmp = num2 + (val + 1) % num1;
+ }
+ hms = seconds_to_hmsstruct(tmp / num3);
+ tmp = tmp % num3;
+ us = tmp / 1000000;
+ ps = tmp % 1000000;
+ year = ymd.year;
+ month = ymd.month;
+ day = ymd.day;
+ hour = hms.hour;
+ min = hms.min;
+ sec = hms.sec;
}
- else if (frequency == NPY_FR_fs) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
+ else if (fr == NPY_FR_fs) { /* entire range is only += 2.6 hours */
+ npy_int64 num1, num2;
+ num1 = 1000000000 * 1000;
+ num2 = num1 * 1000;
+
+ if (val >= 0) {
+ sec = val / num2;
+ fs = val % num2;
+ hms = seconds_to_hms(sec);
+ hour = hms.hour;
+ min = hms.min;
+ sec = hms.sec;
+ }
+ else { /* tmp (number of fs) will be positive after this segment */
+ year = 1969;
+ day = 31;
+ month = 12;
+ sec = (val - (num2-1))/num2;
+ tmp = (num2-1) + (val + 1) % num2;
+ if (sec == 0) { /* we are at the last second */
+ hour = 23;
+ min = 59;
+ sec = 59;
+ }
+ else {
+ hour = 24 + (sec - 3599)/3600;
+ sec = 3599 + (sec+1)%3600;
+ min = sec / 60;
+ sec = sec % 60;
+ }
+ }
+ us = tmp / 1000000000;
+ tmp = tmp % 1000000000;
+ ps = tmp / 1000;
+ as = (tmp % 1000) * 1000;
}
- else if (frequency == NPY_FR_as) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
+ else if (fr == NPY_FR_as) { /* entire range is only += 9.2 seconds */
+ npy_int64 num1, num2, num3;
+ num1 = 1000000;
+ num2 = num1 * 1000000;
+ num3 = num2 * 1000000;
+ if (val >= 0) {
+ hour = 0;
+ minute = 0;
+ sec = val / num3;
+ tmp = val % num3;
+ }
+ else {
+ year = 1969;
+ day = 31;
+ month = 12;
+ hour = 23;
+ minute = 59;
+ sec = 60 + (val - (num3-1)) / num3;
+ tmp = (num3-1) + (val+1) % num3;
+ }
+ us = tmp / num2;
+ tmp = tmp % num2;
+ ps = tmp / num1;
+ as = tmp % num1;
}
else {
- PyErr_SetString(PyExc_ValueError, "invalid internal frequency");
+ PyErr_SetString(PyExc_RuntimeError, "invalid internal time resolution");
}
- result.year = year;
- result.month = month;
- result.day = day;
- result.hour = hour;
- result.min = min;
- result.sec = sec;
- result.ms = ms;
- result.us = us;
- result.ns = ns;
- result.ps = ps;
- result.fs = fs;
- result.as = as;
+ result->year = year;
+ result->month = month;
+ result->day = day;
+ result->hour = hour;
+ result->min = min;
+ result->sec = sec;
+ result->us = us;
+ result->ps = ps;
+ result->as = as;
return result;
}
+/* FIXME: Overflow is not handled at all */
+/* To convert from Years, Months, and Business Days, multiplication by the average is done
+ */
-
-/*
-// Takes a long and a frequency
-// Returns a Python DateTime Object
-*/
-static PyObject *
-long_to_datetime(PyObject *self, PyObject *args)
-{
- PyObject *long_arg = NULL; // string or datetime
- PyObject *freq_arg = NULL; // frequency as string
- PyObject *result = NULL; // long result
-
- npy_longlong val = 0; // Stores the long_arg
- int freq = NPY_FR_ERR; // freq_arg is a PyObject to be parsed to freq
- datestruct dstruct; // To store date values
-
- // macro PyDateTime_IMPORT must be invoked for PyDateTime_Check
- PyDateTime_IMPORT;
-
- // Make sure the callback function is set
- // ! This doesn't check to make sure it's the right callback function
- // ! This should all be done in some init script
- if (!PyCallable_Check(callback))
- {
- PyErr_SetString(PyExc_TypeError, "callback not set.");
- return NULL;
- }
-
- // Parse out long_arg & freq_arg
- if (!PyArg_ParseTuple(args, "OO", &long_arg, &freq_arg))
- {
- return NULL;
- }
-
- // Make sure frequency is not NULL
- if (!freq_arg)
- {
- PyErr_SetString(PyExc_TypeError, "frequency not set.");
- return NULL;
- }
-
- // Parse out frequency into an int so we can use it easily
- if ((freq = _unit_from_str(PyString_AsString(freq_arg))) == NPY_FR_ERR)
- {
- // If the frequency is invalid, set an error and return null
- PyErr_SetString(PyExc_TypeError, "invalid frequency.");
- return NULL;
- }
- // Make sure long_arg is not NULL
- if (!long_arg)
- {
- PyErr_SetString(PyExc_TypeError, "no date provided.");
- return NULL;
- }
- // Be sure long_arg is a long
- if (PyLong_Check(long_arg))
- {
-
- // XXX PyINCREF here?
- // Convert long_arg to a long long
- dlong = PyLong_AsLongLong(long_arg);
- // Format the dstruct to create the datetime object
- dstruct = long_to_datestruct(dlong, freq);
- // Create the PyDateTime Object as result
- result = PyDateTime_FromDateAndTime(dstruct.year, dstruct.month,
- dstruct.day, dstruct.hour, dstruct.min, dstruct.second,
- dstruct.msecond * 1000 + dstruct.usecond);
- }
- else
- {
- // long_arg is not a long; error
- PyErr_SetString(PyExc_TypeError, "invalid date type");
- return NULL;
- }
-
- if (PyErr_Occurred())
- return NULL;
-
- return result;
-}
-
-// Takes a long and a frequency
-// Returns a string formatted to represent the date from the long
-static PyObject *
-long_to_datestring(PyObject *self, PyObject *args)
+/*NUMPY_API
+ * Fill the timedelta struct from the timedelta value and resolution unit.
+ */
+NPY_NO_EXPORT void
+PyArray_TimedeltaToTimedeltaStruct(npy_timdelta val, NPY_DATETIME_UNIT fr,
+ npy_timedeltastruct *result)
{
- PyObject *long_arg = NULL; // string or datetime
- PyObject *freq_arg = NULL; // frequency as string
- PyObject *result = NULL; // string result
-
- npy_longlong dlong = 0; // Stores the long_arg
- int freq = NPY_FR_ERR; // freq_arg is a PyObject to be parsed to freq
- datestruct dstruct; // To store date values
-
- // macro PyDateTime_IMPORT must be invoked for PyDateTime_Check
- PyDateTime_IMPORT;
-
- // Make sure the callback function is set
- // ! This doesn't check to make sure it's the right callback function
- // ! This should all be done in some init script
- if (!PyCallable_Check(callback))
- {
- PyErr_SetString(PyExc_TypeError, "callback not set.");
- return NULL;
- }
-
- // Parse out long_arg & freq_arg
- if (!PyArg_ParseTuple(args, "OO", &long_arg, &freq_arg))
- {
- return NULL;
- }
-
- // Make sure frequency is not NULL
- if (!freq_arg)
- {
- PyErr_SetString(PyExc_TypeError, "frequency not set.");
- return NULL;
- }
-
- // Parse out frequency into an int so we can use it easily
- if ((freq = _unit_from_str(PyString_AsString(freq_arg))) == NPY_FR_ERR)
- {
- // If the frequency is invalid, set an error and return null
- PyErr_SetString(PyExc_TypeError, "invalid frequency.");
- return NULL;
- }
- // Make sure long_arg is not NULL
- if (!long_arg)
- {
- PyErr_SetString(PyExc_TypeError, "no date provided.");
- return NULL;
- }
- // Be sure long_arg is a long
- if (PyLong_Check(long_arg))
- {
-
- // XXX PyINCREF here?
- // Convert long_arg to a long long
- dlong = PyLong_AsLongLong(long_arg);
- // Format the dstruct to create the datetime object
- dstruct = long_to_datestruct(dlong, freq);
- // Make sure date is less than 4 digits
- if (dstruct.year > 9999)
- {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
- return NULL;
- }
- // Create the Python String formatted according frequency
- if ((freq == NPY_FR_Y) || (freq == (NPY_FR_M) ||
- (freq == NPY_FR_W) || (freq == NPY_FR_B) || freq == (NPY_FR_D))) {
- // Good. PyString_FromFormat won't let me do simple printf stuff
- // like "%04d-%02d-%02d" for simple date formatting.
- // Now I have to write this stuff from scratch...
-
- char year[4];
- char month[2];
- char day[2];
-
- sprintf(year, "%04d", dstruct.year);
- sprintf(month, "%02d", dstruct.month);
- sprintf(day, "%02d", dstruct.day);
-
- // Now form the result with our char*
- result = PyString_FromFormat("%s-%s-%s", year, month, day);
- } else if ((freq == NPY_FR_h) || (freq == NPY_FR_m) || freq == (NPY_FR_s)) {
- char year[4];
- char month[2];
- char day[2];
- char hour[2];
- char min[2];
- char second[2];
-
- sprintf(year, "%04d", dstruct.year);
- sprintf(month, "%02d", dstruct.month);
- sprintf(day, "%02d", dstruct.day);
- sprintf(hour, "%02d", dstruct.hour);
- sprintf(minute, "%02d", dstruct.minute);
- sprintf(second, "%02d", dstruct.second);
-
- result = PyString_FromFormat("%s-%s-%s %s:%s:%s", year,
- month, day, hour, minute, second);
- } else if ((freq == NPY_FR_ms) || (freq == NPY_FR_us)) {
- char year[4];
- char month[2];
- char day[2];
- char hour[2];
- char minute[2];
- char second[2];
- char msecond[3];
- char usecond[3];
-
- sprintf(year, "%04d", dstruct.year);
- sprintf(month, "%02d", dstruct.month);
- sprintf(day, "%02d", dstruct.day);
- sprintf(hour, "%02d", dstruct.hour);
- sprintf(minute, "%02d", dstruct.minute);
- sprintf(second, "%02d", dstruct.second);
- sprintf(msecond, "%03d", dstruct.msecond);
- sprintf(usecond, "%03d", dstruct.usecond);
- if ((dstruct.usecond) || (dstruct.msecond))
- {
- result = PyString_FromFormat("%s-%s-%s %s:%s:%s.%s%s",
- year, month, day,
- hour, minute, second,
- msecond, usecond);
- //result = PyString_FromFormat("ms: %s -- us: %s", msecond, usecond);
- }
- else
- {
- result = PyString_FromFormat("%s-%s-%s %s:%s:%s",
- year, month, day,
- hour, minute, second);
- }
- }
- }
- else
- {
- // long_arg is not a long; error
- PyErr_SetString(PyExc_TypeError, "invalid date type");
- return NULL;
- }
-
- if (PyErr_Occurred())
- return NULL;
-
- return result;
-}
-
-//==================================================
-// Frequency Conversions
-//==================================================
-
-// Taken from TimeSeries //
-// helpers for frequency conversion routines
-/*
- static long DtoB_weekday(long fromDate) { return (((fromDate) / 7) * 5) + (fromDate)%7; }
-
- static long DtoB_WeekendToMonday(long absdate, int day_of_week) {
-
- if (day_of_week > 4) {
- //change to Monday after weekend
- absdate += (7 - day_of_week);
- }
- return DtoB_weekday(absdate);
- }
-
- static long DtoB_WeekendToFriday(long absdate, int day_of_week) {
-
- if (day_of_week > 4) {
- //change to friday before weekend
- absdate -= (day_of_week - 4);
- }
- return DtoB_weekday(absdate);
- }
-*/
-
-
-// Taken from TimeSeries //
-// conversion routines for frequencies
+ npy_longlong day=0;
+ int sec=0, us=0, ps=0, as=0;
+ npy_bool negative=0;
+ /* Note that what looks like val / N and val % N for positive numbers maps to
+ [val - (N-1)] / N and [N-1 + (val+1) % N] for negative numbers (with the 2nd
+ value, the remainder, being positive in both cases).
+ */
-// *************** From Day *************** //
-static npy_longlong as_freq_D2Y(npy_longlong dlong)
-{
- ymdstruct ymd = days_to_ymdstruct(dlong);
- return ymd.year - 1970;
-}
-static npy_longlong as_freq_D2M(npy_longlong dlong)
-{
- ymdstruct ymd = days_to_ymdstruct(dlong);
- return ymd.month + (ymd.year - 1970) * 12 - 1;
-}
-static npy_longlong as_freq_D2W(npy_longlong dlong)
-{
- // convert to the previous Sunday
- int dotw = day_of_week(dlong);
- if (dlong < 0)
- return (dlong - dotw) / 7;
- else
- return (dlong + 4) / 7;
-}
-static npy_longlong as_freq_D2B(npy_longlong dlong)
-{
- int dotw = day_of_week(dlong);
- // Pre epoch
- if (dlong < 0)
- {
- // To get beyond Sunday, Dec 28, 1969
- if (dlong < -4) {
- // Offset by 1 for Sundays
- if (dotw)
- return ((dlong + 7 - dotw) / 7) * 5 - (6 - dotw) - 3;
- else
- return ((dlong + 7 - dotw) / 7) * 5 - (6 - dotw) - 2;
- } else {
- // Offset by 1 for Sundays
- if (dotw)
- return -4 + dotw;
- else
- return -3; // Sunday, Dec 28, 1969
- }
- // Post epoch
- } else {
- // To get to Sunday, Jan 4, 1970
- // number of weeks * 5 + dotw [0-6] - Saturdays + 1 for offset
- if (dlong > 2)
- return ((dlong - dotw) / 7) * 5 + dotw - (dotw / 6) + 1;
- else
- return dotw - 4 - (dotw / 6);
+ if (val < 0) {
+ val = -val;
+ negative = 1;
}
-}
-static npy_longlong as_freq_D2h(npy_longlong dlong)
-{
- return dlong * 24LL;
-}
-static npy_longlong as_freq_D2m(npy_longlong dlong)
-{
- return dlong * 1440LL;
-}
-static npy_longlong as_freq_D2s(npy_longlong dlong)
-{
- return dlong * 86400LL;
-}
-static npy_longlong as_freq_D2ms(npy_longlong dlong)
-{
- return dlong * 86400000LL;
-}
-static npy_longlong as_freq_D2us(npy_longlong dlong)
-{
- return dlong * 86400000000LL;
-}
-static npy_longlong as_freq_D2ns(npy_longlong dlong)
-{
- return dlong * 86400000000000LL;
-}
-static npy_longlong as_freq_D2ps(npy_longlong dlong)
-{
- return dlong * 86400000000000000LL;
-}
-static npy_longlong as_freq_D2fs(npy_longlong dlong)
-{
- return 0;
- // should throw an error...
- //return dlong * 86400000000000000000LL;
-}
-static npy_longlong as_freq_D2as(npy_longlong dlong)
-{
- return 0;
- // should throw an error...
- //return dlong * 86400000000000000000000LL;
-}
-
-// *************** From Year *************** //
-static npy_longlong as_freq_Y2D(npy_longlong dlong)
-{
- npy_longlong absdays = absdays_from_ymd(1970 + dlong, 1, 1);
- return absdays;
-}
-static npy_longlong as_freq_Y2M(npy_longlong dlong)
-{
- return dlong * 12;
-}
-static npy_longlong as_freq_Y2W(npy_longlong dlong)
-{
- return as_freq_D2W(as_freq_Y2D(dlong));
-}
-static npy_longlong as_freq_Y2B(npy_longlong dlong)
-{
- return as_freq_D2B(as_freq_Y2D(dlong));
-}
-static npy_longlong as_freq_Y2h(npy_longlong dlong)
-{
- return as_freq_Y2D(dlong) * 24;
-}
-static npy_longlong as_freq_Y2m(npy_longlong dlong)
-{
- return as_freq_Y2D(dlong) * 1440;
-}
-static npy_longlong as_freq_Y2s(npy_longlong dlong)
-{
- return as_freq_Y2D(dlong) * 86400;
-}
-static npy_longlong as_freq_Y2ms(npy_longlong dlong)
-{
- return as_freq_Y2D(dlong) * 86400000LL;
-}
-static npy_longlong as_freq_Y2us(npy_longlong dlong)
-{
- return as_freq_Y2D(dlong) * 86400000000LL;
-}
-static npy_longlong as_freq_Y2ns(npy_longlong dlong)
-{
- return as_freq_Y2D(dlong) * 86400000000000LL;
-}
-static npy_longlong as_freq_Y2ps(npy_longlong dlong)
-{
- return as_freq_Y2D(dlong) * 86400000000000000LL;
-}
-static npy_longlong as_freq_Y2fs(npy_longlong dlong)
-{
- return 0;
- // should return an error
- // return as_freq_Y2D(dlong) * 86400000000000000000LL;
-}
-static npy_longlong as_freq_Y2as(npy_longlong dlong)
-{
- return 0;
- // should return an error
- // return as_freq_Y2D(dlong) * 86400000000000000000000LL;
-}
-
-// *************** From Month *************** //
-// Taken from TimeSeries
-static npy_longlong as_freq_M2D(npy_longlong dlong)
-{
- npy_longlong absdays;
- long y;
- long m;
-
- if (dlong < 0) {
- y = (dlong + 1) / 12 - 1;
- m = 12 + (dlong + 1) % 12;
- if (!m) { m = 12; }
- absdays = absdays_from_ymd(1970 + y, m, 1);
- return absdays;
- } else {
- y = (dlong) / 12;
- m = dlong % 12 + 1;
- absdays = absdays_from_ymd(1970 + y, m, 1);
- return absdays;
+ if (fr == NPY_FR_Y) {
+ day = val * _DAYS_PER_YEAR;
+ }
+ else if (fr == NPY_FR_M) {
+ day = val * _DAYS_PER_MONTH;
+ }
+ else if (fr == NPY_FR_W) {
+ day = val * 7;
+ }
+ else if (fr == NPY_FR_B) { /* Number of business days since Thursday, 1-1-70 */
+ day = (val * 7) / 5;
+ }
+ else if (fr == NPY_FR_D) {
+ day = val;
+ }
+ else if (fr == NPY_FR_h) {
+ day = val / 24;
+ sec = (val % 24)*3600;
+ }
+ else if (fr == NPY_FR_m) {
+ day = val / 1440;
+ sec = (val % 1440)*60;
+ }
+ else if (fr == NPY_FR_s) {
+ day = val / 86400;
+ sec = val % 86400;
}
-}
-static npy_longlong as_freq_M2Y(npy_longlong dlong)
-{
- if (dlong < 0)
- return (dlong + 1) / 12 - 1;
- return dlong / 12;
-}
-static npy_longlong as_freq_M2W(npy_longlong dlong)
-{
- return as_freq_D2W(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2B(npy_longlong dlong)
-{
- return as_freq_D2B(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2h(npy_longlong dlong)
-{
- return as_freq_D2h(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2m(npy_longlong dlong)
-{
- return as_freq_D2m(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2s(npy_longlong dlong)
-{
- return as_freq_D2s(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2ms(npy_longlong dlong)
-{
- return as_freq_D2ms(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2us(npy_longlong dlong)
-{
- return as_freq_D2us(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2ns(npy_longlong dlong)
-{
- return as_freq_D2ns(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2ps(npy_longlong dlong)
-{
- return as_freq_D2ps(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2fs(npy_longlong dlong)
-{
- return as_freq_D2fs(as_freq_M2D(dlong));
-}
-static npy_longlong as_freq_M2as(npy_longlong dlong)
-{
- return as_freq_D2as(as_freq_M2D(dlong));
-}
-
-// *************** From Week *************** //
-static npy_longlong as_freq_W2D(npy_longlong dlong)
-{
- return (dlong * 7) - 4;
-}
-static npy_longlong as_freq_W2Y(npy_longlong dlong)
-{
- return as_freq_D2Y(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2M(npy_longlong dlong)
-{
- return as_freq_D2M(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2B(npy_longlong dlong)
-{
- return as_freq_D2B(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2h(npy_longlong dlong)
-{
- return as_freq_D2h(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2m(npy_longlong dlong)
-{
- return as_freq_D2m(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2s(npy_longlong dlong)
-{
- return as_freq_D2s(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2ms(npy_longlong dlong)
-{
- return as_freq_D2ms(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2us(npy_longlong dlong)
-{
- return as_freq_D2us(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2ns(npy_longlong dlong)
-{
- return as_freq_D2ns(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2ps(npy_longlong dlong)
-{
- return as_freq_D2ps(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2fs(npy_longlong dlong)
-{
- return as_freq_D2fs(as_freq_W2D(dlong));
-}
-static npy_longlong as_freq_W2as(npy_longlong dlong)
-{
- return as_freq_D2as(as_freq_W2D(dlong));
-}
-
-// *************** From Business Day *************** //
-static npy_longlong as_freq_B2D(npy_longlong dlong)
-{
- if (dlong < 0) {
- // Special Case
- if (dlong > -7)
- return dlong + (dlong / 4) * 2;
- else
- return 7 * ((dlong - 1) / 5) + ((dlong - 1) % 5) + 1;
- } else {
- // Special Case
- if (dlong < 3)
- return dlong + (dlong / 2) * 2;
- else
- return 7 * ((dlong + 3) / 5) + ((dlong + 3) % 5) - 3;
+ else if (fr == NPY_FR_ms) {
+ day = val / 86400000;
+ val = val % 86400000;
+ sec = val / 1000;
+ us = (val % 1000)*1000;
}
-}
-static npy_longlong as_freq_B2Y(npy_longlong dlong)
-{
- return as_freq_D2Y(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2M(npy_longlong dlong)
-{
- return as_freq_D2M(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2W(npy_longlong dlong)
-{
- return as_freq_D2W(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2h(npy_longlong dlong)
-{
- return as_freq_D2h(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2m(npy_longlong dlong)
-{
- return as_freq_D2m(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2s(npy_longlong dlong)
-{
- return as_freq_D2s(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2ms(npy_longlong dlong)
-{
- return as_freq_D2ms(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2us(npy_longlong dlong)
-{
- return as_freq_D2us(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2ns(npy_longlong dlong)
-{
- return as_freq_D2ns(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2ps(npy_longlong dlong)
-{
- return as_freq_D2ps(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2fs(npy_longlong dlong)
-{
- return as_freq_D2fs(as_freq_B2D(dlong));
-}
-static npy_longlong as_freq_B2as(npy_longlong dlong)
-{
- return as_freq_D2as(as_freq_B2D(dlong));
-}
-
-// *************** From Hour *************** //
-static npy_longlong as_freq_h2D(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 24 - 1;
- return dlong / 24;
-}
-static npy_longlong as_freq_h2Y(npy_longlong dlong)
-{
- return as_freq_D2Y(as_freq_h2D(dlong));
-}
-static npy_longlong as_freq_h2M(npy_longlong dlong)
-{
- return as_freq_D2M(as_freq_h2D(dlong));
-}
-static npy_longlong as_freq_h2W(npy_longlong dlong)
-{
- return as_freq_D2W(as_freq_h2D(dlong));
-}
-static npy_longlong as_freq_h2B(npy_longlong dlong)
-{
- return as_freq_D2B(as_freq_h2D(dlong));
-}
-// these are easier to think about with a simple calculation
-static npy_longlong as_freq_h2m(npy_longlong dlong)
-{
- return dlong * 60;
-}
-static npy_longlong as_freq_h2s(npy_longlong dlong)
-{
- return dlong * 3600;
-}
-static npy_longlong as_freq_h2ms(npy_longlong dlong)
-{
- return dlong * 3600000;
-}
-static npy_longlong as_freq_h2us(npy_longlong dlong)
-{
- return dlong * 3600000000LL;
-}
-static npy_longlong as_freq_h2ns(npy_longlong dlong)
-{
- return dlong * 3600000000000LL;
-}
-static npy_longlong as_freq_h2ps(npy_longlong dlong)
-{
- return dlong * 3600000000000000LL;
-}
-static npy_longlong as_freq_h2fs(npy_longlong dlong)
-{
- return dlong * 3600000000000000000LL;
-}
-static npy_longlong as_freq_h2as(npy_longlong dlong)
-{
- return 0;
- // should return an error...
- //return dlong * 3600000000000000000000LL;
-}
-
-// *************** From Minute *************** //
-static npy_longlong as_freq_m2D(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 1440 - 1;
- return dlong / 1440;
-}
-static npy_longlong as_freq_m2Y(npy_longlong dlong)
-{
- return as_freq_D2Y(as_freq_m2D(dlong));
-}
-static npy_longlong as_freq_m2M(npy_longlong dlong)
-{
- return as_freq_D2M(as_freq_m2D(dlong));
-}
-static npy_longlong as_freq_m2W(npy_longlong dlong)
-{
- return as_freq_D2W(as_freq_m2D(dlong));
-}
-static npy_longlong as_freq_m2B(npy_longlong dlong)
-{
- return as_freq_D2B(as_freq_m2D(dlong));
-}
-// these are easier to think about with a simple calculation
-static npy_longlong as_freq_m2h(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 60 - 1;
- return dlong / 60;
-}
-static npy_longlong as_freq_m2s(npy_longlong dlong)
-{
- return dlong * 60;
-}
-static npy_longlong as_freq_m2ms(npy_longlong dlong)
-{
- return dlong * 60000;
-}
-static npy_longlong as_freq_m2us(npy_longlong dlong)
-{
- return dlong * 60000000LL;
-}
-static npy_longlong as_freq_m2ns(npy_longlong dlong)
-{
- return dlong * 60000000000LL;
-}
-static npy_longlong as_freq_m2ps(npy_longlong dlong)
-{
- return dlong * 60000000000000LL;
-}
-static npy_longlong as_freq_m2fs(npy_longlong dlong)
-{
- return dlong * 60000000000000000LL;
-}
-static npy_longlong as_freq_m2as(npy_longlong dlong)
-{
- return 0;
- // should return an error...
- //return dlong * 60000000000000000000LL;
-}
-
-// *************** From Second *************** //
-static npy_longlong as_freq_s2D(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 86400 - 1;
- return dlong / 86400;
-}
-static npy_longlong as_freq_s2Y(npy_longlong dlong)
-{
- return as_freq_D2Y(as_freq_s2D(dlong));
-}
-static npy_longlong as_freq_s2M(npy_longlong dlong)
-{
- return as_freq_D2M(as_freq_s2D(dlong));
-}
-static npy_longlong as_freq_s2W(npy_longlong dlong)
-{
- return as_freq_D2W(as_freq_s2D(dlong));
-}
-static npy_longlong as_freq_s2B(npy_longlong dlong)
-{
- return as_freq_D2B(as_freq_s2D(dlong));
-}
-// these are easier to think about with a simple calculation
-static npy_longlong as_freq_s2h(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 3600 - 1;
- return dlong / 3600;
-}
-static npy_longlong as_freq_s2m(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 60 - 1;
- return dlong / 60;
-}
-static npy_longlong as_freq_s2ms(npy_longlong dlong)
-{
- return dlong * 1000;
-}
-static npy_longlong as_freq_s2us(npy_longlong dlong)
-{
- return dlong * 1000000;
-}
-static npy_longlong as_freq_s2ns(npy_longlong dlong)
-{
- return dlong * 1000000000LL;
-}
-static npy_longlong as_freq_s2ps(npy_longlong dlong)
-{
- return dlong * 1000000000000LL;
-}
-static npy_longlong as_freq_s2fs(npy_longlong dlong)
-{
- return dlong * 1000000000000000LL;
-}
-static npy_longlong as_freq_s2as(npy_longlong dlong)
-{
- return dlong * 1000000000000000000LL;
-}
-
-// *************** From Millisecond *************** //
-static npy_longlong as_freq_ms2D(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 86400000 - 1;
- return dlong / 86400000;
-}
-static npy_longlong as_freq_ms2Y(npy_longlong dlong)
-{
- return as_freq_D2Y(as_freq_ms2D(dlong));
-}
-static npy_longlong as_freq_ms2M(npy_longlong dlong)
-{
- return as_freq_D2M(as_freq_ms2D(dlong));
-}
-static npy_longlong as_freq_ms2W(npy_longlong dlong)
-{
- return as_freq_D2W(as_freq_ms2D(dlong));
-}
-static npy_longlong as_freq_ms2B(npy_longlong dlong)
-{
- return as_freq_D2B(as_freq_ms2D(dlong));
-}
-// these are easier to think about with a simple calculation
-static npy_longlong as_freq_ms2h(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 3600000 - 1;
- return dlong / 3600000;
-}
-static npy_longlong as_freq_ms2m(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 60000 - 1;
- return dlong / 60000;
-}
-static npy_longlong as_freq_ms2s(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 1000 - 1;
- return dlong / 1000;
-}
-static npy_longlong as_freq_ms2us(npy_longlong dlong)
-{
- return dlong * 1000;
-}
-static npy_longlong as_freq_ms2ns(npy_longlong dlong)
-{
- return dlong * 1000000;
-}
-static npy_longlong as_freq_ms2ps(npy_longlong dlong)
-{
- return dlong * 1000000000LL;
-}
-static npy_longlong as_freq_ms2fs(npy_longlong dlong)
-{
- return dlong * 1000000000000LL;
-}
-static npy_longlong as_freq_ms2as(npy_longlong dlong)
-{
- return dlong * 1000000000000000LL;
-}
-
-// *************** From Microsecond *************** //
-static npy_longlong as_freq_us2D(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 86400000000LL - 1;
- return dlong / 86400000000LL;
-}
-static npy_longlong as_freq_us2Y(npy_longlong dlong)
-{
- return as_freq_D2Y(as_freq_us2D(dlong));
-}
-static npy_longlong as_freq_us2M(npy_longlong dlong)
-{
- return as_freq_D2M(as_freq_us2D(dlong));
-}
-static npy_longlong as_freq_us2W(npy_longlong dlong)
-{
- return as_freq_D2W(as_freq_us2D(dlong));
-}
-static npy_longlong as_freq_us2B(npy_longlong dlong)
-{
- return as_freq_D2B(as_freq_us2D(dlong));
-}
-// these are easier to think about with a simple calculation
-static npy_longlong as_freq_us2h(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 3600000000LL - 1;
- return dlong / 3600000000LL;
-}
-static npy_longlong as_freq_us2m(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 60000000LL - 1;
- return dlong / 60000000LL;
-}
-static npy_longlong as_freq_us2s(npy_longlong dlong)
-{
- if (dlong < 0)
- return dlong / 1000000LL - 1;
- return dlong / 1000000LL;
-}
-static npy_longlong as_freq_us2ms(npy_longlong dlong)
-{
- // We're losing precision on XX:XX:XX.xx1 times for some reason
- // can't find a fix, so here's a cheap hack...
- if ((dlong < 0) && ((dlong % 10000) != -9000))
- return dlong / 1000LL - 1;
- return dlong / 1000LL;
-}
-static npy_longlong as_freq_us2ns(npy_longlong dlong)
-{
- return dlong * 1000000LL;
-}
-static npy_longlong as_freq_us2ps(npy_longlong dlong)
-{
- return dlong * 1000000000LL;
-}
-static npy_longlong as_freq_us2fs(npy_longlong dlong)
-{
- return dlong * 1000000000000LL;
-}
-static npy_longlong as_freq_us2as(npy_longlong dlong)
-{
- return dlong * 1000000000000000LL;
-}
-
-
-// ******* THESE ARE UNSUPPORTED CURRENTLY ******* //
-// *********************************************** //
-// *************** From Nanosecond *************** //
-// *********************************************** //
-static npy_longlong as_freq_ns2D(npy_longlong dlong)
-{
- return as_freq_s2D(dlong) * 1000000000LL;
-}
-static npy_longlong as_freq_ns2Y(npy_longlong dlong)
-{
- return as_freq_D2Y(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2M(npy_longlong dlong)
-{
- return as_freq_D2M(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2W(npy_longlong dlong)
-{
- return as_freq_D2W(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2B(npy_longlong dlong)
-{
- return as_freq_D2B(as_freq_ns2D(dlong));
-}
-// these are easier to think about with a simple calculation
-static npy_longlong as_freq_ns2h(npy_longlong dlong)
-{
- return as_freq_D2h(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2m(npy_longlong dlong)
-{
- return as_freq_D2m(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2s(npy_longlong dlong)
-{
- return as_freq_D2s(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2ms(npy_longlong dlong)
-{
- return as_freq_D2ms(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2us(npy_longlong dlong)
-{
- return as_freq_D2us(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2ps(npy_longlong dlong)
-{
- return as_freq_D2ps(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2fs(npy_longlong dlong)
-{
- return as_freq_D2fs(as_freq_ns2D(dlong));
-}
-static npy_longlong as_freq_ns2as(npy_longlong dlong)
-{
- return as_freq_D2as(as_freq_ns2D(dlong));
-}
-
-// *************** From Picosecond *************** //
-static npy_longlong as_freq_ps2Y(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2M(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2W(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2B(npy_longlong dlong)
-{
- return dlong;
-}
-// these are easier to think about with a simple calculation
-static npy_longlong as_freq_ps2h(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2m(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2s(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2ms(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2us(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2ns(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2D(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2fs(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_ps2as(npy_longlong dlong)
-{
- return dlong;
-}
-
-// *************** From Femtosecond *************** //
-static npy_longlong as_freq_fs2Y(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2M(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2W(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2B(npy_longlong dlong)
-{
- return dlong;
-}
-// these are easier to think about with a simple calculation
-static npy_longlong as_freq_fs2h(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2m(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2s(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2ms(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2us(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2ns(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2ps(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2D(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_fs2as(npy_longlong dlong)
-{
- return dlong;
-}
-
-// *************** From Attosecond *************** //
-static npy_longlong as_freq_as2Y(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2M(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2W(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2B(npy_longlong dlong)
-{
- return dlong;
-}
-// these are easier to think about with a simple calculation
-static npy_longlong as_freq_as2h(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2m(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2s(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2ms(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2us(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2ns(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2ps(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2fs(npy_longlong dlong)
-{
- return dlong;
-}
-static npy_longlong as_freq_as2D(npy_longlong dlong)
-{
- return dlong;
-}
-
-static npy_longlong NO_FUNC(npy_longlong empty)
-{ return empty; }
-
-// Convert (dlong, ifreq) to a new date based on ofreq
-// Returns the long value to represent the date with the ofreq
-static npy_longlong (*get_conversion_ftn(int ifreq, int ofreq)) (npy_longlong)
-{
- if (ifreq == ofreq)
- return &NO_FUNC;// Error out
-
- // Switch to decide which routine to run
- switch (ifreq)
- {
- case NPY_FR_Y:
- switch (ofreq)
- {
- case NPY_FR_M: return &as_freq_Y2M; break;
- case NPY_FR_W: return &as_freq_Y2W; break;
- case NPY_FR_B: return &as_freq_Y2B; break;
- case NPY_FR_D: return &as_freq_Y2D; break;
- case NPY_FR_h: return &as_freq_Y2h; break;
- case NPY_FR_m: return &as_freq_Y2m; break;
- case NPY_FR_s: return &as_freq_Y2s; break;
- case NPY_FR_ms:return &as_freq_Y2ms; break;
- case NPY_FR_us:return &as_freq_Y2us; break;
- case NPY_FR_ns:return &as_freq_Y2ns; break;
- case NPY_FR_ps:return &as_freq_Y2ps; break;
- case NPY_FR_fs:return &as_freq_Y2fs; break;
- case NPY_FR_as:return &as_freq_Y2as; break;
- }
- break;
- case NPY_FR_M:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_M2Y; break;
- case NPY_FR_W: return &as_freq_M2W; break;
- case NPY_FR_B: return &as_freq_M2B; break;
- case NPY_FR_D: return &as_freq_M2D; break;
- case NPY_FR_h: return &as_freq_M2h; break;
- case NPY_FR_m: return &as_freq_M2m; break;
- case NPY_FR_s: return &as_freq_M2s; break;
- case NPY_FR_ms: return &as_freq_M2ms; break;
- case NPY_FR_us: return &as_freq_M2us; break;
- case NPY_FR_ns: return &as_freq_M2ns; break;
- case NPY_FR_ps: return &as_freq_M2ps; break;
- case NPY_FR_fs: return &as_freq_M2fs; break;
- case NPY_FR_as: return &as_freq_M2as; break;
- }
- break;
- case NPY_FR_W:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_W2Y; break;
- case NPY_FR_M: return &as_freq_W2M; break;
- case NPY_FR_B: return &as_freq_W2B; break;
- case NPY_FR_D: return &as_freq_W2D; break;
- case NPY_FR_h: return &as_freq_W2h; break;
- case NPY_FR_m: return &as_freq_W2m; break;
- case NPY_FR_s: return &as_freq_W2s; break;
- case NPY_FR_ms: return &as_freq_W2ms; break;
- case NPY_FR_us: return &as_freq_W2us; break;
- case NPY_FR_ns: return &as_freq_W2ns; break;
- case NPY_FR_ps: return &as_freq_W2ps; break;
- case NPY_FR_fs: return &as_freq_W2fs; break;
- case NPY_FR_as: return &as_freq_W2as; break;
- }
- break;
- case NPY_FR_B:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_B2Y; break;
- case NPY_FR_M: return &as_freq_B2M; break;
- case NPY_FR_W: return &as_freq_B2W; break;
- case NPY_FR_D: return &as_freq_B2D; break;
- case NPY_FR_h: return &as_freq_B2h; break;
- case NPY_FR_m: return &as_freq_B2m; break;
- case NPY_FR_s: return &as_freq_B2s; break;
- case NPY_FR_ms: return &as_freq_B2ms; break;
- case NPY_FR_us: return &as_freq_B2us; break;
- case NPY_FR_ns: return &as_freq_B2ns; break;
- case NPY_FR_ps: return &as_freq_B2ps; break;
- case NPY_FR_fs: return &as_freq_B2fs; break;
- case NPY_FR_as: return &as_freq_B2as; break;
- }
- break;
- case NPY_FR_D:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_D2Y; break;
- case NPY_FR_M: return &as_freq_D2M; break;
- case NPY_FR_W: return &as_freq_D2W; break;
- case NPY_FR_B: return &as_freq_D2B; break;
- case NPY_FR_h: return &as_freq_D2h; break;
- case NPY_FR_m: return &as_freq_D2m; break;
- case NPY_FR_s: return &as_freq_D2s; break;
- case NPY_FR_ms: return &as_freq_D2ms; break;
- case NPY_FR_us: return &as_freq_D2us; break;
- case NPY_FR_ns: return &as_freq_D2ns; break;
- case NPY_FR_ps: return &as_freq_D2ps; break;
- case NPY_FR_fs: return &as_freq_D2fs; break;
- case NPY_FR_as: return &as_freq_D2as; break;
- }
- break;
- case NPY_FR_h:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_h2Y; break;
- case NPY_FR_M: return &as_freq_h2M; break;
- case NPY_FR_W: return &as_freq_h2W; break;
- case NPY_FR_B: return &as_freq_h2B; break;
- case NPY_FR_D: return &as_freq_h2D; break;
- case NPY_FR_m: return &as_freq_h2m; break;
- case NPY_FR_s: return &as_freq_h2s; break;
- case NPY_FR_ms: return &as_freq_h2ms; break;
- case NPY_FR_us: return &as_freq_h2us; break;
- case NPY_FR_ns: return &as_freq_h2ns; break;
- case NPY_FR_ps: return &as_freq_h2ps; break;
- case NPY_FR_fs: return &as_freq_h2fs; break;
- case NPY_FR_as: return &as_freq_h2as; break;
- }
- break;
- case NPY_FR_m:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_m2Y; break;
- case NPY_FR_M: return &as_freq_m2M;
- case NPY_FR_W: return &as_freq_m2W; break;
- case NPY_FR_B: return &as_freq_m2B; break;
- case NPY_FR_D: return &as_freq_m2D; break;
- case NPY_FR_h: return &as_freq_m2h; break;
- case NPY_FR_s: return &as_freq_m2s; break;
- case NPY_FR_us: return &as_freq_m2us; break;
- case NPY_FR_ms: return &as_freq_m2ms; break;
- case NPY_FR_ns: return &as_freq_m2ns; break;
- case NPY_FR_ps: return &as_freq_m2ps; break;
- case NPY_FR_fs: return &as_freq_m2fs; break;
- case NPY_FR_as: return &as_freq_m2as; break;
- }
- break;
- case NPY_FR_s:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_s2Y; break;
- case NPY_FR_M: return &as_freq_s2M; break;
- case NPY_FR_W: return &as_freq_s2W; break;
- case NPY_FR_B: return &as_freq_s2B; break;
- case NPY_FR_D: return &as_freq_s2D; break;
- case NPY_FR_h: return &as_freq_s2h; break;
- case NPY_FR_m: return &as_freq_s2m; break;
- case NPY_FR_ms: return &as_freq_s2ms; break;
- case NPY_FR_us: return &as_freq_s2us; break;
- case NPY_FR_ns: return &as_freq_s2ns; break;
- case NPY_FR_ps: return &as_freq_s2ps; break;
- case NPY_FR_fs: return &as_freq_s2fs; break;
- case NPY_FR_as: return &as_freq_s2as; break;
- }
- break;
- case NPY_FR_ms:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_ms2Y; break;
- case NPY_FR_M: return &as_freq_ms2M; break;
- case NPY_FR_W: return &as_freq_ms2W; break;
- case NPY_FR_B: return &as_freq_ms2B; break;
- case NPY_FR_D: return &as_freq_ms2D; break;
- case NPY_FR_h: return &as_freq_ms2h; break;
- case NPY_FR_m: return &as_freq_ms2m; break;
- case NPY_FR_s: return &as_freq_ms2s; break;
- case NPY_FR_us: return &as_freq_ms2us; break;
- case NPY_FR_ns: return &as_freq_ms2ns; break;
- case NPY_FR_ps: return &as_freq_ms2ps; break;
- case NPY_FR_fs: return &as_freq_ms2fs; break;
- case NPY_FR_as: return &as_freq_ms2as; break;
- }
- break;
- case NPY_FR_us:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_us2Y; break;
- case NPY_FR_M: return &as_freq_us2M; break;
- case NPY_FR_W: return &as_freq_us2W; break;
- case NPY_FR_B: return &as_freq_us2B; break;
- case NPY_FR_D: return &as_freq_us2D; break;
- case NPY_FR_h: return &as_freq_us2h; break;
- case NPY_FR_m: return &as_freq_us2m; break;
- case NPY_FR_s: return &as_freq_us2s; break;
- case NPY_FR_ms: return &as_freq_us2ms; break;
- case NPY_FR_ns: return &as_freq_us2ns; break;
- case NPY_FR_ps: return &as_freq_us2ps; break;
- case NPY_FR_fs: return &as_freq_us2fs; break;
- case NPY_FR_as: return &as_freq_us2as; break;
- }
- break;
- case NPY_FR_ns:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_ns2Y; break;
- case NPY_FR_M: return &as_freq_ns2M; break;
- case NPY_FR_W: return &as_freq_ns2W; break;
- case NPY_FR_B: return &as_freq_ns2B; break;
- case NPY_FR_D: return &as_freq_ns2D; break;
- case NPY_FR_h: return &as_freq_ns2h; break;
- case NPY_FR_m: return &as_freq_ns2m; break;
- case NPY_FR_s: return &as_freq_ns2s; break;
- case NPY_FR_ms: return &as_freq_ns2ms; break;
- case NPY_FR_us: return &as_freq_ns2us; break;
- case NPY_FR_ps: return &as_freq_ns2ps; break;
- case NPY_FR_fs: return &as_freq_ns2fs; break;
- case NPY_FR_as: return &as_freq_ns2as; break;
- }
- break;
- case NPY_FR_ps:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_ps2Y; break;
- case NPY_FR_M: return &as_freq_ps2M; break;
- case NPY_FR_W: return &as_freq_ps2W; break;
- case NPY_FR_B: return &as_freq_ps2B; break;
- case NPY_FR_D: return &as_freq_ps2D; break;
- case NPY_FR_h: return &as_freq_ps2h; break;
- case NPY_FR_m: return &as_freq_ps2m; break;
- case NPY_FR_s: return &as_freq_ps2s; break;
- case NPY_FR_ms: return &as_freq_ps2ms; break;
- case NPY_FR_us: return &as_freq_ps2us; break;
- case NPY_FR_ns: return &as_freq_ps2ns; break;
- case NPY_FR_fs: return &as_freq_ps2fs; break;
- case NPY_FR_as: return &as_freq_ps2as; break;
- }
- break;
- case NPY_FR_fs:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_fs2Y; break;
- case NPY_FR_M: return &as_freq_fs2M; break;
- case NPY_FR_W: return &as_freq_fs2W; break;
- case NPY_FR_B: return &as_freq_fs2B; break;
- case NPY_FR_D: return &as_freq_fs2D; break;
- case NPY_FR_h: return &as_freq_fs2h; break;
- case NPY_FR_m: return &as_freq_fs2m; break;
- case NPY_FR_s: return &as_freq_fs2s; break;
- case NPY_FR_ms: return &as_freq_fs2ms; break;
- case NPY_FR_us: return &as_freq_fs2us; break;
- case NPY_FR_ns: return &as_freq_fs2ns; break;
- case NPY_FR_ps: return &as_freq_fs2ps; break;
- case NPY_FR_as: return &as_freq_fs2as; break;
- }
- break;
- case NPY_FR_as:
- switch (ofreq) {
- case NPY_FR_Y: return &as_freq_as2Y; break;
- case NPY_FR_M: return &as_freq_as2M; break;
- case NPY_FR_W: return &as_freq_as2W; break;
- case NPY_FR_B: return &as_freq_as2B; break;
- case NPY_FR_D: return &as_freq_as2D; break;
- case NPY_FR_h: return &as_freq_as2h; break;
- case NPY_FR_m: return &as_freq_as2m; break;
- case NPY_FR_s: return &as_freq_as2s; break;
- case NPY_FR_ms: return &as_freq_as2ms; break;
- case NPY_FR_us: return &as_freq_as2us; break;
- case NPY_FR_ns: return &as_freq_as2ns; break;
- case NPY_FR_ps: return &as_freq_as2ps; break;
- case NPY_FR_fs: return &as_freq_as2fs; break;
- }
- break;
- default:
- return &NO_FUNC;
- break;
- // error out
- }
-
- // error out
- return &NO_FUNC;
-}
-
-// Uses get_conversion_ftn to find which function to return
-static npy_longlong as_freq_to_long(npy_longlong dlong, int ifreq, int ofreq)
-{
- // Needs more error checking, but it works for now
- if (ifreq == ofreq)
- return -1;// Error out
-
- // grab conversion function based on ifreq and ofreq
- npy_longlong (*conversion_ftn)(npy_longlong) = get_conversion_ftn(ifreq, ofreq);
- // return conversion function ran with dlong
- return (*conversion_ftn)(dlong);
-}
-
-// Takes a long and an in frequency ( to emulate a date )
-// and an out frequency to learn the conversion to run
-// OR takes a PyList and an in frequency and outputs a PyList as the second freq
-// Returns a long
-static PyObject *
-convert_freq(PyObject *self, PyObject *args)
-{
- PyObject *main_arg = NULL; // string or datetime
- PyObject *ifreq_arg = NULL; // in frequency as string
- PyObject *ofreq_arg = NULL; // out frequency as string
- PyObject *result = NULL; // long result
-
- npy_longlong dlong = 0; // Stores the main_arg
- int ifreq = NPY_FR_ERR; // freq_arg is a PyObject to be parsed to freq
- int ofreq = NPY_FR_ERR; // freq_arg is a PyObject to be parsed to freq
-
- // Parse out main_arg & freq_arg
- if (!PyArg_ParseTuple(args, "OOO", &main_arg, &ifreq_arg, &ofreq_arg))
- return NULL;
- // Parse the in frequency into an int so we can use it easily
- if ((ifreq = _unit_from_str(PyString_AsString(ifreq_arg))) == NPY_FR_ERR)
- {
- // If the frequency is invalid, set an error and return null
- PyErr_SetString(PyExc_TypeError, "invalid frequency.");
- return NULL;
- }
- // Parse the out frequency into an int so we can use it easily
- if ((ofreq = _unit_from_str(PyString_AsString(ofreq_arg))) == NPY_FR_ERR)
- {
- // If the frequency is invalid, set an error and return null
- PyErr_SetString(PyExc_TypeError, "invalid frequency.");
- return NULL;
- }
-
- // Make sure main_arg is not NULL
- if (!main_arg)
- {
- PyErr_SetString(PyExc_TypeError, "no date provided.");
- return NULL;
- }
- // For Scalars
- if (PyLong_Check(main_arg))
- {
- // XXX PyINCREF here?
- // Convert main_arg to a npy_longlong
- dlong = PyLong_AsLongLong(main_arg);
+ else if (fr == NPY_FR_us) {
+ npy_int64 num1;
+ num1 = 86400 * 1000 * 1000;
+ day = val / num1;
+ us = val % num1;
+ sec = us / 1000000;
+ us = us % 1000000;
+ }
+ else if (fr == NPY_FR_ns) {
+ npy_int64 num1;
+ num1 = 86400 * 1000 * 1000 * 1000;
+ day = val / num1;
+ val = val % num1;
+ sec = val / 1000000000;
+ val = val % 1000000000;
+ us = val / 1000;
+ ps = (val % 1000) * 1000;
+ }
+ else if (fr == NPY_FR_ps) {
+ npy_int64 num1, num2
+ num2 = 1000000000 * 1000;
+ num1 = 86400 * num2;
- // All the basic tests are out of the way, now we need to figure out
- // which frequency conversion to run based on the ofreq
- result = PyLong_FromLongLong(as_freq_to_long(dlong, ifreq, ofreq));
- }
- // For lists
- else if (PyList_Check(main_arg))
- {
- // Result needs to be a list size of main arg
- result = PyList_New(0);
- // get the pointer ftn here
- // We shouldn't just use as_freq_to_long because that checks
- // each ifreq and ofreq. We'll always be using the same ifreq
- // and ofreq, so we just need that one function...
- npy_longlong (*conversion_ftn)(npy_longlong) = get_conversion_ftn(ifreq, ofreq);
- // Iterate through main_arg
- Py_ssize_t idx;
- for (idx = 0; idx < PyList_Size(main_arg); idx++)
- {
- // extract correct value of main arg
- npy_longlong dlong = PyLong_AsLongLong(PyList_GetItem(main_arg, idx));
- npy_longlong resultant_dlong = (*conversion_ftn)(dlong);
- // put calculated dlong into result
- PyList_Append(result,
- PyLong_FromLongLong(resultant_dlong));
- }
- }
- // For NumPy narrays
- else if (PyArray_Check(main_arg))
- {
- // Create new
- }
- else
- {
- PyErr_SetString(PyExc_TypeError, "invalid long entry.");
- return NULL;
- }
- return result;
-}
+ day = val / num1;
+ ps = val % num1;
+ sec = ps / num2;
+ ps = ps % num2;
+ us = ps / 1000000;
+ ps = ps % 1000000;
+ }
+ }
+ else if (fr == NPY_FR_fs) { /* entire range is only += 9.2 hours */
+ npy_int64 num1, num2;
+ num1 = 1000000000;
+ num2 = num1 * 1000000;
+
+ day = 0;
+ sec = val / num2;
+ val = val % num2;
+ us = val / num1;
+ val = val % num1;
+ ps = val / 1000;
+ as = (val % 1000) * 1000;
+ }
+ else if (fr == NPY_FR_as) { /* entire range is only += 2.6 seconds */
+ npy_int64 num1, num2, num3;
+ num1 = 1000000;
+ num2 = num1 * 1000000;
+ num3 = num2 * 1000000;
+ day = 0;
+ sec = val / num3;
+ as = val % num3;
+ us = as / num2;
+ as = as % num2;
+ ps = as / num1;
+ as = as % num1;
+ }
+ else {
+ PyErr_SetString(PyExc_RuntimeError, "invalid internal time resolution");
+ }
-//==================================================
-// TimeDelta
-//==================================================
-// Very similar to datetime_to_long
-// Takes a datetime timedelta object and a string as frequency
-// Returns the number of (frequency) since Jan 1, 1970
-static
-npy_longlong timedelta_to_long(PyObject* timedelta, int frequency)
-{
- int year = 0, month = 0, day = 0, hour = 0,
- minute = 0, second = 0, microsecond = 0;
-
- // Get the time units from PyDateTime
- year = PyDateTime_GET_YEAR(timedelta);
- month = PyDateTime_GET_MONTH(timedelta);
- day = PyDateTime_GET_DAY(timedelta);
- hour = PyDateTime_DATE_GET_HOUR(timedelta);
- minute = PyDateTime_DATE_GET_MINUTE(timedelta);
- second = PyDateTime_DATE_GET_SECOND(timedelta);
- microsecond = PyDateTime_DATE_GET_MICROSECOND(timedelta);
-
- // The return value
- npy_longlong result = 0;
-
- // The absolute number of days since 1970
- npy_longlong absdays = absdays_from_ymd(year, month, day);
-
- // These calculations depend on the frequency
-
- if (frequency == NPY_FR_Y) {
- result = year;
- } else if (frequency == NPY_FR_M) {
- result = (year) * 12 + month - 1;
- } else if (frequency == NPY_FR_W) {
- // 4 day offset for post 1970 to get correct week
- int dotw = day_of_week(absdays);
- if (absdays >= 0)
- result = (absdays + 4) / 7;
- else
- result = (absdays - dotw)/ 7;
- } else if (frequency == NPY_FR_B) {
- int dotw = day_of_week(absdays);
- // To get to Sunday, Jan 4, 1970
- // number of weeks * 5 + dotw [0-6] - Saturdays + 1 for offset
- if (absdays > 2)
- result = ((absdays - dotw) / 7) * 5 + dotw - (dotw / 6) + 1;
- else
- result = dotw - 4 - (dotw / 6);
- } else if (frequency == NPY_FR_D) {
- result = absdays;
- } else if (frequency == NPY_FR_h) {
- result = absdays * 24 + hour;
- } else if (frequency == NPY_FR_m) {
- result = absdays * 1440 + hour * 60 + minute;
- } else if (frequency == NPY_FR_s) {
- result = absdays * 86400LL + abssecs_from_hms(hour, minute, second);
- } else if (frequency == NPY_FR_ms) {
- result = absdays * 86400000LL + abssecs_from_hms(hour, minute, second) * 1000LL
- + (microsecond / 1000LL);
- } else if (frequency == NPY_FR_us) {
- result = absdays * 86400000000LL + abssecs_from_hms(hour, minute, second) * 1000000LL
- + microsecond;
+ if (negative) {
+ result->day = -day;
+ result->sec = -sec;
+ result->us = -us;
+ result->ps = -ps;
+ result->as = -as;
+ }
+ else {
+ result->day = day;
+ result->sec = sec;
+ result->us = us;
+ result->ps = ps;
+ result->as = as;
}
- // Starting from here, we need extra units (ns, ps, fs, as)
- // for correct precision: timedelta doesn't include beyond microsecond
- else if (frequency == NPY_FR_ns) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
- result = 0;
- } else if (frequency == NPY_FR_ps) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
- result = 0;
- } else if (frequency == NPY_FR_fs) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
- result = 0;
- } else if (frequency == NPY_FR_as) {
- PyErr_SetString(PyExc_NotImplementedError, "not implemented yet");
- result = 0;
- } else {
- // Throw some Not Valid Frequency error here
- result = -1;
- }
return result;
}
-static char* timedelta_to_cstring(npy_longlong tlong, int freq)
-{
- char result[64];
- switch (freq)
- {
- case NPY_FR_Y:
- {
- sprintf(result, "%lld Years", tlong);
- break;
- }
- case NPY_FR_M:
- {
- if (tlong > 11)
- {
- sprintf(result, "%lld Years, %d Days",
- tlong / 12,
- month_offset[0][tlong % 12]);
- }
- else
- {
- sprintf(result, "%d Days",
- month_offset[0][tlong % 12]);
- }
- break;
- }
- case NPY_FR_W:
- {
- if (tlong > 51)
- {
- sprintf(result, "%lli Years, %lli Days",
- tlong / 52,
- (tlong % 52) * 7);
- }
- else
- {
- sprintf(result, "%lli Days", tlong * 7);
- }
- break;
- }
- case NPY_FR_B:
- {
-
- }
- case NPY_FR_D:
- {
- if (tlong > 364)
- sprintf(result, "%lli Years, %lli Days",
- tlong / 365,
- tlong % 365);
- else
- sprintf(result, "%lli Days", tlong);
- break;
- }
- case NPY_FR_h:
- {
- // 8760 hours in 365 days
- if (tlong > 8759)
- {
- npy_longlong years = as_freq_h2Y(tlong);
- sprintf(result, "%lli Years, %lli Days %lli:00:00",
- years, (tlong / 24) % 365, tlong % 24);
- break;
- }
- else if (tlong > 23)
- {
- sprintf(result, "%lli Days, %lli:00:00",
- tlong / 24, tlong % 24);
- }
- else
- {
- sprintf(result, "%lli:00:00", tlong);
- }
- break;
- }
- case NPY_FR_m:
- {
- // 525600 minutes in 365 days
- if (tlong > 525600)
- {
- npy_longlong years = as_freq_m2Y(tlong);
- npy_longlong days = as_freq_m2D(tlong % 525600);
- sprintf(result, "%lli Years, %lli Days, %lli:%lli:00",
- years, days, (tlong / 60) % 24, tlong % 60);
- break;
- }
- else if (tlong > 1440)
- {
- npy_longlong days = as_freq_m2D(tlong % 525600);
- sprintf(result, "%lli Days, %lli:%lli:00",
- days, (tlong / 60) % 24, tlong % 60);
- break;
- }
- else
- {
- sprintf(result, "%02lli:%02lli:00",
- (tlong / 60) % 24, tlong % 60);
- }
- break;
- }
- case NPY_FR_s:
- {
- // How many Years
- // How many Days
- // How many hours
- // How many minutes
- }
- case NPY_FR_ms:
- {
-
- }
- case NPY_FR_us:
- {
-
- }
- case NPY_FR_ns:
- {
-
- }
- case NPY_FR_ps:
- {
-
- }
- case NPY_FR_fs:
- {
-
- }
- case NPY_FR_as:
- {
- break;
- }
- default: return "error"; break;
- }
- return "error";
-}
-
-// TimeDelta long -> timedelta is very simple.
-// DateTime timedelta -> long is very simple.
-// Takes a Python DateTime TimeDelta object and a freq
-// returns a long
-static PyObject *
-dt_timedelta_to_long(PyObject *self, PyObject *args)
-{
- PyObject *dt_timedelta_arg = NULL;
- PyObject *freq_arg = NULL;
-
- PyDateTime_IMPORT;
-
- int freq = NPY_FR_ERR;
-
- // Parse out long_arg & freq_arg
- if (!PyArg_ParseTuple(args, "OO", &dt_timedelta_arg, &freq_arg))
- return NULL;
-
- if (!PyDelta_Check(dt_timedelta_arg))
- {
- PyErr_SetString(PyExc_TypeError, "invalid datetime timedelta entry.");
- return NULL;
- }
-
- if ((freq = _unit_from_str(PyString_AsString(freq_arg))) == NPY_FR_ERR)
- {
- // If the frequency is invalid, set an error and return null
- PyErr_SetString(PyExc_TypeError, "invalid frequency.");
- return NULL;
- }
- return PyLong_FromLongLong(timedelta_to_long(dt_timedelta_arg, freq));
-}
-// TimeDelta TimeDelta -> long is also simple.
-// TimeDelta TimeDelta -> String is less simple.
-// Takes a npy_longlong value for timedelta and
-// a frequency as it's frequency
-// Returns a string formatted:
-// X Years, Y Days xx:xx:xx.xxxxxx
-static PyObject *
-timedelta_to_string(PyObject *self, PyObject *args)
-{
- PyObject *long_arg = NULL;
- PyObject *freq_arg = NULL;
-
- npy_longlong tlong = 0;
- int freq = NPY_FR_ERR;
-
- // Parse out long_arg & freq_arg
- if (!PyArg_ParseTuple(args, "OO", &long_arg, &freq_arg))
- return NULL;
-
- if (PyLong_Check(long_arg))
- tlong = PyLong_AsLongLong(long_arg);
- else
- PyErr_SetString(PyExc_TypeError, "invalid long entry.");
-
- if ((freq = _unit_from_str(PyString_AsString(freq_arg))) == NPY_FR_ERR)
- {
- // If the frequency is invalid, set an error and return null
- PyErr_SetString(PyExc_TypeError, "invalid frequency.");
- return NULL;
- }
- return PyString_FromString(timedelta_to_cstring(tlong, freq));
-}
-// TimeDelta + TimeDelta is interesting
-// if it's one TimeDelta and one TimeDelta
-// return one TimeDelta
-// if it's one list and one TimeDelta
-// return one (list + that TimeDelta)
-// if it's one list and one list
-// return one (list + that list)
-static PyObject *
-timedelta_plus_timedelta(PyObject *self, PyObject *args)
-{
- PyObject *long_arg1 = NULL;
- PyObject *freq_arg1 = NULL;
- PyObject *long_arg2 = NULL;
- PyObject *freq_arg2 = NULL;
-
- npy_longlong tlong1 = 0;
- npy_longlong tlong2 = 0;
- int freq1 = NPY_FR_ERR;
- int freq2 = NPY_FR_ERR;
-
- // Parse out long_arg & freq_arg
- if (!PyArg_ParseTuple(args, "OOOO", &long_arg1, &freq_arg1,
- &long_arg2, &freq_arg2))
- return NULL;
-
- // Parse out both freqs
- if (((freq1 = _unit_from_str(PyString_AsString(freq_arg1))) == NPY_FR_ERR) ||
- ((freq2 = _unit_from_str(PyString_AsString(freq_arg2))) == NPY_FR_ERR))
- {
- // If the frequency is invalid, set an error and return null
- PyErr_SetString(PyExc_TypeError, "invalid frequency.");
- return NULL;
- }
-
- // TimeDelta + TimeDelta
- if (PyLong_Check(long_arg1) && PyLong_Check(long_arg2))
- {
- tlong1 = PyLong_AsLongLong(long_arg1);
- tlong2 = PyLong_AsLongLong(long_arg2);
-
- if (freq1 == freq2)
- return PyLong_FromLongLong(tlong1 + tlong2);
- // Freq1 is more precise than freq2
- // change freq2 to freq1
- else if (freq1 < freq2)
- {
- npy_longlong (* conversion_ftn) (npy_longlong) =
- get_conversion_ftn(freq2, freq1);
- return PyLong_FromLongLong(conversion_ftn(tlong2) + tlong1);
- }
- // Freq1 is less precise than freq2
- // change freq1 to freq2
- else
- {
- npy_longlong (* conversion_ftn) (npy_longlong) =
- get_conversion_ftn(freq1, freq2);
- return PyLong_FromLongLong(conversion_ftn(tlong1) + tlong2);
- }
- }
- // List + TimeDelta
- else if (PyList_Check(long_arg1) && PyLong_Check(long_arg2))
- {
- npy_longlong tlong_scalar = PyLong_AsLongLong(long_arg2);
- PyObject* result = PyList_New(0);
- npy_longlong (*conversion_ftn) (npy_longlong) = NULL;
- int smaller_arg = 0; // which argument is more precise?
-
- // Freq1 is more precise than freq2
- // change freq2 to freq1
- if (freq1 < freq2)
- {
- conversion_ftn = get_conversion_ftn(freq2, freq1);
- // list is more precise than scalar
- smaller_arg = 0;
- }
- // Freq1 is less precise than freq2
- // change freq1 to freq2
- else
- {
- conversion_ftn = get_conversion_ftn(freq1, freq2);
- // scalar is more precise than list
- smaller_arg = 1;
- }
-
- // Iterate through long_arg1
- Py_ssize_t idx;
- for (idx = 0; idx < PyList_Size(long_arg1); idx++)
- {
- // extract correct value of main arg
- npy_longlong tlong_member =
- PyLong_AsLongLong(PyList_GetItem(long_arg1, idx));
- npy_longlong tlong_result;
- if (conversion_ftn)
- {
- if (smaller_arg)
- tlong_result = (*conversion_ftn)(tlong_member)
- + tlong_scalar;
- else
- tlong_result = (*conversion_ftn)(tlong_scalar)
- + tlong_member;
- }
- else
- tlong_result = tlong_member + tlong2;
- // put calculated dlong into result
- PyList_Append(result,
- PyLong_FromLongLong(tlong_result));
- }
- return result;
- }
- // List + List
- else if (PyList_Check(long_arg1) && PyList_Check(long_arg2))
- {
- if (PyList_Size(long_arg1) != PyList_Size(long_arg2))
- {
- PyErr_SetString(PyExc_TypeError, "list sizes must be equal.");
- return NULL;
- }
-
- PyObject* result = PyList_New(0);
- npy_longlong (*conversion_ftn)(npy_longlong) = NULL;
- int smaller_arg = 0; // which argument is smaller?
-
- // Freq1 is more precise than freq2
- // change freq2 to freq1
- if (freq1 < freq2)
- {
- conversion_ftn= get_conversion_ftn(freq2, freq1);
- smaller_arg = 0;
- }
- // Freq1 is less precise than freq2
- // change freq1 to freq2
- else
- {
- conversion_ftn = get_conversion_ftn(freq1, freq2);
- smaller_arg = 1;
- }
-
- // Iterate through list_1
- Py_ssize_t idx;
- for (idx = 0; idx < PyList_Size(long_arg1); idx++)
- {
- // extract correct value of main arg
- npy_longlong tlong_member1 = PyLong_AsLongLong(
- PyList_GetItem(long_arg1, idx));
- npy_longlong tlong_member2 = PyLong_AsLongLong(
- PyList_GetItem(long_arg2, idx));
- npy_longlong tlong_result;
- if (conversion_ftn)
- {
- // if the second is smaller
- if (smaller_arg)
- {
- tlong_result = (*conversion_ftn)(tlong_member2)
- + tlong_member1;
- }
- else
- {
- tlong_result = (*conversion_ftn)(tlong_member1)
- + tlong_member2;
- }
- }
- else
- tlong_result = tlong1 + tlong2;
- // put calculated dlong into result
- PyList_Append(result,
- PyLong_FromLongLong(tlong_result));
- }
- return result;
- }
- else
- {
- PyErr_SetString(PyExc_TypeError, "invalid entries.");
- return NULL;
- }
-}
-
-// This is the same as td_plus_td, but minus instead...
-// This should be stacked on to plus, but I haven't decided how yet
-static PyObject *
-timedelta_minus_timedelta(PyObject *self, PyObject *args)
-{
- PyObject *long_arg1 = NULL;
- PyObject *freq_arg1 = NULL;
- PyObject *long_arg2 = NULL;
- PyObject *freq_arg2 = NULL;
-
- npy_longlong tlong1 = 0;
- npy_longlong tlong2 = 0;
- int freq1 = NPY_FR_ERR;
- int freq2 = NPY_FR_ERR;
-
- // Parse out long_arg & freq_arg
- if (!PyArg_ParseTuple(args, "OOOO", &long_arg1, &freq_arg1,
- &long_arg2, &freq_arg2))
- return NULL;
-
- // Parse out both freqs
- if (((freq1 = _unit_from_str(PyString_AsString(freq_arg1))) == NPY_FR_ERR) ||
- ((freq2 = _unit_from_str(PyString_AsString(freq_arg2))) == NPY_FR_ERR))
- {
- // If the frequency is invalid, set an error and return null
- PyErr_SetString(PyExc_TypeError, "invalid frequency.");
- return NULL;
- }
-
- // TimeDelta + TimeDelta
- if (PyLong_Check(long_arg1) && PyLong_Check(long_arg2))
- {
- tlong1 = PyLong_AsLongLong(long_arg1);
- tlong2 = PyLong_AsLongLong(long_arg2);
-
- if (freq1 == freq2)
- return PyLong_FromLongLong(tlong1 - tlong2);
- // Freq1 is more precise than freq2
- // change freq2 to freq1
- else if (freq1 < freq2)
- {
- npy_longlong (* conversion_ftn) (npy_longlong) =
- get_conversion_ftn(freq2, freq1);
- return PyLong_FromLongLong(-conversion_ftn(tlong2) + tlong1);
- }
- // Freq1 is less precise than freq2
- // change freq1 to freq2
- else
- {
- npy_longlong (* conversion_ftn) (npy_longlong) =
- get_conversion_ftn(freq1, freq2);
- return PyLong_FromLongLong(conversion_ftn(tlong1) - tlong2);
- }
- }
- // List + TimeDelta
- else if (PyList_Check(long_arg1) && PyLong_Check(long_arg2))
- {
- npy_longlong tlong_scalar = PyLong_AsLongLong(long_arg2);
- PyObject* result = PyList_New(0);
- npy_longlong (*conversion_ftn) (npy_longlong) = NULL;
- int smaller_arg = 0; // which argument is more precise?
-
- // Freq1 is more precise than freq2
- // change freq2 to freq1
- if (freq1 < freq2)
- {
- conversion_ftn = get_conversion_ftn(freq2, freq1);
- // list is more precise than scalar
- smaller_arg = 0;
- }
- // Freq1 is less precise than freq2
- // change freq1 to freq2
- else
- {
- conversion_ftn = get_conversion_ftn(freq1, freq2);
- // scalar is more precise than list
- smaller_arg = 1;
- }
-
- // Iterate through long_arg1
- Py_ssize_t idx;
- for (idx = 0; idx < PyList_Size(long_arg1); idx++)
- {
- // extract correct value of main arg
- npy_longlong tlong_member =
- PyLong_AsLongLong(PyList_GetItem(long_arg1, idx));
- npy_longlong tlong_result;
- if (conversion_ftn)
- {
- if (smaller_arg)
- tlong_result = (*conversion_ftn)(tlong_member)
- - tlong_scalar;
- else
- tlong_result = -(*conversion_ftn)(tlong_scalar)
- + tlong_member;
- }
- else
- tlong_result = tlong_member + tlong2;
- // put calculated dlong into result
- PyList_Append(result,
- PyLong_FromLongLong(tlong_result));
- }
- return result;
- }
- // List + List
- else if (PyList_Check(long_arg1) && PyList_Check(long_arg2))
- {
- if (PyList_Size(long_arg1) != PyList_Size(long_arg2))
- {
- PyErr_SetString(PyExc_TypeError, "list sizes must be equal.");
- return NULL;
- }
-
- PyObject* result = PyList_New(0);
- npy_longlong (*conversion_ftn)(npy_longlong) = NULL;
- int smaller_arg = 0; // which argument is smaller?
-
- // Freq1 is more precise than freq2
- // change freq2 to freq1
- if (freq1 < freq2)
- {
- conversion_ftn= get_conversion_ftn(freq2, freq1);
- smaller_arg = 0;
- }
- // Freq1 is less precise than freq2
- // change freq1 to freq2
- else
- {
- conversion_ftn = get_conversion_ftn(freq1, freq2);
- smaller_arg = 1;
- }
-
- // Iterate through list_1
- Py_ssize_t idx;
- for (idx = 0; idx < PyList_Size(long_arg1); idx++)
- {
- // extract correct value of main arg
- npy_longlong tlong_member1 = PyLong_AsLongLong(
- PyList_GetItem(long_arg1, idx));
- npy_longlong tlong_member2 = PyLong_AsLongLong(
- PyList_GetItem(long_arg2, idx));
- npy_longlong tlong_result;
- if (conversion_ftn)
- {
- // if the second is smaller
- if (smaller_arg)
- {
- tlong_result = -(*conversion_ftn)(tlong_member2)
- + tlong_member1;
- }
- else
- {
- tlong_result = (*conversion_ftn)(tlong_member1)
- - tlong_member2;
- }
- }
- else
- tlong_result = tlong1 - tlong2;
- // put calculated dlong into result
- PyList_Append(result,
- PyLong_FromLongLong(tlong_result));
- }
- return result;
- }
- else
- {
- PyErr_SetString(PyExc_TypeError, "invalid entries.");
- return NULL;
- }
-}
-// TimeDelta + DateTime is very interesting
-// TimeDelta - DateTime is very interesting
-//==================================================
-// Frequency conversion UFunc
-//==================================================
-
-
-// This is the ufunc for handling "specific" frequency conversions
-// Later, format it as astype_Y2M_ufunc, astype_Y2W_ufunc, etc
-// and set each of these to a seperate cf_function[] depending on the
-// cf_signature
-static void
-convert_freq_ufunc(char **args, npy_intp *dimensions, \
- npy_intp *steps, void *extra)
-{
- npy_intp idx;
- npy_intp insteps = steps[0], outsteps = steps[1];
- npy_intp n = dimensions[0];
- char *input = args[0], *output = args[1];
- // char *freq_char = (char *) extra;
- // parse freq
- int freq;
- //if ((freq = _unit_from_str(*freq_char)) == NPY_FR_ERR)
-
- // freq = _unit_from_str(*freq_char);
- // error out
-
- npy_longlong (*conversion_ftn)(npy_longlong) = NULL;
-
- // Pull out freqs from extra OR
- // grab freqs depending on dtype
- // int freq1 = this dtype
- // int freq2 = input 2's dtype
- // Get conversion function
- //conversion_ftn= get_conversion_ftn(13, freq);
-
- for (idx = 0; idx < n; idx++)
- {
- // Perform operation
- *((npy_longlong *)output) = conversion_ftn(*((npy_longlong *)input));
-
- // Iterate over data
- input += insteps;
- output += outsteps;
- }
-}
-
-// Which specific looping function to run
-static PyUFuncGenericFunction cf_functions[] = \
- {convert_freq_ufunc};
-
-// What GENERIC ufunc to run
-static void* cf_data[1];
-
-// Correct argument signatures
-static char cf_signatures[]=\
- {NPY_INT64, NPY_INT64};
-
-/*
- * Eventually, these should be formatted as:
- * NPY_DATETIME64Y, NPY_DATETIMEM
- * NPY_DATETIME64Y, NPY_DATETIMEW
- * NPY_DATETIME64Y, NPY_DATETIMEB
- * NPY_DATETIME64Y, NPY_DATETIMEW
- * etc
- *
- * with each type deserving a different function
- */
-
-
-
-