[Scipy-svn] r2757 - trunk/Lib/sandbox/timeseries/src
scipy-svn at scipy.org
scipy-svn at scipy.org
Fri Feb 23 15:27:39 EST 2007
Author: mattknox_ca
Date: 2007-02-23 14:27:35 -0600 (Fri, 23 Feb 2007)
New Revision: 2757
Modified:
trunk/Lib/sandbox/timeseries/src/cseries.c
Log:
major overhaul. Eliminated use of mx.DateTime
Modified: trunk/Lib/sandbox/timeseries/src/cseries.c
===================================================================
--- trunk/Lib/sandbox/timeseries/src/cseries.c 2007-02-23 20:27:07 UTC (rev 2756)
+++ trunk/Lib/sandbox/timeseries/src/cseries.c 2007-02-23 20:27:35 UTC (rev 2757)
@@ -2,7 +2,6 @@
#include <structmember.h>
#include <stdio.h>
#include <string.h>
-#include "mxDateTime.h"
#include "arrayobject.h"
static char cseries_doc[] = "Speed sensitive time series operations";
@@ -12,7 +11,7 @@
#define FR_MTH 3000 /* Monthly */
#define FR_WK 4000 /* Weekly */
#define FR_BUS 5000 /* Business days */
-#define FR_DAY 6000 /* Daily */
+#define FR_DAY 6000 /* Daily */
#define FR_HR 7000 /* Hourly */
#define FR_MIN 8000 /* Minutely */
#define FR_SEC 9000 /* Secondly */
@@ -23,79 +22,417 @@
PyDict_SetItemString(dict, key, pyval); \
Py_DECREF(pyval); }
-static long minval_D_toHighFreq = 719163;
-///////////////////////////////////////////////////////////////////////
+//DERIVED FROM mx.DateTime
+/*
+=====================================================
+== Functions in the following section are borrowed ==
+== from mx.DateTime, and in many cases slightly ==
+== modified ==
+=====================================================
+*/
-// helpers for frequency conversion routines //
+#define Py_AssertWithArg(x,errortype,errorstr,a1) {if (!(x)) {PyErr_Format(errortype,errorstr,a1);goto onError;}}
+#define Py_Error(errortype,errorstr) {PyErr_SetString(errortype,errorstr);goto onError;}
-static long DtoB_weekday(long fromDate) { return (((fromDate) / 7) * 5) + (fromDate)%7; }
+static PyObject *DateCalc_Error; /* Error Exception object */
+static PyObject *DateCalc_RangeError; /* Error Exception object */
-static long DtoB_WeekendToMonday(mxDateTimeObject *dailyDate) {
+#define DINFO_ERR -99
- long absdate = dailyDate->absdate;
- if (dailyDate->day_of_week > 4) {
- //change to Monday after weekend
- absdate += (7 - dailyDate->day_of_week);
+#define GREGORIAN_CALENDAR 0
+#define JULIAN_CALENDAR 1
+
+#define SECONDS_PER_DAY ((double) 86400.0)
+
+/* Table with day offsets for each month (0-based, without and with leap) */
+static int month_offset[2][13] = {
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+};
+
+/* Table of number of days in a month (0-based, without and with leap) */
+static int days_in_month[2][12] = {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+struct date_info {
+ long absdate;
+ double abstime;
+
+ double second;
+ int minute;
+ int hour;
+ int day;
+ int month;
+ int quarter;
+ int year;
+ int day_of_week;
+ int day_of_year;
+ int calendar;
+};
+
+
+/* Return 1/0 iff year points to a leap year in calendar. */
+static
+int dInfoCalc_Leapyear(register long year,
+ int calendar)
+{
+ if (calendar == GREGORIAN_CALENDAR) {
+ return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
+ } else {
+ return (year % 4 == 0);
}
- return DtoB_weekday(absdate);
}
-static long DtoB_WeekendToFriday(mxDateTimeObject *dailyDate) {
+static
+int dInfoCalc_ISOWeek(struct date_info dinfo)
+{
+ int week;
- long absdate = dailyDate->absdate;
- if (dailyDate->day_of_week > 4) {
- //change to friday before weekend
- absdate -= (dailyDate->day_of_week - 4);
+ /* Estimate */
+ week = (dinfo.day_of_year-1) - dinfo.day_of_week + 3;
+ if (week >= 0) week = week / 7 + 1;
+
+ /* Verify */
+ if (week < 0) {
+ /* The day lies in last week of the previous year */
+ if ((week > -2) ||
+ (week == -2 && dInfoCalc_Leapyear(dinfo.year-1, dinfo.calendar)))
+ week = 53;
+ else
+ week = 52;
+ } else if (week == 53) {
+ /* Check if the week belongs to year or year+1 */
+ if (31-dinfo.day + dinfo.day_of_week < 3) {
+ week = 1;
+ }
}
- return DtoB_weekday(absdate);
+
+ return week;
}
-static long absdate_from_ymd(int y, int m, int d) {
- mxDateTimeObject *tempDate;
- long result;
- tempDate = (mxDateTimeObject *)mxDateTime.DateTime_FromDateAndTime(y,m,d,0,0,0);
- result = (long)(tempDate->absdate);
- Py_DECREF(tempDate);
- return result;
+/* Return the day of the week for the given absolute date. */
+static
+int dInfoCalc_DayOfWeek(register long absdate)
+{
+ int day_of_week;
+
+ if (absdate >= 1) {
+ day_of_week = (absdate - 1) % 7;
+ } else {
+ day_of_week = 6 - ((-absdate) % 7);
+ }
+ return day_of_week;
}
+/* Return the year offset, that is the absolute date of the day
+ 31.12.(year-1) in the given calendar.
-static mxDateTimeObject *day_before_mxobj(int y, int m, int d) {
- return (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(absdate_from_ymd(y, m, d) - 1, 0);
+ Note:
+ For the Julian calendar we shift the absdate (which is measured
+ using the Gregorian Epoch) value by two days because the Epoch
+ (0001-01-01) in the Julian calendar lies 2 days before the Epoch in
+ the Gregorian calendar. */
+static
+int dInfoCalc_YearOffset(register long year,
+ int calendar)
+{
+ year--;
+ if (calendar == GREGORIAN_CALENDAR) {
+ if (year >= 0 || -1/4 == -1)
+ return year*365 + year/4 - year/100 + year/400;
+ else
+ return year*365 + (year-3)/4 - (year-99)/100 + (year-399)/400;
+ }
+ else if (calendar == JULIAN_CALENDAR) {
+ if (year >= 0 || -1/4 == -1)
+ return year*365 + year/4 - 2;
+ else
+ return year*365 + (year-3)/4 - 2;
+ }
+ Py_Error(DateCalc_Error, "unknown calendar");
+ onError:
+ return -1;
}
-/*
-returns Date(y, m, d) converted to business frequency.
-If the initial result is a weekend, the following Monday is returned
-*/
-static long busday_before(int y, int m, int d) {
- mxDateTimeObject *dailyDate;
- long result;
- dailyDate = (mxDateTimeObject *)mxDateTime.DateTime_FromDateAndTime(y,m,d,0,0,0);
- result = DtoB_WeekendToMonday(dailyDate);
+/* Set the instance's value using the given date and time. calendar
+ may be set to the flags: GREGORIAN_CALENDAR,
+ JULIAN_CALENDAR to indicate the calendar to be used. */
- Py_DECREF(dailyDate);
- return result;
+static
+int dInfoCalc_SetFromDateAndTime(struct date_info *dinfo,
+ int year,
+ int month,
+ int day,
+ int hour,
+ int minute,
+ double second,
+ int calendar)
+{
+
+ /* Calculate the absolute date */
+ {
+ int leap;
+ long yearoffset,absdate;
+
+ /* Range check */
+ Py_AssertWithArg(year > -(INT_MAX / 366) && year < (INT_MAX / 366),
+ DateCalc_RangeError,
+ "year out of range: %i",
+ year);
+
+ /* Is it a leap year ? */
+ leap = dInfoCalc_Leapyear(year,calendar);
+
+ /* Negative month values indicate months relative to the years end */
+ if (month < 0) month += 13;
+ Py_AssertWithArg(month >= 1 && month <= 12,
+ DateCalc_RangeError,
+ "month out of range (1-12): %i",
+ month);
+
+ /* Negative values indicate days relative to the months end */
+ if (day < 0) day += days_in_month[leap][month - 1] + 1;
+ Py_AssertWithArg(day >= 1 && day <= days_in_month[leap][month - 1],
+ DateCalc_RangeError,
+ "day out of range: %i",
+ day);
+
+ yearoffset = dInfoCalc_YearOffset(year,calendar);
+ if (yearoffset == -1 && PyErr_Occurred()) goto onError;
+
+ absdate = day + month_offset[leap][month - 1] + yearoffset;
+
+ dinfo->absdate = absdate;
+
+ dinfo->year = year;
+ dinfo->month = month;
+ dinfo->day = day;
+
+ dinfo->day_of_week = dInfoCalc_DayOfWeek(absdate);
+ dinfo->day_of_year = (short)(absdate - yearoffset);
+
+ dinfo->calendar = calendar;
+ }
+
+ /* Calculate the absolute time */
+ {
+ Py_AssertWithArg(hour >= 0 && hour <= 23,
+ DateCalc_RangeError,
+ "hour out of range (0-23): %i",
+ hour);
+ Py_AssertWithArg(minute >= 0 && minute <= 59,
+ DateCalc_RangeError,
+ "minute out of range (0-59): %i",
+ minute);
+ Py_AssertWithArg(second >= (double)0.0 &&
+ (second < (double)60.0 ||
+ (hour == 23 && minute == 59 &&
+ second < (double)61.0)),
+ DateCalc_RangeError,
+ "second out of range (0.0 - <60.0; <61.0 for 23:59): %f",
+ second);
+
+ dinfo->abstime = (double)(hour*3600 + minute*60) + second;
+
+ dinfo->hour = hour;
+ dinfo->minute = minute;
+ dinfo->second = second;
+ }
+ return 0;
+ onError:
+ return -1;
}
+
+/* Sets the date part of the date_info struct using the indicated
+ calendar.
+
+ XXX This could also be done using some integer arithmetics rather
+ than with this iterative approach... */
+static
+int dInfoCalc_SetFromAbsDate(register struct date_info *dinfo,
+ long absdate,
+ int calendar)
+{
+ register long year;
+ long yearoffset;
+ int leap,dayoffset;
+ int *monthoffset;
+
+ /* Approximate year */
+ if (calendar == GREGORIAN_CALENDAR) {
+ year = (long)(((double)absdate) / 365.2425);
+ } else if (calendar == JULIAN_CALENDAR) {
+ year = (long)(((double)absdate) / 365.25);
+ } else {
+ Py_Error(DateCalc_Error, "unknown calendar");
+ }
+ if (absdate > 0) year++;
+
+ /* Apply corrections to reach the correct year */
+ while (1) {
+ /* Calculate the year offset */
+ yearoffset = dInfoCalc_YearOffset(year,calendar);
+ if (yearoffset == -1 && PyErr_Occurred())
+ goto onError;
+
+ /* Backward correction: absdate must be greater than the
+ yearoffset */
+ if (yearoffset >= absdate) {
+ year--;
+ continue;
+ }
+
+ dayoffset = absdate - yearoffset;
+ leap = dInfoCalc_Leapyear(year,calendar);
+
+ /* Forward correction: non leap years only have 365 days */
+ if (dayoffset > 365 && !leap) {
+ year++;
+ continue;
+ }
+ break;
+ }
+
+ dinfo->year = year;
+ dinfo->calendar = calendar;
+
+ /* Now iterate to find the month */
+ monthoffset = month_offset[leap];
+ {
+ register int month;
+
+ for (month = 1; month < 13; month++) {
+ if (monthoffset[month] >= dayoffset)
+ break;
+ }
+
+ dinfo->month = month;
+ dinfo->quarter = ((month-1)/3)+1;
+ dinfo->day = dayoffset - month_offset[leap][month-1];
+ }
+
+
+ dinfo->day_of_week = dInfoCalc_DayOfWeek(absdate);
+ dinfo->day_of_year = dayoffset;
+ dinfo->absdate = absdate;
+
+ return 0;
+
+ onError:
+ return -1;
+}
+
+/* Sets the time part of the DateTime object. */
+static
+int dInfoCalc_SetFromAbsTime(struct date_info *dinfo,
+ double abstime)
+{
+ int inttime;
+ int hour,minute;
+ double second;
+
+ inttime = (int)abstime;
+ hour = inttime / 3600;
+ minute = (inttime % 3600) / 60;
+ second = abstime - (double)(hour*3600 + minute*60);
+
+ dinfo->hour = hour;
+ dinfo->minute = minute;
+ dinfo->second = second;
+
+ dinfo->abstime = abstime;
+
+ return 0;
+}
+
+/* Set the instance's value using the given date and time. calendar
+ may be set to the flags: GREGORIAN_CALENDAR, JULIAN_CALENDAR to
+ indicate the calendar to be used. */
+static
+int dInfoCalc_SetFromAbsDateTime(struct date_info *dinfo,
+ long absdate,
+ double abstime,
+ int calendar)
+{
+
+ /* Bounds check */
+ Py_AssertWithArg(abstime >= 0.0 && abstime <= SECONDS_PER_DAY,
+ DateCalc_Error,
+ "abstime out of range (0.0 - 86400.0): %f",
+ abstime);
+
+ /* Calculate the date */
+ if (dInfoCalc_SetFromAbsDate(dinfo,
+ absdate,
+ calendar))
+ goto onError;
+
+ /* Calculate the time */
+ if (dInfoCalc_SetFromAbsTime(dinfo,
+ abstime))
+ goto onError;
+
+ return 0;
+ onError:
+ return -1;
+}
+
/*
-returns Date(y, m, d) - 1 converted to business frequency.
-If the initial result is a weekend, the preceding Friday is returned
+====================================================
+== End of section borrowed from mx.DateTime ==
+====================================================
*/
-static long busday_after(int y, int m, int d) {
- mxDateTimeObject *dailyDate;
- long result;
- dailyDate = day_before_mxobj(y,m,d);
- result = DtoB_WeekendToFriday(dailyDate);
- Py_DECREF(dailyDate);
- return result;
+//////////////////////////////////////////////////////////
+
+static long minval_D_toHighFreq = 719163;
+
+///////////////////////////////////////////////////////////////////////
+
+static long absdatetime_hour(long absdate, long time) {
+
}
+///////////////////////////////////////////////////////////////////////
+
+// helpers for frequency conversion routines //
+
+static long DtoB_weekday(long fromDate) { return (((fromDate) / 7) * 5) + (fromDate)%7; }
+
+static long DtoB_WeekendToMonday(struct date_info dinfo) {
+
+ long absdate = dinfo.absdate;
+ if (dinfo.day_of_week > 4) {
+ //change to Monday after weekend
+ absdate += (7 - dinfo.day_of_week);
+ }
+ return DtoB_weekday(absdate);
+}
+
+static long DtoB_WeekendToFriday(struct date_info dinfo) {
+
+ long absdate = dinfo.absdate;
+ if (dinfo.day_of_week > 4) {
+ //change to friday before weekend
+ absdate -= (dinfo.day_of_week - 4);
+ }
+ return DtoB_weekday(absdate);
+}
+
+static long absdate_from_ymd(int y, int m, int d) {
+ struct date_info tempDate;
+ if (dInfoCalc_SetFromDateAndTime(&tempDate, y, m, d, 0, 0, 0, GREGORIAN_CALENDAR)) return DINFO_ERR;
+ return tempDate.absdate;
+}
+
+
///////////////////////////////////////////////
// frequency specifc conversion routines
@@ -104,67 +441,55 @@
//************ FROM DAILY ***************
static long asfreq_DtoA(long fromDate, char relation) {
- mxDateTimeObject *mxDate;
- long result;
- mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
- result = (long)(mxDate->year);
- Py_DECREF(mxDate);
- return result;
+ struct date_info dinfo;
+ if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
+ return (long)(dinfo.year);
}
static long asfreq_DtoQ(long fromDate, char relation) {
- mxDateTimeObject *mxDate;
- long result;
-
- mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
- result = (long)((mxDate->year - 1) * 4 + (mxDate->month-1)/3 + 1);
- Py_DECREF(mxDate);
- return result;
+ struct date_info dinfo;
+ if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
+ return (long)((dinfo.year - 1) * 4 + dinfo.quarter);
}
static long asfreq_DtoM(long fromDate, char relation) {
- mxDateTimeObject *mxDate;
- long result;
- mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
- result = (long)((mxDate->year - 1) * 12 + mxDate->month);
- Py_DECREF(mxDate);
- return result;
+ struct date_info dinfo;
+ if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
+ return (long)((dinfo.year - 1) * 12 + dinfo.month);
}
static long asfreq_DtoW(long fromDate, char relation) { return (fromDate - 1)/7 + 1; }
static long asfreq_DtoB(long fromDate, char relation) {
- mxDateTimeObject *mxDate;
- long result;
- mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
+ struct date_info dinfo;
+ if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
+
if (relation == 'B') {
- result = DtoB_WeekendToFriday(mxDate);
+ return DtoB_WeekendToFriday(dinfo);
} else {
- result = DtoB_WeekendToMonday(mxDate);
+ return DtoB_WeekendToMonday(dinfo);
}
-
- Py_DECREF(mxDate);
- return result;
}
static long asfreq_DtoB_forConvert(long fromDate, char relation) {
- mxDateTimeObject *mxDate;
- long result;
- mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
+ struct date_info dinfo;
+ if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
- if (mxDate->day_of_week > 4) {
- result = -1;
+ if (dinfo.day_of_week > 4) {
+ return -1;
} else {
- result = DtoB_weekday(mxDate->absdate);
+ return DtoB_weekday(fromDate);
}
-
- Py_DECREF(mxDate);
- return result;
}
// needed for getDateInfo function
@@ -271,14 +596,13 @@
return asfreq_DtoM(asfreq_WtoD(fromDate, 'A'), relation); }
static long asfreq_WtoB(long fromDate, char relation) {
- mxDateTimeObject *mxDate;
- long result;
- mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(asfreq_WtoD(fromDate, relation), 0);
- if (relation == 'B') { result = DtoB_WeekendToMonday(mxDate); }
- else { result = DtoB_WeekendToFriday(mxDate); }
- Py_DECREF(mxDate);
- return result;
+ struct date_info dinfo;
+ if (dInfoCalc_SetFromAbsDate(&dinfo, asfreq_WtoD(fromDate, relation),
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
+
+ if (relation == 'B') { return DtoB_WeekendToMonday(dinfo); }
+ else { return DtoB_WeekendToFriday(dinfo); }
}
static long asfreq_WtoH(long fromDate, char relation) {
@@ -297,14 +621,16 @@
static long asfreq_MtoD(long fromDate, char relation) {
- long y, m;
+ long y, m, absdate;
if (relation == 'B') {
MtoD_ym(fromDate, &y, &m);
- return absdate_from_ymd(y, m, 1);
+ if ((absdate = absdate_from_ymd(y, m, 1)) == DINFO_ERR) return DINFO_ERR;
+ return absdate;
} else {
MtoD_ym(fromDate+1, &y, &m);
- return absdate_from_ymd(y, m, 1) - 1;
+ if ((absdate = absdate_from_ymd(y, m, 1)) == DINFO_ERR) return DINFO_ERR;
+ return absdate-1;
}
}
@@ -315,14 +641,12 @@
static long asfreq_MtoB(long fromDate, char relation) {
- mxDateTimeObject *mxDate;
- long result;
+ struct date_info dinfo;
+ if (dInfoCalc_SetFromAbsDate(&dinfo, asfreq_MtoD(fromDate, relation),
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
- mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(asfreq_MtoD(fromDate, relation), 0);
- if (relation == 'B') { result = DtoB_WeekendToMonday(mxDate); }
- else { result = DtoB_WeekendToFriday(mxDate); }
- Py_DECREF(mxDate);
- return result;
+ if (relation == 'B') { return DtoB_WeekendToMonday(dinfo); }
+ else { return DtoB_WeekendToFriday(dinfo); }
}
static long asfreq_MtoH(long fromDate, char relation) { return asfreq_DtoH(asfreq_MtoD(fromDate, relation), relation); }
@@ -338,14 +662,16 @@
static long asfreq_QtoD(long fromDate, char relation) {
- long y, m;
+ long y, m, absdate;
if (relation == 'B') {
QtoD_ym(fromDate, &y, &m);
- return absdate_from_ymd(y, m, 1);
+ if ((absdate = absdate_from_ymd(y, m, 1)) == DINFO_ERR) return DINFO_ERR;
+ return absdate;
} else {
QtoD_ym(fromDate+1, &y, &m);
- return absdate_from_ymd(y, m, 1) - 1;
+ if ((absdate = absdate_from_ymd(y, m, 1)) == DINFO_ERR) return DINFO_ERR;
+ return absdate - 1;
}
}
@@ -360,14 +686,12 @@
static long asfreq_QtoB(long fromDate, char relation) {
- mxDateTimeObject *mxDate;
- long result;
+ struct date_info dinfo;
+ if (dInfoCalc_SetFromAbsDate(&dinfo, asfreq_QtoD(fromDate, relation),
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
- mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(asfreq_QtoD(fromDate, relation), 0);
- if (relation == 'B') { result = DtoB_WeekendToMonday(mxDate); }
- else { result = DtoB_WeekendToFriday(mxDate); }
- Py_DECREF(mxDate);
- return result;
+ if (relation == 'B') { return DtoB_WeekendToMonday(dinfo); }
+ else { return DtoB_WeekendToFriday(dinfo); }
}
@@ -379,8 +703,14 @@
//************ FROM ANNUAL ***************
static long asfreq_AtoD(long fromDate, char relation) {
- if (relation == 'B') { return absdate_from_ymd(fromDate,1,1); }
- else { return absdate_from_ymd(fromDate+1,1,1) - 1; }
+ long absdate;
+ if (relation == 'B') {
+ if ((absdate = absdate_from_ymd(fromDate,1,1)) == DINFO_ERR) return DINFO_ERR;
+ return absdate;
+ } else {
+ if ((absdate = absdate_from_ymd(fromDate+1,1,1)) == DINFO_ERR) return DINFO_ERR;
+ return absdate - 1;
+ }
}
static long asfreq_AtoQ(long fromDate, char relation) {
@@ -396,8 +726,29 @@
static long asfreq_AtoW(long fromDate, char relation) { return asfreq_DtoW(asfreq_AtoD(fromDate, relation), relation); }
static long asfreq_AtoB(long fromDate, char relation) {
- if (relation == 'B') { return busday_before(fromDate,1,1); }
- else { return busday_after(fromDate+1,1,1); }
+
+ struct date_info dailyDate;
+
+ if (relation == 'B') {
+ if (dInfoCalc_SetFromDateAndTime(&dailyDate,
+ fromDate,1,1, 0, 0, 0,
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
+ return DtoB_WeekendToMonday(dailyDate);
+ } else {
+ long absdate;
+
+ if (dInfoCalc_SetFromDateAndTime(&dailyDate,
+ fromDate+1,1,1, 0, 0, 0,
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
+
+ absdate = dailyDate.absdate - 1;
+
+ if(dInfoCalc_SetFromAbsDate(&dailyDate,
+ absdate,
+ GREGORIAN_CALENDAR)) return DINFO_ERR;
+
+ return DtoB_WeekendToFriday(dailyDate);
+ }
}
static long asfreq_AtoH(long fromDate, char relation) { return asfreq_DtoH(asfreq_AtoD(fromDate, relation), relation); }
@@ -856,14 +1207,15 @@
}
-static long dInfo_year(mxDateTimeObject *dateObj) { return dateObj->year; }
-static long dInfo_quarter(mxDateTimeObject *dateObj) { return ((dateObj->month-1)/3)+1; }
-static long dInfo_month(mxDateTimeObject *dateObj) { return dateObj->month; }
-static long dInfo_day(mxDateTimeObject *dateObj) { return dateObj->day; }
-static long dInfo_day_of_year(mxDateTimeObject *dateObj) { return dateObj->day_of_year; }
-static long dInfo_day_of_week(mxDateTimeObject *dateObj) { return dateObj->day_of_week; }
-static long dInfo_week(mxDateTimeObject *dateObj) {
+static int dInfo_year(struct date_info dateObj) { return dateObj.year; }
+static int dInfo_quarter(struct date_info dateObj) { return dateObj.quarter; }
+static int dInfo_month(struct date_info dateObj) { return dateObj.month; }
+static int dInfo_day(struct date_info dateObj) { return dateObj.day; }
+static int dInfo_day_of_year(struct date_info dateObj) { return dateObj.day_of_year; }
+static int dInfo_day_of_week(struct date_info dateObj) { return dateObj.day_of_week; }
+static int dInfo_week(struct date_info dateObj) { return dInfoCalc_ISOWeek(dateObj); }
+/*
int year, week, day;
PyObject *ISOWeekTuple = NULL;
ISOWeekTuple = PyObject_GetAttrString((PyObject*)dateObj, "iso_week");
@@ -874,11 +1226,14 @@
Py_DECREF(ISOWeekTuple);
return (long)week;
+ dInfoCalc_ISOWeek(dinfo)
}
-static long dInfo_hour(mxDateTimeObject *dateObj) { return dateObj->hour; }
-static long dInfo_minute(mxDateTimeObject *dateObj) { return dateObj->minute; }
-static long dInfo_second(mxDateTimeObject *dateObj) { return (long)dateObj->second; }
+*/
+static int dInfo_hour(struct date_info dateObj) { return dateObj.hour; }
+static int dInfo_minute(struct date_info dateObj) { return dateObj.minute; }
+static int dInfo_second(struct date_info dateObj) { return (int)dateObj.second; }
+
static double getAbsTime(int freq, long dailyDate, long originalDate) {
long startOfDay, periodsPerDay;
@@ -914,7 +1269,7 @@
PyArrayObject *array;
PyArrayObject *newArray;
PyArrayIterObject *iterSource, *iterResult;
- mxDateTimeObject *convDate;
+ struct date_info convDate;
PyObject *val;
long dateNum, dInfo;
@@ -922,7 +1277,7 @@
double abstime;
long (*toDaily)(long, char) = NULL;
- long (*getDateInfo)(mxDateTimeObject*) = NULL;
+ int (*getDateInfo)(struct date_info) = NULL;
if (!PyArg_ParseTuple(args, "Ois:getDateInfo(array, freq, info)", &array, &freq, &info)) return NULL;
newArray = (PyArrayObject *)PyArray_Copy(array);
@@ -972,12 +1327,12 @@
val = PyArray_GETITEM(array, iterSource->dataptr);
dateNum = PyInt_AsLong(val);
+ Py_DECREF(val);
absdate = toDaily(dateNum, 'B');
abstime = getAbsTime(freq, absdate, dateNum);
- convDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(absdate, abstime);
+ if(dInfoCalc_SetFromAbsDateTime(&convDate, absdate, abstime, GREGORIAN_CALENDAR)) return NULL;
dInfo = getDateInfo(convDate);
- Py_DECREF(convDate);
PyArray_SETITEM(newArray, iterResult->dataptr, PyInt_FromLong(dInfo));
@@ -989,9 +1344,9 @@
Py_DECREF(iterResult);
return (PyObject *) newArray;
-
}
+
///////////////////////////////////////////////////////////////////////
static PyMethodDef cseries_methods[] = {
@@ -1006,7 +1361,6 @@
{
PyObject *m, *TSER_CONSTANTS;
m = Py_InitModule3("cseries", cseries_methods, cseries_doc);
- mxDateTime_ImportModuleAndAPI();
import_array();
TSER_CONSTANTS = PyDict_New();
More information about the Scipy-svn
mailing list