[Scipy-svn] r2852 - in trunk/Lib/sandbox/timeseries: . src tests

scipy-svn@scip... scipy-svn@scip...
Tue Mar 20 09:44:15 CDT 2007


Author: mattknox_ca
Date: 2007-03-20 09:44:08 -0500 (Tue, 20 Mar 2007)
New Revision: 2852

Modified:
   trunk/Lib/sandbox/timeseries/__init__.py
   trunk/Lib/sandbox/timeseries/setup.py
   trunk/Lib/sandbox/timeseries/src/cseries.c
   trunk/Lib/sandbox/timeseries/tcore.py
   trunk/Lib/sandbox/timeseries/tdates.py
   trunk/Lib/sandbox/timeseries/tests/test_dates.py
   trunk/Lib/sandbox/timeseries/tests/test_timeseries.py
   trunk/Lib/sandbox/timeseries/tseries.py
Log:
major update. Ported Date class to C, removed a lot of stuff from tcore

Modified: trunk/Lib/sandbox/timeseries/__init__.py
===================================================================
--- trunk/Lib/sandbox/timeseries/__init__.py	2007-03-20 14:42:18 UTC (rev 2851)
+++ trunk/Lib/sandbox/timeseries/__init__.py	2007-03-20 14:44:08 UTC (rev 2852)
@@ -1,34 +1,42 @@
-"""TimeSeries
-
-Support for time series in numpy/scipy
-
-:author: Pierre GF Gerard-Marchant & Matt Knox
-:contact: pierregm_at_uga_dot_edu - mattknox_ca_at_hotmail_dot_com
-:version: $Id$
-"""
+"""TimeSeries
 
+Support for time series in numpy/scipy
 
-__author__ = "Pierre GF Gerard-Marchant  & Matt Knox ($Author$)"
-__version__ = '1.0'
-__revision__ = "$Revision$"
-__date__     = '$Date$'
-
-import tcore
-from tcore import *
-import tdates
-from tdates import *
-import tseries
-from tseries import *
-import tmulti
-from tmulti import *
+:author: Pierre GF Gerard-Marchant & Matt Knox
+:contact: pierregm_at_uga_dot_edu - mattknox_ca_at_hotmail_dot_com
+:version: $Id$
+"""
+
+
+__author__ = "Pierre GF Gerard-Marchant  & Matt Knox ($Author$)"
+__version__ = '1.0'
+__revision__ = "$Revision$"
+__date__     = '$Date$'
+
+# initialize python callbacks for C code
+import cseries as cs
+import parser
+from parser import DateFromString, DateTimeFromString
+cs.set_callback_DateFromString(DateFromString)
+cs.set_callback_DateTimeFromString(DateTimeFromString)
+
+import tcore
+from tcore import *
+import const
+import tdates
+from tdates import *
+import tseries
+from tseries import *
+import tmulti
+from tmulti import *
 import reportlib
-from reportlib import *
-from addons import filters, interpolate
+from reportlib import *
+from addons import filters, interpolate
 
-
-__all__ = ['tdates', 'tseries','tmulti','reportlib','filters','interpolate']
-__all__ += tdates.__all__
-__all__ += tseries.__all__
+
+__all__ = ['const', 'tdates','parser','tseries','tmulti','reportlib','filters',
+           'interpolate','DateFromString','DateTimeFromString']
+__all__ += tdates.__all__
+__all__ += tseries.__all__
 __all__ += tmulti.__all__
 __all__ += reportlib.__all__
-

Modified: trunk/Lib/sandbox/timeseries/setup.py
===================================================================
--- trunk/Lib/sandbox/timeseries/setup.py	2007-03-20 14:42:18 UTC (rev 2851)
+++ trunk/Lib/sandbox/timeseries/setup.py	2007-03-20 14:44:08 UTC (rev 2852)
@@ -25,5 +25,5 @@
 if __name__ == "__main__":
     from numpy.distutils.core import setup
     #setup.update(nmasetup)
-    config = configuration(top_path='').todict() 
+    config = configuration(top_path='').todict()
     setup(**config)
\ No newline at end of file

Modified: trunk/Lib/sandbox/timeseries/src/cseries.c
===================================================================
--- trunk/Lib/sandbox/timeseries/src/cseries.c	2007-03-20 14:42:18 UTC (rev 2851)
+++ trunk/Lib/sandbox/timeseries/src/cseries.c	2007-03-20 14:44:08 UTC (rev 2852)
@@ -1,8 +1,6 @@
 #include <Python.h>
 #include <datetime.h>
 #include <structmember.h>
-#include <stdio.h>
-#include <string.h>
 #include <time.h>
 #include "arrayobject.h"
 
@@ -41,15 +39,16 @@
 #define FR_SEC  9000  /* Secondly */
 #define FR_UND  -10000 /* Undefined */
 
-#define ADD_INT_TO_DICT(dict, key, val) \
-    {PyObject *pyval = PyInt_FromLong(val); \
-     PyDict_SetItemString(dict, key, pyval); \
-     Py_DECREF(pyval); }
+#define INT_ERR_CODE -999
 
-#define DINFO_ERR -99
+#define HIGHFREQ_ORIG 719163
 
-#define CHECK_ASFREQ(result) if ((result) == DINFO_ERR) return NULL
+#define CHECK_ASFREQ(result) if ((result) == INT_ERR_CODE) return NULL
 
+static int get_freq_group(int freq) {
+    return (freq/1000)*1000;
+}
+
 struct asfreq_info{
     int from_week_end; //day the week ends on in the "from" frequency
     int to_week_end; //day the week ends on in the "to" frequency
@@ -61,6 +60,129 @@
 
 static struct asfreq_info NULL_AF_INFO;
 
+/*********************************************************
+** Python callbacks. These functions must be called by  **
+** the module __init__ script                           **
+*********************************************************/
+static PyObject *
+set_callback(PyObject *args, PyObject **callback)
+{
+    PyObject *result = NULL;
+    PyObject *temp;
+
+    if (PyArg_ParseTuple(args, "O:set_callback", &temp)) {
+
+        if (!PyCallable_Check(temp)) {
+            PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+            return NULL;
+        }
+
+        Py_XINCREF(temp);        // Add a reference to new callback
+        Py_XDECREF(*callback);  // Dispose of previous callback
+        *callback = temp;       // Remember new callback
+        // Boilerplate to return "None"
+        Py_INCREF(Py_None);
+        result = Py_None;
+    }
+    return result;
+}
+
+static PyObject *DateFromString = NULL;
+static char set_callback_DateFromString_doc[] =
+"set DateFromString function python callback";
+static PyObject *
+set_callback_DateFromString(PyObject *dummy, PyObject *args) {
+    return set_callback(args, &DateFromString);
+}
+
+static PyObject *DateTimeFromString = NULL;
+static char set_callback_DateTimeFromString_doc[] =
+"set DateTimeFromString function python callback";
+static PyObject *
+set_callback_DateTimeFromString(PyObject *dummy, PyObject *args) {
+    return set_callback(args, &DateTimeFromString);
+}
+
+/*********************************************************/
+
+static char *
+str_uppercase(char *str) {
+    if (str) {
+        int i, len=strlen(str);
+        char *result;
+        if((result = malloc((len + 1)*sizeof(char))) == NULL) {
+            return (char *)PyErr_NoMemory();
+        }
+        strcpy(result, str);
+
+        for (i=0;i<len;i++) {
+            switch(result[i])
+            {
+                case 'a': { result[i]='A'; break; }
+                case 'b': { result[i]='B'; break; }
+                case 'c': { result[i]='C'; break; }
+                case 'd': { result[i]='D'; break; }
+                case 'e': { result[i]='E'; break; }
+                case 'f': { result[i]='F'; break; }
+                case 'g': { result[i]='G'; break; }
+                case 'h': { result[i]='H'; break; }
+                case 'i': { result[i]='I'; break; }
+                case 'j': { result[i]='J'; break; }
+                case 'k': { result[i]='K'; break; }
+                case 'l': { result[i]='L'; break; }
+                case 'm': { result[i]='M'; break; }
+                case 'n': { result[i]='N'; break; }
+                case 'o': { result[i]='O'; break; }
+                case 'p': { result[i]='P'; break; }
+                case 'q': { result[i]='Q'; break; }
+                case 'r': { result[i]='R'; break; }
+                case 's': { result[i]='S'; break; }
+                case 't': { result[i]='T'; break; }
+                case 'u': { result[i]='U'; break; }
+                case 'v': { result[i]='V'; break; }
+                case 'w': { result[i]='W'; break; }
+                case 'x': { result[i]='X'; break; }
+                case 'y': { result[i]='Y'; break; }
+                case 'z': { result[i]='Z'; break; }
+            }
+        }
+
+        return result;
+    } else { return NULL; }
+}
+
+static char *
+str_replace(const char *s, const char *old, const char *new) {
+    char *ret;
+    int i, count = 0;
+    size_t newlen = strlen(new);
+    size_t oldlen = strlen(old);
+
+    for (i = 0; s[i] != '\0'; i++) {
+        if (strstr(&s[i], old) == &s[i]) {
+           count++;
+           i += oldlen - 1;
+        }
+    }
+
+    ret = malloc(i + 1 + count * (newlen - oldlen));
+    if (ret == NULL) {return (char *)PyErr_NoMemory();}
+
+    i = 0;
+    while (*s) {
+        if (strstr(s, old) == s) {
+            strcpy(&ret[i], new);
+            i += newlen;
+            s += oldlen;
+        } else {
+            ret[i++] = *s++;
+        }
+    }
+    ret[i] = '\0';
+
+    return ret;
+}
+
 //DERIVED FROM mx.DateTime
 /*
 =====================================================
@@ -429,45 +551,36 @@
 */
 
 
-//////////////////////////////////////////////////////////
 
-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) {
+static long DtoB_WeekendToMonday(long absdate, int day_of_week) {
 
-    long absdate = dinfo.absdate;
-    if (dinfo.day_of_week > 4) {
+    if (day_of_week > 4) {
         //change to Monday after weekend
-        absdate += (7 - dinfo.day_of_week);
+        absdate += (7 - day_of_week);
     }
     return DtoB_weekday(absdate);
 }
 
-static long DtoB_WeekendToFriday(struct date_info dinfo) {
+static long DtoB_WeekendToFriday(long absdate, int day_of_week) {
 
-    long absdate = dinfo.absdate;
-    if (dinfo.day_of_week > 4) {
+    if (day_of_week > 4) {
         //change to friday before weekend
-        absdate -= (dinfo.day_of_week - 4);
+        absdate -= (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;
+    if (dInfoCalc_SetFromDateAndTime(&tempDate, y, m, d, 0, 0, 0, GREGORIAN_CALENDAR)) return INT_ERR_CODE;
     return tempDate.absdate;
 }
 
@@ -483,7 +596,7 @@
 
     struct date_info dinfo;
     if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
-                    GREGORIAN_CALENDAR)) return DINFO_ERR;
+                    GREGORIAN_CALENDAR)) return INT_ERR_CODE;
     if (dinfo.month > af_info->to_a_year_end) { return (long)(dinfo.year + 1); }
     else { return (long)(dinfo.year); }
 }
@@ -493,7 +606,7 @@
 
     struct date_info dinfo;
     if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
-                    GREGORIAN_CALENDAR)) return DINFO_ERR;
+                    GREGORIAN_CALENDAR)) return INT_ERR_CODE;
     return (long)((dinfo.year - 1) * 4 + dinfo.quarter);
 }
 
@@ -501,7 +614,7 @@
 
     struct date_info dinfo;
     if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
-                    GREGORIAN_CALENDAR)) return DINFO_ERR;
+                    GREGORIAN_CALENDAR)) return INT_ERR_CODE;
     return (long)((dinfo.year - 1) * 12 + dinfo.month);
 }
 
@@ -513,12 +626,12 @@
 
     struct date_info dinfo;
     if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
-                    GREGORIAN_CALENDAR)) return DINFO_ERR;
+                    GREGORIAN_CALENDAR)) return INT_ERR_CODE;
 
     if (relation == 'B') {
-        return DtoB_WeekendToFriday(dinfo);
+        return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week);
     } else {
-        return DtoB_WeekendToMonday(dinfo);
+        return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week);
     }
 }
 
@@ -526,7 +639,7 @@
 
     struct date_info dinfo;
     if (dInfoCalc_SetFromAbsDate(&dinfo, fromDate,
-                    GREGORIAN_CALENDAR)) return DINFO_ERR;
+                    GREGORIAN_CALENDAR)) return INT_ERR_CODE;
 
     if (dinfo.day_of_week > 4) {
         return -1;
@@ -539,9 +652,9 @@
 static long asfreq_DtoD(long fromDate, char relation, struct asfreq_info *af_info) { return fromDate; }
 
 static long asfreq_DtoHIGHFREQ(long fromDate, char relation, long periodsPerDay) {
-    if (fromDate >= minval_D_toHighFreq) {
-        if (relation == 'B') { return (fromDate - minval_D_toHighFreq)*(periodsPerDay) + 1; }
-        else                 { return (fromDate - minval_D_toHighFreq + 1)*(periodsPerDay); }
+    if (fromDate >= HIGHFREQ_ORIG) {
+        if (relation == 'B') { return (fromDate - HIGHFREQ_ORIG)*(periodsPerDay) + 1; }
+        else                 { return (fromDate - HIGHFREQ_ORIG + 1)*(periodsPerDay); }
     } else { return -1; }
 }
 
@@ -555,7 +668,7 @@
 //************ FROM SECONDLY ***************
 
 static long asfreq_StoD(long fromDate, char relation, struct asfreq_info *af_info)
-    { return (fromDate - 1)/(60*60*24) + minval_D_toHighFreq; }
+    { return (fromDate - 1)/(60*60*24) + HIGHFREQ_ORIG; }
 
 static long asfreq_StoA(long fromDate, char relation, struct asfreq_info *af_info)
     { return asfreq_DtoA(asfreq_StoD(fromDate, relation, &NULL_AF_INFO), relation, af_info); }
@@ -577,7 +690,7 @@
 //************ FROM MINUTELY ***************
 
 static long asfreq_TtoD(long fromDate, char relation, struct asfreq_info *af_info)
-    { return (fromDate - 1)/(60*24) + minval_D_toHighFreq; }
+    { return (fromDate - 1)/(60*24) + HIGHFREQ_ORIG; }
 
 static long asfreq_TtoA(long fromDate, char relation, struct asfreq_info *af_info)
     { return asfreq_DtoA(asfreq_TtoD(fromDate, relation, &NULL_AF_INFO), relation, af_info); }
@@ -602,7 +715,7 @@
 //************ FROM HOURLY ***************
 
 static long asfreq_HtoD(long fromDate, char relation, struct asfreq_info *af_info)
-    { return (fromDate - 1)/24 + minval_D_toHighFreq; }
+    { return (fromDate - 1)/24 + HIGHFREQ_ORIG; }
 static long asfreq_HtoA(long fromDate, char relation, struct asfreq_info *af_info)
     { return asfreq_DtoA(asfreq_HtoD(fromDate, relation, &NULL_AF_INFO), relation, af_info); }
 static long asfreq_HtoQ(long fromDate, char relation, struct asfreq_info *af_info)
@@ -671,10 +784,10 @@
 
     struct date_info dinfo;
     if (dInfoCalc_SetFromAbsDate(&dinfo, asfreq_WtoD(fromDate, relation, af_info),
-                    GREGORIAN_CALENDAR)) return DINFO_ERR;
+                    GREGORIAN_CALENDAR)) return INT_ERR_CODE;
 
-    if (relation == 'B') { return DtoB_WeekendToMonday(dinfo); }
-    else                 { return DtoB_WeekendToFriday(dinfo); }
+    if (relation == 'B') { return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); }
+    else                 { return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); }
 }
 
 static long asfreq_WtoH(long fromDate, char relation, struct asfreq_info *af_info)
@@ -697,11 +810,11 @@
 
     if (relation == 'B') {
         MtoD_ym(fromDate, &y, &m);
-        if ((absdate = absdate_from_ymd(y, m, 1)) == DINFO_ERR) return DINFO_ERR;
+        if ((absdate = absdate_from_ymd(y, m, 1)) == INT_ERR_CODE) return INT_ERR_CODE;
         return absdate;
     } else {
         MtoD_ym(fromDate+1, &y, &m);
-        if ((absdate = absdate_from_ymd(y, m, 1)) == DINFO_ERR) return DINFO_ERR;
+        if ((absdate = absdate_from_ymd(y, m, 1)) == INT_ERR_CODE) return INT_ERR_CODE;
         return absdate-1;
     }
 }
@@ -723,10 +836,10 @@
 
     struct date_info dinfo;
     if (dInfoCalc_SetFromAbsDate(&dinfo, asfreq_MtoD(fromDate, relation, &NULL_AF_INFO),
-                    GREGORIAN_CALENDAR)) return DINFO_ERR;
+                    GREGORIAN_CALENDAR)) return INT_ERR_CODE;
 
-    if (relation == 'B') { return DtoB_WeekendToMonday(dinfo); }
-    else                 { return DtoB_WeekendToFriday(dinfo); }
+    if (relation == 'B') { return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); }
+    else                 { return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); }
 }
 
 static long asfreq_MtoH(long fromDate, char relation, struct asfreq_info *af_info)
@@ -749,11 +862,11 @@
 
     if (relation == 'B') {
         QtoD_ym(fromDate, &y, &m);
-        if ((absdate = absdate_from_ymd(y, m, 1)) == DINFO_ERR) return DINFO_ERR;
+        if ((absdate = absdate_from_ymd(y, m, 1)) == INT_ERR_CODE) return INT_ERR_CODE;
         return absdate;
     } else {
         QtoD_ym(fromDate+1, &y, &m);
-        if ((absdate = absdate_from_ymd(y, m, 1)) == DINFO_ERR) return DINFO_ERR;
+        if ((absdate = absdate_from_ymd(y, m, 1)) == INT_ERR_CODE) return INT_ERR_CODE;
         return absdate - 1;
     }
 }
@@ -777,10 +890,10 @@
 
     struct date_info dinfo;
     if (dInfoCalc_SetFromAbsDate(&dinfo, asfreq_QtoD(fromDate, relation, &NULL_AF_INFO),
-                    GREGORIAN_CALENDAR)) return DINFO_ERR;
+                    GREGORIAN_CALENDAR)) return INT_ERR_CODE;
 
-    if (relation == 'B') { return DtoB_WeekendToMonday(dinfo); }
-    else                 { return DtoB_WeekendToFriday(dinfo); }
+    if (relation == 'B') { return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); }
+    else                 { return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); }
 }
 
 
@@ -808,7 +921,7 @@
         final_adj = -1;
     }
     absdate = absdate_from_ymd(year, month, 1);
-    if (absdate  == DINFO_ERR) return DINFO_ERR;
+    if (absdate  == INT_ERR_CODE) return INT_ERR_CODE;
     return absdate + final_adj;
 }
 
@@ -836,7 +949,7 @@
 
 static long asfreq_AtoB(long fromDate, char relation, struct asfreq_info *af_info) {
 
-    long absdate, year;
+    long year;
     int month = (af_info->from_a_year_end + 1) % 12;
 
     struct date_info dailyDate;
@@ -848,8 +961,8 @@
 
         if (dInfoCalc_SetFromDateAndTime(&dailyDate,
                         year,month,1, 0, 0, 0,
-                        GREGORIAN_CALENDAR)) return DINFO_ERR;
-        return DtoB_WeekendToMonday(dailyDate);
+                        GREGORIAN_CALENDAR)) return INT_ERR_CODE;
+        return DtoB_WeekendToMonday(dailyDate.absdate, dailyDate.day_of_week);
     } else {
         long absdate;
 
@@ -858,15 +971,15 @@
 
         if (dInfoCalc_SetFromDateAndTime(&dailyDate,
                        year,month,1, 0, 0, 0,
-                       GREGORIAN_CALENDAR)) return DINFO_ERR;
+                       GREGORIAN_CALENDAR)) return INT_ERR_CODE;
 
         absdate = dailyDate.absdate - 1;
 
         if(dInfoCalc_SetFromAbsDate(&dailyDate,
                       absdate,
-                      GREGORIAN_CALENDAR)) return DINFO_ERR;
+                      GREGORIAN_CALENDAR)) return INT_ERR_CODE;
 
-        return DtoB_WeekendToFriday(dailyDate);
+        return DtoB_WeekendToFriday(dailyDate.absdate, dailyDate.day_of_week);
     }
 }
 
@@ -884,9 +997,11 @@
 // return a pointer to appropriate conversion function
 static long (*get_asfreq_func(int fromFreq, int toFreq, int forConvert))(long, char, struct asfreq_info*) {
 
-    int fromGroup = (fromFreq/1000)*1000;
-    int toGroup = (toFreq/1000)*1000;
+    int fromGroup = get_freq_group(fromFreq);
+    int toGroup = get_freq_group(toFreq);
 
+    if (fromGroup == FR_UND) { fromGroup = FR_DAY; }
+
     switch(fromGroup)
     {
         case FR_ANN:
@@ -1038,9 +1153,11 @@
     int maxBusDaysPerYear, maxBusDaysPerQuarter, maxBusDaysPerMonth;
     int maxDaysPerYear, maxDaysPerQuarter, maxDaysPerMonth;
 
-    int fromGroup = (fromFreq/1000)*1000;
-    int toGroup = (toFreq/1000)*1000;
+    int fromGroup = get_freq_group(fromFreq);
+    int toGroup = get_freq_group(toFreq);
 
+    if (fromGroup == FR_UND) { fromGroup = FR_DAY; }
+
     maxBusDaysPerYear = 262;
     maxBusDaysPerQuarter = 66;
     maxBusDaysPerMonth = 23;
@@ -1145,8 +1262,8 @@
 
 static void get_asfreq_info(int fromFreq, int toFreq, struct asfreq_info *af_info) {
 
-    int fromGroup = (fromFreq/1000)*1000;
-    int toGroup = (toFreq/1000)*1000;
+    int fromGroup = get_freq_group(fromFreq);
+    int toGroup = get_freq_group(toFreq);
 
     switch(fromGroup)
     {
@@ -1170,10 +1287,1250 @@
 
 }
 
-static char cseries_convert_doc[] = "";
+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); }
+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;
+
+    switch(freq)
+    {
+        case FR_HR:
+            periodsPerDay = 24;
+            break;
+        case FR_MIN:
+            periodsPerDay = 24*60;
+            break;
+        case FR_SEC:
+            periodsPerDay = 24*60*60;
+            break;
+        default:
+            return 0;
+    }
+
+    startOfDay = asfreq_DtoHIGHFREQ(dailyDate, 'B', periodsPerDay);
+    return (24*60*60)*((double)(originalDate - startOfDay))/((double)periodsPerDay);
+}
+
+/************************************************************
+** Date type definition
+************************************************************/
+
+typedef struct {
+    PyObject_HEAD
+    int freq; /* frequency of date */
+    int value; /* integer representation of date */
+    PyObject* cached_vals;
+} DateObject;
+
+/* Forward declarations */
+static PyTypeObject DateType;
+#define DateObject_Check(op) PyObject_TypeCheck(op, &DateType)
+
+static void
+DateObject_dealloc(DateObject* self) {
+    Py_XDECREF(self->cached_vals);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+
+static PyObject *freq_dict, *freq_dict_rev, *freq_constants;
+
+#define DICT_SETINT_STRKEY(dict, key, val) \
+    {PyObject *pyval = PyInt_FromLong(val); \
+     PyDict_SetItemString(dict, key, pyval); \
+     Py_DECREF(pyval); }
+
+#define ADD_FREQ_CONSTANT(const_name, val) \
+    DICT_SETINT_STRKEY(freq_constants, const_name, val)
+
+#define INIT_FREQ(const_name, key, aliases) \
+    {PyObject *pykey = PyInt_FromLong(key); \
+     PyDict_SetItem(freq_dict, pykey, aliases); \
+     PyDict_SetItemString(freq_constants, const_name, pykey); \
+     Py_DECREF(pykey); \
+     Py_DECREF(aliases); }
+
+
+static int init_freq_group(int num_items, int num_roots, int group_const,
+                            char item_abbrevs[][2][10], char group_prefixes[][10],
+                            char item_const_names[][10]) {
+
+    int i;
+
+    for (i = 0; i < num_items; i++) {
+
+        PyObject *aliases;
+        int j, size, k;
+
+        if (i == 0) { k = 3; } else { k = 2; }
+
+        size = num_roots * k;
+
+        aliases = PyTuple_New(size);
+
+        for (j = 0; j < num_roots; j++) {
+            PyObject *alias_v1, *alias_v2;
+            char *root, *alt;
+
+            if ((root = malloc((26) * sizeof(char))) == NULL) return INT_ERR_CODE;
+            if ((alt = malloc((26) * sizeof(char))) == NULL) return INT_ERR_CODE;
+
+            strcpy(root, group_prefixes[j]);
+            strcpy(alt, group_prefixes[j]);
+
+            if (i == 0) {
+                PyObject *alias = PyString_FromString(root);
+                PyTuple_SET_ITEM(aliases, j*k + 2, alias);
+            }
+
+            strcat(root, "-");
+            strcat(root, item_abbrevs[i][0]);
+            strcat(alt, "-");
+            strcat(alt, item_abbrevs[i][1]);
+
+            alias_v1 = PyString_FromString(root);
+            alias_v2 = PyString_FromString(alt);
+
+            free(root);
+            free(alt);
+
+            PyTuple_SET_ITEM(aliases, j*k, alias_v1);
+            PyTuple_SET_ITEM(aliases, j*k + 1, alias_v2);
+        }
+
+        INIT_FREQ(item_const_names[i], group_const+i, aliases);
+    }
+
+    return 0;
+}
+
+/* take a dictionary with integer keys and tuples of strings for values,
+   and populate a dictionary with all the strings as keys and integers
+   for values */
+static int reverse_dict(PyObject *source, PyObject *dest) {
+
+    PyObject *key, *value;
+
+    int pos = 0;
+
+    while (PyDict_Next(source, &pos, &key, &value)) {
+        PyObject *tuple_iter;
+        PyObject *item;
+
+        if((tuple_iter = PyObject_GetIter(value)) == NULL) return INT_ERR_CODE;
+
+        while (item = PyIter_Next(tuple_iter)) {
+            PyDict_SetItem(dest, item, key);
+            Py_DECREF(item);
+        }
+        Py_DECREF(tuple_iter);
+    }
+    return 0;
+}
+
+static int build_freq_dict() {
+
+    char ANN_prefixes[8][10] = { "A", "Y", "ANN", "ANNUAL", "ANNUALLY",
+                                 "YR", "YEAR", "YEARLY" };
+    char WK_prefixes[4][10] =  { "W", "WK", "WEEK", "WEEKLY" };
+
+    /* Note: order of this array must match up with how the Annual
+       frequency constants are lined up */
+    char month_names[12][2][10] = {
+        { "DEC", "DECEMBER" },
+        { "JAN", "JANUARY" },
+        { "FEB", "FEBRUARY" },
+        { "MAR", "MARCH" },
+        { "APR", "APRIL" },
+        { "MAY", "MAY" },
+        { "JUN", "JUNE" },
+        { "JUL", "JULY" },
+        { "AUG", "AUGUST" },
+        { "SEP", "SEPTEMBER" },
+        { "OCT", "OCTOBER" },
+        { "NOV", "NOVEMBER" }};
+
+    char ANN_const_names[12][10] = {
+        "FR_ANNDEC",
+        "FR_ANNJAN",
+        "FR_ANNFEB",
+        "FR_ANNMAR",
+        "FR_ANNAPR",
+        "FR_ANNMAY",
+        "FR_ANNJUN",
+        "FR_ANNJUL",
+        "FR_ANNAUG",
+        "FR_ANNSEP",
+        "FR_ANNOCT",
+        "FR_ANNNOV"};
+
+    char day_names[7][2][10] = {
+        { "SUN", "SUNDAY" },
+        { "MON", "MONDAY" },
+        { "TUE", "TUESDAY" },
+        { "WED", "WEDNESDAY" },
+        { "THU", "THURSDAY" },
+        { "FRI", "FRIDAY" },
+        { "SAT", "SATURDAY" }};
+
+    char WK_const_names[7][10] = {
+        "FR_WKSUN",
+        "FR_WKMON",
+        "FR_WKTUE",
+        "FR_WKWED",
+        "FR_WKTHU",
+        "FR_WKFRI",
+        "FR_WKSAT"};
+
+    PyObject *aliases;
+
+    freq_dict = PyDict_New();
+    freq_dict_rev = PyDict_New();
+    freq_constants = PyDict_New();
+
+    aliases = Py_BuildValue("(ssss)", "Q", "QTR", "QUARTER", "QUARTERLY");
+    INIT_FREQ("FR_QTR", FR_QTR, aliases);
+
+    aliases = Py_BuildValue("(ssss)", "M", "MTH", "MONTH", "MONTHLY");
+    INIT_FREQ("FR_MTH", FR_MTH, aliases);
+
+    aliases = Py_BuildValue("(ssss)", "B", "BUS", "BUSINESS", "BUSINESSLY");
+    INIT_FREQ("FR_BUS", FR_BUS, aliases);
+
+    aliases = Py_BuildValue("(ssss)", "D", "DAY", "DLY", "DAILY");
+    INIT_FREQ("FR_DAY", FR_DAY, aliases);
+
+    aliases = Py_BuildValue("(sssss)", "H", "HR", "HOUR", "HRLY", "HOURLY");
+    INIT_FREQ("FR_HR", FR_HR, aliases);
+
+    aliases = Py_BuildValue("(ssss)", "T", "MIN", "MINUTE", "MINUTELY");
+    INIT_FREQ("FR_MIN", FR_MIN, aliases);
+
+    aliases = Py_BuildValue("(ssss)", "S", "SEC", "SECOND", "SECONDLY");
+    INIT_FREQ("FR_SEC", FR_SEC, aliases);
+
+    aliases = Py_BuildValue("(ssss)", "U", "UND", "UNDEF", "UNDEFINED");
+    INIT_FREQ("FR_UND", FR_UND, aliases);
+
+    ADD_FREQ_CONSTANT("FR_ANN", FR_ANN);
+
+    if(init_freq_group(12, 8, FR_ANN,
+        month_names, ANN_prefixes, ANN_const_names) == INT_ERR_CODE) {
+            return INT_ERR_CODE;
+    }
+
+    ADD_FREQ_CONSTANT("FR_WK", FR_WK);
+
+    if(init_freq_group(7, 4, FR_WK,
+                    day_names, WK_prefixes, WK_const_names) == INT_ERR_CODE) {
+            return INT_ERR_CODE;
+    }
+
+    if(reverse_dict(freq_dict, freq_dict_rev) == INT_ERR_CODE) {
+        return INT_ERR_CODE;
+    }
+
+    return 0;
+}
+
+
+/* take user specified frequency and convert to int representation
+   of the frequency */
+static int check_freq(PyObject *freq_spec) {
+
+    if (PyInt_Check(freq_spec)) {
+        return (int)PyInt_AsLong(freq_spec);
+    } else if (PyString_Check(freq_spec)) {
+        char *freq_str, *freq_str_uc;
+        PyObject *freq_val;
+
+        freq_str = PyString_AsString(freq_spec);
+        if((freq_str_uc = str_uppercase(freq_str)) == NULL) {return INT_ERR_CODE;}
+
+        freq_val = PyDict_GetItemString(freq_dict_rev, freq_str_uc);
+
+        free(freq_str_uc);
+
+        if (freq_val == NULL) {
+            PyErr_SetString(PyExc_ValueError, "invalid frequency specification");
+            return INT_ERR_CODE;
+        } else {
+            int ret_val = (int)PyInt_AsLong(freq_val);
+            return ret_val;
+        }
+    } else if (freq_spec == Py_None) {
+        return FR_UND;
+    } else {
+        int retval = (int)PyInt_AsLong(freq_spec);
+        if (PyErr_Occurred()) {
+            PyErr_SetString(PyExc_ValueError, "invalid frequency specification");
+            return INT_ERR_CODE;
+        } else { return retval; }
+    }
+
+}
+
 static PyObject *
-cseries_convert(PyObject *self, PyObject *args)
+DateObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
+
+    DateObject *self;
+
+    self = (DateObject*)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        // initialize attributes that need initializing in here
+        self->freq = FR_UND;
+        self->value = -1;
+    }
+
+    return (PyObject *)self;
+}
+
+/* for use in C code */
+static DateObject *
+DateObject_New() {
+    PyObject *dummy;
+    return (DateObject*)DateObject_new(&DateType, dummy, dummy);
+}
+
+#define INIT_ERR(errortype, errmsg) PyErr_SetString(errortype,errmsg);return -1
+
+static int
+DateObject_init(DateObject *self, PyObject *args, PyObject *kwds) {
+
+    PyObject *freq=NULL, *value=NULL, *datetime=NULL, *string=NULL;
+    char *INSUFFICIENT_MSG = "insufficient parameters to initialize Date";
+
+    int def_info=INT_ERR_CODE;
+
+    int year=def_info, month=def_info, day=def_info, quarter=def_info,
+        hour=def_info, minute=def_info, second=def_info;
+
+    int free_dt=0;
+
+    static char *kwlist[] = {"freq", "value", "string",
+                             "year", "month", "day", "quarter",
+                             "hour", "minute", "second",
+                             "datetime", NULL};
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OOiiiiiiiO", kwlist,
+                                      &freq, &value, &string,
+                                      &year, &month, &day, &quarter,
+                                      &hour, &minute, &second,
+                                      &datetime)) return -1;
+
+    if (PyObject_HasAttrString(freq, "freq")) {
+        PyObject *freq_attr = PyObject_GetAttrString(freq, "freq");
+        self->freq = PyInt_AS_LONG(freq_attr);
+        Py_DECREF(freq_attr);
+    } else {
+        if((self->freq = check_freq(freq)) == INT_ERR_CODE) return -1;
+    }
+
+    if ((value && PyString_Check(value)) || string) {
+
+        PyObject *string_arg = PyTuple_New(1);
+        int freq_group = get_freq_group(self->freq);
+
+        free_dt = 1;
+
+        if (!string) {
+            string = value;
+        }
+
+        PyTuple_SET_ITEM(string_arg, 0, string);
+        Py_INCREF(string);
+
+        if (freq_group == FR_HR ||
+            freq_group == FR_MIN ||
+            freq_group == FR_SEC)
+             { datetime = PyEval_CallObject(DateTimeFromString, string_arg); }
+        else { datetime = PyEval_CallObject(DateFromString, string_arg); }
+
+        Py_DECREF(string_arg);
+
+        value = NULL;
+    }
+
+    if (value) {
+        self->value = PyInt_AsLong(value);
+    } else {
+
+        int freq_group = get_freq_group(self->freq);
+
+        if (datetime) {
+            year=PyDateTime_GET_YEAR(datetime);
+            month=PyDateTime_GET_MONTH(datetime);
+            day=PyDateTime_GET_DAY(datetime);
+            hour=PyDateTime_DATE_GET_HOUR(datetime);
+            minute=PyDateTime_DATE_GET_MINUTE(datetime);
+            second=PyDateTime_DATE_GET_SECOND(datetime);
+        }
+
+        if (!datetime) {
+
+            // First, some basic checks.....
+            if (year == def_info) {
+                INIT_ERR(PyExc_ValueError, INSUFFICIENT_MSG);
+            }
+            if (self->freq == FR_BUS ||
+               self->freq == FR_DAY ||
+               self->freq == FR_WK ||
+               self->freq == FR_UND) {
+                if (month == def_info || day == def_info) {
+                    INIT_ERR(PyExc_ValueError, INSUFFICIENT_MSG);
+                }
+
+                // if FR_BUS, check for week day
+
+            } else if (self->freq == FR_MTH) {
+                if (month == def_info) {
+                    INIT_ERR(PyExc_ValueError, INSUFFICIENT_MSG);
+                }
+            } else if (self->freq == FR_QTR) {
+                if (quarter == def_info && month == def_info) {
+                    INIT_ERR(PyExc_ValueError, INSUFFICIENT_MSG);
+                } else if (month != def_info) {
+                    quarter = (int)asfreq_MtoQ(month, '-', &NULL_AF_INFO);
+                }
+            } else if (self->freq == FR_SEC) {
+                if (month == def_info ||
+                    day == def_info ||
+                    second == def_info) {
+                    INIT_ERR(PyExc_ValueError, INSUFFICIENT_MSG);
+                }
+                if (hour == def_info) {
+                    hour = second/3600;
+                    minute = (second % 3600)/60;
+                    second = second % 60;
+                } else if (minute == def_info) {
+                    INIT_ERR(PyExc_ValueError, INSUFFICIENT_MSG);
+                }
+            } else if (self->freq == FR_MIN) {
+                if (month == def_info ||
+                    day == def_info ||
+                    minute == def_info) {
+                    INIT_ERR(PyExc_ValueError, INSUFFICIENT_MSG);
+                }
+                if (hour == def_info) {
+                    hour = minute/60;
+                    minute = minute % 60;
+                }
+            } else if (self->freq == FR_HR) {
+                if (month == def_info ||
+                    day == def_info ||
+                    hour == def_info) {
+                    INIT_ERR(PyExc_ValueError, INSUFFICIENT_MSG);
+                }
+            }
+
+        }
+
+        if (self->freq == FR_SEC) {
+            long absdays, delta;
+            absdays = absdate_from_ymd(year, month, day);
+            delta = (absdays - HIGHFREQ_ORIG);
+            self->value = (int)(delta*86400 + hour*3600 + minute*60 + second + 1);
+        } else if (self->freq == FR_MIN) {
+            long absdays, delta;
+            absdays = absdate_from_ymd(year, month, day);
+            delta = (absdays - HIGHFREQ_ORIG);
+            self->value = (int)(delta*1440 + hour*60 + minute + 1);
+        } else if (self->freq == FR_HR) {
+            long absdays, delta;
+            absdays = absdate_from_ymd(year, month, day);
+            delta = (absdays - HIGHFREQ_ORIG);
+            self->value = (int)(delta*24 + hour + 1);
+        } else if (self->freq == FR_DAY) {
+            self->value = (int)absdate_from_ymd(year, month, day);
+        } else if (self->freq == FR_UND) {
+            self->value = (int)absdate_from_ymd(year, month, day);
+        } else if (self->freq == FR_BUS) {
+            long weeks, days;
+            days = absdate_from_ymd(year, month, day);
+            weeks = days/7;
+            self->value = (int)(days - weeks*2);
+        } else if (freq_group == FR_WK) {
+            int adj_ordinal;
+            int ordinal = (int)absdate_from_ymd(year, month, day);
+            int day_adj = (7 - (self->freq - FR_WK)) % 7;
+
+            adj_ordinal = ordinal + ((7 - day_adj) - ordinal % 7) % 7;
+            self->value = adj_ordinal/7;
+        } else if (self->freq == FR_MTH) {
+            self->value = (year-1)*12 + month;
+        } else if (self->freq == FR_QTR) {
+            self->value = (year-1)*4 + quarter;
+        } else if (freq_group == FR_ANN) {
+            self->value = year;
+        }
+
+    }
+
+    if (free_dt) { Py_DECREF(datetime); }
+
+    return 0;
+}
+
+static PyMemberDef DateObject_members[] = {
+    {"freq", T_INT, offsetof(DateObject, freq), 0,
+     "frequency"},
+    {"value", T_INT, offsetof(DateObject, value), 0,
+     "integer representation of the Date"},
+    {NULL}  /* Sentinel */
+};
+
+static char DateObject_toordinal_doc[] =
+"Return the proleptic Gregorian ordinal of the date, where January 1 of\n"
+"year 1 has ordinal 1";
+static PyObject *
+DateObject_toordinal(DateObject* self)
 {
+    if (self->freq == FR_DAY) {
+        return PyInt_FromLong(self->value);
+    } else {
+        long (*toDaily)(long, char, struct asfreq_info*) = NULL;
+        struct asfreq_info af_info;
+
+        toDaily = get_asfreq_func(self->freq, FR_DAY, 0);
+        get_asfreq_info(self->freq, FR_DAY, &af_info);
+
+        return PyInt_FromLong(toDaily(self->value, 'A', &af_info));
+    }
+}
+
+static char DateObject_asfreq_doc[] =
+"Returns a date converted to a specified frequency.\n\n"
+":Parameters:\n"
+"   - freq : string/int\n"
+"       Frequency to convert the Date to. Accepts any valid frequency\n"
+"       specification (string or integer)\n"
+"   - relation :string *['After']*\n"
+"       Applies only when converting a lower frequency Date to a higher\n"
+"       frequency Date, or when converting a weekend Date to a business\n"
+"       frequency Date. Valid values are 'before', 'after', 'b', and 'a'.";
+static PyObject *
+DateObject_asfreq(DateObject *self, PyObject *args, PyObject *kwds)
+{
+
+    PyObject *freq=NULL;
+    char *relation_raw=NULL;
+    char *relation_uc;
+    char relation;
+    int invalid_relation=0;
+    int toFreq;
+    int result_val;
+    DateObject *result = DateObject_New();
+
+    static char *kwlist[] = {"freq", "relation", NULL};
+
+    long (*asfreq_func)(long, char, struct asfreq_info*) = NULL;
+    struct asfreq_info af_info;
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|s", kwlist,
+                                      &freq, &relation_raw)) return NULL;
+
+    if(relation_raw) {
+        if (strlen(relation_raw) > 0) {
+            if((relation_uc = str_uppercase(relation_raw)) == NULL)
+            {return PyErr_NoMemory();}
+
+            if (strcmp(relation_uc, "BEFORE") == 0 ||
+                strcmp(relation_uc, "B") == 0 ||
+                strcmp(relation_uc, "AFTER") == 0 ||
+                strcmp(relation_uc, "A") == 0) {
+                 relation = relation_uc[0];
+            } else { invalid_relation=1; }
+        } else {
+            invalid_relation=1;
+        }
+
+        if (invalid_relation) {
+            PyErr_SetString(PyExc_ValueError,"Invalid relation specification");
+            return NULL;
+        }
+    } else {
+        relation = 'A';
+    }
+
+    if ((toFreq = check_freq(freq)) == INT_ERR_CODE) return NULL;
+
+    get_asfreq_info(self->freq, toFreq, &af_info);
+    asfreq_func = get_asfreq_func(self->freq, toFreq, 0);
+
+    result_val = asfreq_func(self->value, relation, &af_info);
+
+    result->freq = toFreq;
+    result->value = result_val;
+
+    return (PyObject*)result;
+
+}
+
+static char DateObject_strfmt_doc[] =
+"Returns string representation of Date object according to format specified.\n\n"
+":Parameters:\n"
+"   - fmt : string\n"
+"       Formatting string. Uses the same directives as in the time.strftime\n"
+"       function in the standard Python time module. In addition, a %q directive\n"
+"       directive is recognized which represents the 'quarter' of the date";
+static PyObject *
+DateObject_strfmt(DateObject *self, PyObject *args)
+{
+
+    char *orig_fmt_str, *fmt_str;
+    char *result;
+
+    char extra_fmts[1][2][10] = {{"%q", "^`XZ`^"}};
+    int extra_fmts_found[1] = {0};
+    int extra_fmts_found_one = 0;
+    struct tm c_date;
+    struct date_info tempDate;
+    long absdate;
+    double abstime;
+    int i, result_len, special_found=0;
+    PyObject *py_result;
+
+    long (*toDaily)(long, char, struct asfreq_info*) = NULL;
+    struct asfreq_info af_info;
+
+    if (!PyArg_ParseTuple(args, "s:strfmt(fmt)", &orig_fmt_str)) return NULL;
+
+    toDaily = get_asfreq_func(self->freq, FR_DAY, 0);
+    get_asfreq_info(self->freq, FR_DAY, &af_info);
+
+    absdate = toDaily(self->value, 'A', &af_info);
+    abstime = getAbsTime(self->freq, absdate, self->value);
+
+    if(dInfoCalc_SetFromAbsDateTime(&tempDate, absdate, abstime,
+                                    GREGORIAN_CALENDAR)) return NULL;
+
+    // populate standard C date struct with info from our date_info struct
+    c_date.tm_sec = (int)tempDate.second;
+    c_date.tm_min = tempDate.minute;
+    c_date.tm_hour = tempDate.hour;
+    c_date.tm_mday = tempDate.day;
+    c_date.tm_mon = tempDate.month - 1;
+    c_date.tm_year = tempDate.year - 1900;
+    c_date.tm_wday = tempDate.day_of_week;
+    c_date.tm_yday = tempDate.day_of_year;
+    c_date.tm_isdst = -1;
+
+    result_len = strlen(orig_fmt_str) + 50;
+    if ((result = malloc(result_len * sizeof(char))) == NULL) {return PyErr_NoMemory();}
+
+    fmt_str = orig_fmt_str;
+
+    // replace any special format characters with their place holder
+    for(i=0; i < 1; i++) {
+        char *special_loc;
+        if ((special_loc = strstr(fmt_str,extra_fmts[i][0])) != NULL) {
+            char *tmp_str = fmt_str;
+            fmt_str = str_replace(fmt_str, extra_fmts[i][0],
+                                           extra_fmts[i][1]);
+            /* only free the previous loop value if this is not the first
+               special format string found */
+            if (extra_fmts_found_one) { free(tmp_str); }
+
+            if (fmt_str == NULL) {return NULL;}
+
+            extra_fmts_found[i] = 1;
+            extra_fmts_found_one = 1;
+        }
+    }
+
+    strftime(result, result_len, fmt_str, &c_date);
+    if (extra_fmts_found_one) { free(fmt_str); }
+
+    // replace any place holders with the appropriate value
+    for(i=0; i < 1; i++) {
+        if (extra_fmts_found[i]) {
+            char *tmp_str = result;
+            char *extra_str;
+
+            if(strcmp(extra_fmts[i][0], "%q") == 0) {
+                if ((extra_str = malloc(2 * sizeof(char))) == NULL) {
+                    free(tmp_str);
+                    return PyErr_NoMemory();
+                }
+
+                sprintf(extra_str, "%i", tempDate.quarter);
+            } else {
+                PyErr_SetString(PyExc_RuntimeError,"Unrecogized fmt string");
+                return NULL;
+            }
+
+            result = str_replace(result, extra_fmts[i][1], extra_str);
+            free(tmp_str);
+            if (result == NULL) { return NULL; }
+        }
+    }
+
+    py_result = PyString_FromString(result);
+    free(result);
+
+    return py_result;
+}
+
+static PyObject *
+DateObject___str__(DateObject* self)
+{
+
+    int freq_group = get_freq_group(self->freq);
+    PyObject *string_arg, *retval;
+
+    if (freq_group == FR_ANN) { string_arg = Py_BuildValue("(s)", "%Y"); }
+    else if (freq_group == FR_QTR) { string_arg = Py_BuildValue("(s)", "%YQ%q"); }
+    else if (freq_group == FR_MTH) { string_arg = Py_BuildValue("(s)", "%b-%Y"); }
+    else if (freq_group == FR_DAY ||
+             freq_group == FR_BUS ||
+             freq_group == FR_WK ||
+             freq_group == FR_UND) { string_arg = Py_BuildValue("(s)", "%d-%b-%Y"); }
+    else if (freq_group == FR_HR) { string_arg = Py_BuildValue("(s)", "%d-%b-%Y %H:00"); }
+    else if (freq_group == FR_MIN) { string_arg = Py_BuildValue("(s)", "%d-%b-%Y %H:%M"); }
+    else if (freq_group == FR_SEC) { string_arg = Py_BuildValue("(s)", "%d-%b-%Y %H:%M:%S"); }
+
+    if (string_arg == NULL) { return NULL; }
+
+    retval = DateObject_strfmt(self, string_arg);
+    Py_DECREF(string_arg);
+
+    return retval;
+}
+
+static PyObject *
+DateObject_freqstr(DateObject *self, void *closure) {
+    PyObject *key = PyInt_FromLong(self->freq);
+    PyObject *freq_aliases = PyDict_GetItem(freq_dict, key);
+    PyObject *main_alias = PyTuple_GET_ITEM(freq_aliases, 0);
+    Py_DECREF(key);
+    Py_INCREF(main_alias);
+    return main_alias;
+}
+
+
+static PyObject *
+DateObject___repr__(DateObject* self)
+{
+    PyObject *py_str_rep, *py_freqstr, *py_repr;
+    char *str_rep, *freqstr, *repr;
+    int repr_len;
+
+    py_str_rep = DateObject___str__(self);
+    if (py_str_rep == NULL) { return NULL; }
+
+    py_freqstr = DateObject_freqstr(self, NULL);
+
+    str_rep = PyString_AsString(py_str_rep);
+    freqstr = PyString_AsString(py_freqstr);
+
+    repr_len = strlen(str_rep) + strlen(freqstr) + 6;
+
+    if((repr = malloc((repr_len + 1) * sizeof(char))) == NULL)
+    { return PyErr_NoMemory(); }
+
+    strcpy(repr, "<");
+    strcat(repr, freqstr);
+    strcat(repr, " : ");
+    strcat(repr, str_rep);
+    strcat(repr, ">");
+
+    py_repr = PyString_FromString(repr);
+
+    Py_DECREF(py_str_rep);
+    Py_DECREF(py_freqstr);
+
+    free(repr);
+
+    return py_repr;
+}
+
+/******************************
+   These methods seem rather useless. May or may not implement them.
+fromordinal(self, ordinal):
+    return Date(self.freq, datetime=dt.datetime.fromordinal(ordinal))
+tostring(self):
+    return str(self)
+toobject(self):
+    return self
+isvalid(self):
+    return True
+*******************************/
+
+
+static DateObject *
+DateObject_FromFreqAndValue(int freq, int value) {
+
+    DateObject *result = DateObject_New();
+
+    PyObject *args = PyTuple_New(0);
+    PyObject *kw = PyDict_New();
+    PyObject *py_freq = PyInt_FromLong(freq);
+    PyObject *py_value = PyInt_FromLong(value);
+
+    PyDict_SetItemString(kw, "freq", py_freq);
+    PyDict_SetItemString(kw, "value", py_value);
+
+    Py_DECREF(py_freq);
+    Py_DECREF(py_value);
+
+    DateObject_init(result, args, kw);
+
+    Py_DECREF(args);
+    Py_DECREF(kw);
+
+    return result;
+}
+
+static PyObject *
+DateObject_date_plus_int(PyObject *date, PyObject *pyint) {
+    DateObject *dateobj = (DateObject*)date;
+    if (DateObject_Check(pyint)) {
+        PyErr_SetString(PyExc_TypeError, "Cannot add two Date objects");
+        return NULL;
+    }
+
+    return (PyObject*)DateObject_FromFreqAndValue(dateobj->freq, PyInt_AsLong(pyint) + dateobj->value);
+}
+
+static PyObject *
+DateObject___add__(PyObject *left, PyObject *right)
+{
+    if (DateObject_Check(left)) {
+        return DateObject_date_plus_int(left, right);
+    } else {
+        return DateObject_date_plus_int(right, left);
+    }
+}
+
+static PyObject *
+DateObject___subtract__(PyObject *left, PyObject *right)
+{
+    int result;
+    DateObject *dleft;
+    if (!DateObject_Check(left)) {
+        PyErr_SetString(PyExc_ValueError, "Cannot subtract Date from non-Date value");
+        return NULL;
+    }
+
+    dleft = (DateObject*)left;
+
+    if (DateObject_Check(right)) {
+        DateObject *dright = (DateObject*)right;
+        if (dleft->freq != dright->freq) {
+            PyErr_SetString(PyExc_ValueError, "Cannot subtract Dates with different frequency");
+            return NULL;
+        }
+        result = dleft->value - dright->value;
+        return PyInt_FromLong(result);
+    } else {
+        result = dleft->value - PyInt_AsLong(right);
+        return (PyObject*)DateObject_FromFreqAndValue(dleft->freq, result);
+    }
+}
+
+static int
+DateObject___compare__(DateObject * obj1, DateObject * obj2)
+{
+    if (obj1->freq != obj2->freq) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Cannot compare dates with different frequency");
+        return -1;
+    }
+
+    if (obj1->value < obj2->value) return -1;
+    if (obj1->value > obj2->value) return 1;
+    if (obj1->value == obj2->value) return 0;
+
+}
+
+static long
+DateObject___hash__(DateObject *self)
+{
+    register int freq_group = get_freq_group(self->freq);
+
+    /* within a given frequency, hash values are guaranteed to be unique
+       for different dates. For different frequencies, we make a reasonable
+       effort to ensure hash values will be unique, but it is not guaranteed */
+    if (freq_group == FR_BUS) {
+        return self->value + 10000000;
+    } else if (freq_group == FR_WK) {
+        return self->value + 100000000;
+    } else { return self->value; }
+}
+
+static PyObject *
+DateObject___int__(DateObject *self)
+{
+    return PyInt_FromLong(self->value);
+}
+
+static PyObject *
+DateObject___float__(DateObject *self)
+{
+    return PyFloat_FromDouble((double)(self->value));
+}
+
+/***************************************************
+           ====== Date Properties ======
+****************************************************/
+
+// helper function for date property funcs
+static int
+DateObject_set_date_info(DateObject *self, struct date_info *dinfo) {
+    PyObject *daily_obj = DateObject_toordinal(self);
+    long absdate = PyInt_AsLong(daily_obj);
+
+    Py_DECREF(daily_obj);
+
+    if(dInfoCalc_SetFromAbsDate(dinfo, absdate,
+                                GREGORIAN_CALENDAR)) return -1;
+
+    return 0;
+}
+
+// helper function for date property funcs
+static int
+DateObject_set_date_info_wtime(DateObject *self, struct date_info *dinfo) {
+    PyObject *daily_obj = DateObject_toordinal(self);
+    long absdate = PyInt_AsLong(daily_obj);
+    double abstime;
+
+    Py_DECREF(daily_obj);
+
+    abstime = getAbsTime(self->freq, absdate, self->value);
+
+    if(dInfoCalc_SetFromAbsDateTime(dinfo, absdate, abstime,
+                                    GREGORIAN_CALENDAR)) return -1;
+
+    return 0;
+}
+
+static PyObject *
+DateObject_year(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong(dinfo.year);
+}
+
+static PyObject *
+DateObject_quarter(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong(dinfo.quarter);
+}
+
+static PyObject *
+DateObject_month(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong(dinfo.month);
+}
+
+static PyObject *
+DateObject_day(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong(dinfo.day);
+}
+
+static PyObject *
+DateObject_day_of_week(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong(dinfo.day_of_week);
+}
+
+static PyObject *
+DateObject_day_of_year(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong(dinfo.day_of_year);
+}
+
+static PyObject *
+DateObject_week(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong(dInfoCalc_ISOWeek(&dinfo));
+}
+
+static PyObject *
+DateObject_hour(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info_wtime(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong(dinfo.hour);
+}
+
+static PyObject *
+DateObject_minute(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info_wtime(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong(dinfo.minute);
+}
+
+static PyObject *
+DateObject_second(DateObject *self, void *closure) {
+    struct date_info dinfo;
+    if(DateObject_set_date_info_wtime(self, &dinfo) == -1) return NULL;
+    return PyInt_FromLong((int)dinfo.second);
+}
+
+static PyObject *
+DateObject_datetime(DateObject *self, void *closure) {
+    PyObject *datetime;
+    struct date_info dinfo;
+    if(DateObject_set_date_info_wtime(self, &dinfo) == -1) return NULL;
+    datetime = PyDateTime_FromDateAndTime(dinfo.year, dinfo.month,
+                                          dinfo.day, dinfo.hour,
+                                          dinfo.minute, (int)dinfo.second, 0);
+    return datetime;
+}
+
+static int
+DateObject_ReadOnlyErr(DateObject *self, PyObject *value, void *closure) {
+   PyErr_SetString(PyExc_AttributeError, "Cannot set read-only property");
+   return -1;
+}
+
+static PyGetSetDef DateObject_getseters[] = {
+    {"year", (getter)DateObject_year, (setter)DateObject_ReadOnlyErr,
+            "Returns the year.", NULL},
+    {"quarter", (getter)DateObject_quarter, (setter)DateObject_ReadOnlyErr,
+            "Returns the quarter.", NULL},
+    {"month", (getter)DateObject_month, (setter)DateObject_ReadOnlyErr,
+            "Returns the month.", NULL},
+    {"week", (getter)DateObject_week, (setter)DateObject_ReadOnlyErr,
+            "Returns the week.", NULL},
+    {"day", (getter)DateObject_day, (setter)DateObject_ReadOnlyErr,
+            "Returns the day of month.", NULL},
+    {"day_of_week", (getter)DateObject_day_of_week, (setter)DateObject_ReadOnlyErr,
+            "Returns the day of week.", NULL},
+    {"day_of_year", (getter)DateObject_day_of_year, (setter)DateObject_ReadOnlyErr,
+            "Returns the day of year.", NULL},
+    {"second", (getter)DateObject_second, (setter)DateObject_ReadOnlyErr,
+            "Returns the second.", NULL},
+    {"minute", (getter)DateObject_minute, (setter)DateObject_ReadOnlyErr,
+            "Returns the minute.", NULL},
+    {"hour", (getter)DateObject_hour, (setter)DateObject_ReadOnlyErr,
+            "Returns the hour.", NULL},
+
+    {"freqstr", (getter)DateObject_freqstr, (setter)DateObject_ReadOnlyErr,
+            "Returns the string representation of frequency.", NULL},
+    {"datetime", (getter)DateObject_datetime, (setter)DateObject_ReadOnlyErr,
+            "Returns the Date object converted to standard python datetime object",
+            NULL},
+
+    {NULL}  /* Sentinel */
+};
+
+
+static PyNumberMethods DateObject_as_number = {
+    (binaryfunc)DateObject___add__,      /* nb_add */
+    (binaryfunc)DateObject___subtract__, /* nb_subtract */
+    0,                                   /* nb_multiply */
+    0,                                   /* nb_divide */
+    0,                                   /* nb_remainder */
+    0,                                   /* nb_divmod */
+    0,                                   /* nb_power */
+    0,                                   /* nb_negative */
+    0,                                   /* nb_positive */
+    0,                                   /* nb_absolute */
+    0,                                   /* nb_nonzero */
+    0,				                     /* nb_invert */
+    0,	                                 /* nb_lshift */
+    0,	                                 /* nb_rshift */
+    0,	                                 /* nb_and */
+    0,	                                 /* nb_xor */
+    0,	                                 /* nb_or */
+    0,		                             /* nb_coerce */
+    (unaryfunc)DateObject___int__,		 /* nb_int */
+    (unaryfunc)0,				         /* nb_long */
+    (unaryfunc)DateObject___float__,	 /* nb_float */
+    (unaryfunc)0,				         /* nb_oct */
+    (unaryfunc)0,				         /* nb_hex */
+};
+
+static PyMethodDef DateObject_methods[] = {
+    {"toordinal", (PyCFunction)DateObject_toordinal, METH_NOARGS,
+     DateObject_toordinal_doc},
+    {"strfmt", (PyCFunction)DateObject_strfmt, METH_VARARGS,
+     DateObject_strfmt_doc},
+    {"asfreq", (PyCFunction)DateObject_asfreq, METH_VARARGS | METH_KEYWORDS,
+     DateObject_asfreq_doc},
+    {NULL}  /* Sentinel */
+};
+
+
+static PyTypeObject DateType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                               /* ob_size */
+    "timeseries.Date",               /* tp_name */
+    sizeof(DateObject),              /* tp_basicsize */
+    0,                               /* tp_itemsize */
+    (destructor)DateObject_dealloc,  /* tp_dealloc */
+    0,                               /* tp_print */
+    0,                               /* tp_getattr */
+    0,                               /* tp_setattr */
+    (cmpfunc)DateObject___compare__, /* tp_compare */
+    (reprfunc)DateObject___repr__,   /* tp_repr */
+    &DateObject_as_number,           /* tp_as_number */
+    0,                               /* tp_as_sequence */
+    0,                               /* tp_as_mapping */
+    (hashfunc)DateObject___hash__,   /* tp_hash */
+    0,                               /* tp_call*/
+    (reprfunc)DateObject___str__,    /* tp_str */
+    0,                               /* tp_getattro */
+    0,                               /* tp_setattro */
+    0,                               /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |             /* tp_flags */
+    Py_TPFLAGS_CHECKTYPES |
+    Py_TPFLAGS_BASETYPE,
+    "Defines a Date object, as the combination of a date and a frequency.\n"
+    "Several options are available to construct a Date object explicitly:\n\n"
+    "- Give appropriate values to the `year`, `month`, `day`, `quarter`, `hours`,\n"
+    "  `minutes`, `seconds` arguments.\n\n"
+    "  >>> td.Date(freq='Q',year=2004,quarter=3)\n"
+    "  >>> td.Date(freq='D',year=2001,month=1,day=1)\n\n"
+    "- Use the `string` keyword. This method uses a modified version of the\n"
+    "  mx.DateTime parser submodule. More information is available in its\n"
+    "  documentation.\n\n"
+    "  >>> ts.Date('D', '2007-01-01')\n\n"
+    "- Use the `datetime` keyword with an existing datetime.datetime object.\n\n"
+    "  >>> td.Date('D', datetime=datetime.datetime.now())",  /* tp_doc */
+    0,                               /* tp_traverse */
+    0,                               /* tp_clear */
+    0,                               /* tp_richcompare */
+    0,                               /* tp_weaklistoffset */
+    0,                               /* tp_iter */
+    0,                               /* tp_iternext */
+    DateObject_methods,              /* tp_methods */
+    DateObject_members,              /* tp_members */
+    DateObject_getseters,            /* tp_getset */
+    0,                               /* tp_base */
+    0,                               /* tp_dict */
+    0,                               /* tp_descr_get */
+    0,                               /* tp_descr_set */
+    0,                               /* tp_dictoffset */
+    (initproc)DateObject_init,       /* tp_init */
+    0,                               /* tp_alloc */
+    DateObject_new,                  /* tp_new */
+};
+
+
+///////////////////////////////////////////////////////////////////////
+
+static char cseries_check_freq_doc[] =
+"translate user specified frequency into frequency constant";
+static PyObject *
+cseries_check_freq(PyObject *self, PyObject *args) {
+
+    PyObject *freq;
+    int freq_val;
+
+    if (!PyArg_ParseTuple(args, "O:check_freq(freq)", &freq)) return NULL;
+    if ((freq_val = check_freq(freq)) == INT_ERR_CODE) return NULL;
+
+    return PyInt_FromLong(freq_val);
+}
+
+static char cseries_check_freq_str_doc[] =
+"translate user specified frequency into standard string representation";
+static PyObject *
+cseries_check_freq_str(PyObject *self, PyObject *args) {
+
+    PyObject *alias_tuple, *result, *freq_key;
+    int freq_val;
+
+    if ((freq_key = cseries_check_freq(self, args)) == NULL) return NULL;
+
+    alias_tuple = PyDict_GetItem(freq_dict, freq_key);
+    result = PyTuple_GET_ITEM(alias_tuple, 0);
+
+    Py_INCREF(result);
+
+    Py_DECREF(freq_key);
+
+    return result;
+}
+
+static char cseries_thisday_doc[] =
+"Returns today's date, at the given frequency\n\n"
+":Parameters:\n"
+"   - freq : string/int\n"
+"       Frequency to convert the Date to. Accepts any valid frequency\n"
+"       specification (string or integer)\n";
+static PyObject *
+cseries_thisday(PyObject *self, PyObject *args) {
+
+    PyObject *freq, *init_args, *init_kwargs;
+    time_t rawtime;
+    struct tm *timeinfo;
+    int freq_val;
+
+    DateObject *secondly_date;
+
+    if (!PyArg_ParseTuple(args, "O:thisday(freq)", &freq)) return NULL;
+
+    if ((freq_val = check_freq(freq)) == INT_ERR_CODE) return NULL;
+
+    time(&rawtime);
+    timeinfo = localtime(&rawtime);
+
+    init_args = PyTuple_New(0);
+    init_kwargs = PyDict_New();
+
+    DICT_SETINT_STRKEY(init_kwargs, "freq", FR_SEC);
+    DICT_SETINT_STRKEY(init_kwargs, "year", timeinfo->tm_year+1900);
+    DICT_SETINT_STRKEY(init_kwargs, "month", timeinfo->tm_mon+1);
+    DICT_SETINT_STRKEY(init_kwargs, "day", timeinfo->tm_mday);
+    DICT_SETINT_STRKEY(init_kwargs, "hour", timeinfo->tm_hour);
+    DICT_SETINT_STRKEY(init_kwargs, "minute", timeinfo->tm_min);
+    DICT_SETINT_STRKEY(init_kwargs, "second", timeinfo->tm_sec);
+
+    secondly_date = DateObject_New();
+    DateObject_init(secondly_date, init_args, init_kwargs);
+
+    Py_DECREF(init_args);
+    Py_DECREF(init_kwargs);
+
+    if (freq_val != FR_SEC) {
+        DateObject *result = DateObject_New();
+
+        long (*asfreq_func)(long, char, struct asfreq_info*) = NULL;
+        struct asfreq_info af_info;
+
+        int date_val;
+
+        get_asfreq_info(FR_SEC, freq_val, &af_info);
+        asfreq_func = get_asfreq_func(FR_SEC, freq_val, 0);
+
+        date_val = asfreq_func(secondly_date->value, 'A', &af_info);
+
+        Py_DECREF(secondly_date);
+
+        result->freq = freq_val;
+        result->value = date_val;
+
+        return (PyObject*)result;
+
+    } else { return (PyObject*)secondly_date; }
+}
+
+
+static char TimeSeries_convert_doc[] = "";
+static PyObject *
+TimeSeries_convert(PyObject *self, PyObject *args)
+{
     PyObject *arrayTest;
     PyArrayObject *array, *newArray;
     PyArrayObject *mask, *newMask;
@@ -1190,6 +2547,7 @@
     npy_intp *dim, *newIdx;
     long currPerLen;
     char *position;
+    PyObject *fromFreq_arg, *toFreq_arg;
     int fromFreq, toFreq;
     char relation;
     struct asfreq_info af_info;
@@ -1202,16 +2560,29 @@
 
     returnVal = PyDict_New();
 
-    if (!PyArg_ParseTuple(args, "OiislO:convert(array, fromfreq, tofreq, position, startIndex, mask)", &array, &fromFreq, &toFreq, &position, &startIndex, &mask)) return NULL;
+    if (!PyArg_ParseTuple(args,
+        "OOOslO:convert(array, fromfreq, tofreq, position, startIndex, mask)",
+        &array, &fromFreq_arg, &toFreq_arg,
+        &position, &startIndex, &mask)) return NULL;
 
+    if((fromFreq = check_freq(fromFreq_arg)) == INT_ERR_CODE) return NULL;
+    if((toFreq = check_freq(toFreq_arg)) == INT_ERR_CODE) return NULL;
+
     if (toFreq == fromFreq)
     {
-        PyDict_SetItemString(returnVal, "values", (PyObject*)array);
-        PyDict_SetItemString(returnVal, "mask", (PyObject*)mask);
+        PyObject *sidx;
+        newArray = (PyArrayObject *)PyArray_Copy(array);
+        newMask = (PyArrayObject *)PyArray_Copy(mask);
+        sidx = PyInt_FromLong(startIndex);
 
-        Py_DECREF(array);
-        Py_DECREF(mask);
+        PyDict_SetItemString(returnVal, "values", (PyObject*)newArray);
+        PyDict_SetItemString(returnVal, "mask", (PyObject*)newMask);
+        PyDict_SetItemString(returnVal, "startindex", sidx);
 
+        Py_DECREF(newArray);
+        Py_DECREF(newMask);
+        Py_DECREF(sidx);
+
         return returnVal;
     }
 
@@ -1338,9 +2709,9 @@
     return returnVal;
 }
 
-static char cseries_asfreq_doc[] = "";
+static char DateArray_asfreq_doc[] = "";
 static PyObject *
-cseries_asfreq(PyObject *self, PyObject *args)
+DateArray_asfreq(PyObject *self, PyObject *args)
 {
     PyArrayObject *fromDates, *toDates;
     PyArrayIterObject *iterFrom, *iterTo;
@@ -1351,7 +2722,9 @@
     long (*asfreq_main)(long, char, struct asfreq_info*) = NULL;
     struct asfreq_info af_info;
 
-    if (!PyArg_ParseTuple(args, "Oiis:asfreq(fromDates, fromfreq, tofreq, relation)", &fromDates, &fromFreq, &toFreq, &relation)) return NULL;
+    if (!PyArg_ParseTuple(args,
+                "Oiis:asfreq(fromDates, fromfreq, tofreq, relation)",
+                &fromDates, &fromFreq, &toFreq, &relation)) return NULL;
 
     get_asfreq_info(fromFreq, toFreq, &af_info);
 
@@ -1388,45 +2761,9 @@
 
 }
 
-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); }
-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;
-
-    switch(freq)
-    {
-        case FR_HR:
-            periodsPerDay = 24;
-            break;
-        case FR_MIN:
-            periodsPerDay = 24*60;
-            break;
-        case FR_SEC:
-            periodsPerDay = 24*60*60;
-            break;
-        default:
-            return 0;
-    }
-
-    startOfDay = asfreq_DtoHIGHFREQ(dailyDate, 'B', periodsPerDay);
-    return (24*60*60)*((double)(originalDate - startOfDay))/((double)periodsPerDay);
-}
-
-
-
-static char cseries_getDateInfo_doc[] = "";
+static char DateArray_getDateInfo_doc[] = "";
 static PyObject *
-cseries_getDateInfo(PyObject *self, PyObject *args)
+DateArray_getDateInfo(PyObject *self, PyObject *args)
 {
     int freq;
     char *info;
@@ -1513,162 +2850,50 @@
     return (PyObject *) newArray;
 }
 
-static char *str_replace(const char *s, const char *old, const char *new)
-{
-    char *ret;
-    int i, count = 0;
-    size_t newlen = strlen(new);
-    size_t oldlen = strlen(old);
+static PyMethodDef cseries_methods[] = {
 
-    for (i = 0; s[i] != '\0'; i++) {
-        if (strstr(&s[i], old) == &s[i]) {
-           count++;
-           i += oldlen - 1;
-        }
-    }
+    {"TS_convert", TimeSeries_convert, METH_VARARGS, TimeSeries_convert_doc},
 
-    ret = malloc(i + 1 + count * (newlen - oldlen));
-    if (ret == NULL) return NULL;
+    {"DA_asfreq", DateArray_asfreq, METH_VARARGS, DateArray_asfreq_doc},
+    {"DA_getDateInfo", DateArray_getDateInfo, METH_VARARGS, DateArray_getDateInfo_doc},
 
-    i = 0;
-    while (*s) {
-        if (strstr(s, old) == s) {
-            strcpy(&ret[i], new);
-            i += newlen;
-            s += oldlen;
-        } else {
-            ret[i++] = *s++;
-        }
-    }
-    ret[i] = '\0';
+    {"thisday", cseries_thisday, METH_VARARGS, cseries_thisday_doc},
+    {"check_freq", cseries_check_freq, METH_VARARGS, cseries_check_freq_doc},
+    {"check_freq_str", cseries_check_freq_str, METH_VARARGS, cseries_check_freq_str_doc},
 
-    return ret;
-}
+    {"set_callback_DateFromString", set_callback_DateFromString, METH_VARARGS,
+     set_callback_DateFromString_doc},
+    {"set_callback_DateTimeFromString", set_callback_DateTimeFromString, METH_VARARGS,
+     set_callback_DateTimeFromString_doc},
 
-static char cseries_strfmt_doc[] = "";
-static PyObject *
-cseries_strfmt(PyObject *self, PyObject *args)
-{
-
-    char *orig_fmt_str, *fmt_str, *q_loc;
-    char *result;
-    char place_holder[] = "^`";
-    struct tm c_date;
-    struct date_info tempDate;
-    int result_len;
-    PyObject *date, *py_result;
-
-    if (!PyArg_ParseTuple(args, "Os:strfmt(datetime, fmt_str)", &date, &orig_fmt_str)) return NULL;
-
-    if (dInfoCalc_SetFromDateAndTime(&tempDate,
-                                    PyDateTime_GET_YEAR(date),
-                                    PyDateTime_GET_MONTH(date),
-                                    PyDateTime_GET_DAY(date),
-                                    PyDateTime_DATE_GET_HOUR(date),
-                                    PyDateTime_DATE_GET_MINUTE(date),
-                                    PyDateTime_DATE_GET_SECOND(date),
-                                    GREGORIAN_CALENDAR)) return NULL;
-
-    /* We need to modify the fmt_str passed in to handle our special syntax for quarters.
-       We can't modify the string passed in directly, so we must make a copy. */
-    fmt_str = malloc((strlen(orig_fmt_str) + 1)*sizeof(char));
-    strcpy(fmt_str, orig_fmt_str);
-
-    if ((q_loc = strstr(fmt_str,"%q")) != NULL) {
-        q_loc = strstr(fmt_str,"%q");
-        strncpy (q_loc,place_holder,2);
-    }
-
-    c_date.tm_sec = (int)tempDate.second;
-    c_date.tm_min = tempDate.minute;
-    c_date.tm_hour = tempDate.hour;
-    c_date.tm_mday = tempDate.day;
-    c_date.tm_mon = tempDate.month - 1;
-    c_date.tm_year = tempDate.year - 1900;
-    c_date.tm_wday = tempDate.day_of_week;
-    c_date.tm_yday = tempDate.day_of_year;
-    c_date.tm_isdst = -1;
-
-    result_len = strlen(orig_fmt_str) + 50;
-
-    result = malloc(result_len * sizeof(char));
-
-    strftime(result, result_len, fmt_str, &c_date);
-
-    if (q_loc != NULL) {
-        char *alt_result;
-        char q_str[2];
-
-        sprintf(q_str, "%i", tempDate.quarter);
-        alt_result = str_replace(result, place_holder, q_str);
-        py_result = PyString_FromString(alt_result);
-        free(result);
-        free(alt_result);
-    } else {
-        py_result = PyString_FromString(result);
-        free(result);
-    }
-
-    return py_result;
-
-}
-
-
-///////////////////////////////////////////////////////////////////////
-
-//{"fpointer", cseries_fpointer, METH_VARARGS, cseries_fpointer_doc},
-
-static PyMethodDef cseries_methods[] = {
-    {"strfmt", cseries_strfmt, METH_VARARGS, cseries_strfmt_doc},
-    {"convert", cseries_convert, METH_VARARGS, cseries_convert_doc},
-    {"asfreq", cseries_asfreq, METH_VARARGS, cseries_asfreq_doc},
-    {"getDateInfo", cseries_getDateInfo, METH_VARARGS, cseries_getDateInfo_doc},
     {NULL, NULL}
 };
 
 PyMODINIT_FUNC
 initcseries(void)
 {
-    PyObject *m, *TSER_CONSTANTS;
+    PyObject *m;
+
+    if (PyType_Ready(&DateType) < 0) return;
+
     m = Py_InitModule3("cseries", cseries_methods, cseries_doc);
+    if (m == NULL)
+      return;
+
     import_array();
     PyDateTime_IMPORT;
 
-    TSER_CONSTANTS = PyDict_New();
+    Py_INCREF(&DateType);
+    PyModule_AddObject(m, "Date", (PyObject *)&DateType);
 
-    // Add all the frequency constants to a python dictionary
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANN", FR_ANN);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNJAN", FR_ANNJAN);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNFEB", FR_ANNFEB);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNMAR", FR_ANNMAR);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNAPR", FR_ANNAPR);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNMAY", FR_ANNMAY);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNJUN", FR_ANNJUN);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNJUL", FR_ANNJUL);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNAUG", FR_ANNAUG);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNSEP", FR_ANNSEP);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNOCT", FR_ANNOCT);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNNOV", FR_ANNNOV);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_ANNDEC", FR_ANNDEC);
+    if(build_freq_dict(m) == INT_ERR_CODE) {
+    	PyErr_SetString(					\
+    		PyExc_ImportError,				\
+    		"initialization of module timeseries.cseries failed");
+        return;
+    };
 
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_QTR", FR_QTR);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_MTH", FR_MTH);
-
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_WK", FR_WK);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_WKSUN", FR_WKSUN);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_WKSAT", FR_WKSAT);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_WKFRI", FR_WKFRI);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_WKTHU", FR_WKTHU);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_WKWED", FR_WKWED);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_WKTUE", FR_WKTUE);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_WKMON", FR_WKMON);
-
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_BUS", FR_BUS);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_DAY", FR_DAY);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_HR", FR_HR);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_MIN", FR_MIN);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_SEC", FR_SEC);
-    ADD_INT_TO_DICT(TSER_CONSTANTS, "FR_UND", FR_UND);
-
-    PyModule_AddObject(m, "TSER_CONSTANTS", TSER_CONSTANTS);
+    PyModule_AddObject(m, "freq_dict", freq_dict);
+    PyModule_AddObject(m, "freq_dict_rev", freq_dict_rev);
+    PyModule_AddObject(m, "freq_constants", freq_constants);
 }
\ No newline at end of file

Modified: trunk/Lib/sandbox/timeseries/tcore.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tcore.py	2007-03-20 14:42:18 UTC (rev 2851)
+++ trunk/Lib/sandbox/timeseries/tcore.py	2007-03-20 14:44:08 UTC (rev 2852)
@@ -13,19 +13,8 @@
 import numpy
 import numpy.core.numeric as numeric
 
-from scipy.interpolate import fitpack
-
 import maskedarray as MA
 
-from cseries import TSER_CONSTANTS
-
-"""add constants in cfame.FAME_CONSTANTS dictionary to global namespace
-for this module"""
-
-_g = globals()
-_g.update(TSER_CONSTANTS)
-
-
 #####---------------------------------------------------------------------------
 #---- --- Generic functions ---
 #####---------------------------------------------------------------------------
@@ -48,149 +37,6 @@
 
 
 #####---------------------------------------------------------------------------
-#---- --- Option conversion ---
-#####---------------------------------------------------------------------------
-fmtobs_dict = {'UNDEFINED': ['UNDEF','UNDEFINED',None],
-               'BEGINNING': ['BEGIN','BEGINNING'],
-               'ENDING': ['END','ENDING'],
-               'AVERAGED': ['AVERAGE','AVERAGE','MEAN'],
-               'SUMMED': ['SUM','SUMMED'],
-               'MAXIMUM': ['MAX','MAXIMUM','HIGH'],
-               'MINIMUM': ['MIN','MINIMUM','LOW']}
-
-obs_dict = {None:None,
-            "UNDEFINED":None,
-            "UNDEF":None,
-            "BEGIN": first_unmasked_val,
-            "BEGINNING": first_unmasked_val,
-            "END": last_unmasked_val,
-            "ENDING": last_unmasked_val,
-            "AVERAGED": MA.average,
-            "AVERAGE": MA.average,
-            "MEAN": MA.average,
-            "SUMMED": MA.sum,
-            "SUM": MA.sum,
-            "MAXIMUM": MA.maximum,
-            "MAX": MA.maximum,
-            "MINIMUM": MA.minimum,
-            "MIN": MA.minimum,
-            }
-obsDict = obs_dict
-fmtobs_revdict = reverse_dict(fmtobs_dict)
-
-#
-def fmtObserv(obStr):
-    "Converts a possible 'Observed' string into acceptable values."
-    if obStr is None:
-        return fmtobs_revdict[None]
-    elif obStr.upper() in fmtobs_revdict:
-        return fmtobs_revdict[obStr.upper()]
-    else:
-        raise ValueError("Invalid value for observed attribute: %s " % str(obStr))
-
-_weekly_prefixes = ['W','WEEK','WEEKLY']
-_week_end_map = {
-    FR_WKSUN:'SUNDAY',
-    FR_WKSAT:'SATURDAY',
-    FR_WKFRI:'FRIDAY',
-    FR_WKTHU:'THURSDAY',
-    FR_WKWED:'WEDNESDAY',
-    FR_WKTUE:'TUESDAY',
-    FR_WKMON:'MONDAY'}
-
-def _gen_weekly_strs(day):
-    result = []
-    for pr in _weekly_prefixes:
-        result += [pr+'-'+day_str for day_str in (day[:3], day)]
-    return result
-
-_annual_prefixes = ['A','Y','ANNUAL','ANNUALLY','YEAR','YEARLY']
-_year_end_map = {
-    FR_ANNJAN:'JANUARY',
-    FR_ANNFEB:'FEBRUARY',
-    FR_ANNMAR:'MARCH',
-    FR_ANNAPR:'APRIL',
-    FR_ANNMAY:'MAY',
-    FR_ANNJUN:'JUNE',
-    FR_ANNJUL:'JULY',
-    FR_ANNAUG:'AUGUST',
-    FR_ANNSEP:'SEPTEMBER',
-    FR_ANNOCT:'OCTOBER',
-    FR_ANNNOV:'NOVEMBER',
-    FR_ANNDEC:'DECEMBER'
-    }
-
-def _gen_annual_strs(month):
-    result = []
-    for pr in _annual_prefixes:
-        result += [pr+'-'+mth_str for mth_str in (month[:3], month)]
-    return result
-
-freq_dict = { FR_QTR: ['Q','QUARTER','QUARTERLY'],
-              FR_MTH: ['M','MONTH','MONTHLY'],
-              FR_BUS: ['B','BUSINESS','BUSINESSLY'],
-              FR_DAY: ['D','DAY','DAILY'],
-              FR_HR: ['H','HOUR','HOURLY'],
-              FR_MIN: ['T','MINUTE','MINUTELY'],
-              FR_SEC: ['S','SECOND','SECONDLY'],
-              FR_UND: ['U','UNDEF','UNDEFINED']
-                }
-                
-for _freq, day_str in _week_end_map.iteritems():
-    freq_dict[_freq] = _gen_weekly_strs(day_str)
-freq_dict[FR_WK] += _weekly_prefixes
-
-for _freq, mth_str in _year_end_map.iteritems():
-    freq_dict[_freq] = _gen_annual_strs(mth_str)
-freq_dict[FR_ANN] += _annual_prefixes
-
-freq_revdict = reverse_dict(freq_dict)
-
-def freq_fromstr(freq_asstr):
-    "Converts a frequency given as string to the corresponding integer."
-    freq_asstr = freq_asstr.upper()
-    if freq_asstr not in freq_revdict.keys():
-        raise ValueError, "Invalid frequency string %s" % freq_asstr
-    return freq_revdict[freq_asstr]
-    
-def freq_tostr(freq_asint):
-    "Converts a frequency given as integer to the corresponding symbol."
-    if freq_asint not in freq_dict.keys():
-        raise ValueError, "Invalid frequency representation %s" % freq_asint
-    return freq_dict[freq_asint][0]
-
-def check_freq(freq):
-    "Converts a possible 'frequency' string to acceptable values."
-    if freq is None:
-        return None
-    elif isinstance(freq, int):
-        if freq not in freq_dict.keys():
-            raise ValueError("Invalid frequency: %s " % str(freq))
-        return freq
-    elif freq.upper() in freq_revdict.keys():
-        return freq_revdict[freq.upper()]
-    else:
-        raise ValueError("Invalid frequency: %s " % str(freq))
-    
-def check_freqstr(freq):
-    if freq is None:
-        return None
-    elif isinstance(freq, int):
-        if freq not in freq_dict.keys():
-            raise ValueError("Invalid frequency: %s " % str(freq))
-        return freq_dict[freq][0]
-    elif freq.upper() in freq_revdict.keys():
-        return freq_dict[freq_revdict[freq.upper()]][0]
-    else:
-        raise ValueError("Invalid frequency: %s " % str(freq))    
-fmtFreq = check_freqstr
-
-def get_freq_group(freq):
-    # truncate frequency to nearest thousand
-    return (freq//1000)*1000
-        
-
-#####---------------------------------------------------------------------------
 #---- --- Misc functions ---
 #####---------------------------------------------------------------------------
 #http://aspn.activestate.com/ASPN/Mail/Message/python-tutor/2302348
@@ -203,11 +49,10 @@
                 yield f
         else:
             yield elm
-        
+
 def flatargs(*args):
     "Flattens the arguments."
     if not hasattr(args, '__iter__'):
         return args
     else:
         return flatten_sequence(args)
-        

Modified: trunk/Lib/sandbox/timeseries/tdates.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tdates.py	2007-03-20 14:42:18 UTC (rev 2851)
+++ trunk/Lib/sandbox/timeseries/tdates.py	2007-03-20 14:44:08 UTC (rev 2852)
@@ -27,38 +27,25 @@
 
 import maskedarray as MA
 
-try:
-    from mx.DateTime import DateTimeType
-except ImportError:
-    class DateTimeType: pass
+from parser import DateFromString, DateTimeFromString
 
-from parser import DateFromString, DateTimeFromString    
-
 import tcore as corelib
-import tcore as _c
+import const as _c
 import cseries
 
+from cseries import Date, thisday, check_freq, check_freq_str
+today = thisday
 
-
 __all__ = [
 'Date', 'DateArray','isDate','isDateArray',
 'DateError', 'ArithmeticDateError', 'FrequencyDateError','InsufficientDateError',
 'datearray','date_array', 'date_array_fromlist', 'date_array_fromrange',
-'day_of_week','day_of_year','day','month','quarter','year','hour','minute','second',
-'truncateDate','monthToQuarter','thisday','today','prevbusday','asfreq',
-'period_break'
+'day_of_week','day_of_year','day','month','quarter','year','hour','minute',
+'second','thisday','today','prevbusday','period_break', 'check_freq',
+'check_freq_str'
            ]
 
-#####---------------------------------------------------------------------------
-#---- --- Date Info ---
-#####---------------------------------------------------------------------------
 
-OriginDate = dt.datetime(1970, 1, 1)
-secondlyOriginDate = OriginDate - dt.timedelta(seconds=1)
-minutelyOriginDate = OriginDate - dt.timedelta(minutes=1)
-hourlyOriginDate = OriginDate - dt.timedelta(hours=1)
-
-
 #####---------------------------------------------------------------------------
 #---- --- Date Exceptions ---
 #####---------------------------------------------------------------------------
@@ -72,15 +59,15 @@
         "Calculate the string representation"
         return str(self.args)
     __repr__ = __str__
-    
+
 class InsufficientDateError(DateError):
-    """Defines the exception raised when there is not enough information 
+    """Defines the exception raised when there is not enough information
     to create a Date object."""
     def __init__(self, msg=None):
         if msg is None:
             msg = "Insufficient parameters given to create a date at the given frequency"
         DateError.__init__(self, msg)
-        
+
 class FrequencyDateError(DateError):
     """Defines the exception raised when the frequencies are incompatible."""
     def __init__(self, msg, freql=None, freqr=None):
@@ -88,470 +75,45 @@
         if not (freql is None or freqr is None):
             msg += " (%s<>%s)" % (freql, freqr)
         DateError.__init__(self, msg)
-        
+
 class ArithmeticDateError(DateError):
     """Defines the exception raised when dates are used in arithmetic expressions."""
     def __init__(self, msg=''):
         msg += " Cannot use dates for arithmetics!"
         DateError.__init__(self, msg)
 
-#####---------------------------------------------------------------------------
-#---- --- Date Class ---
-#####---------------------------------------------------------------------------
 
-class Date:
-    """Defines a Date object, as the combination of a date and a frequency.
-    Several options are available to construct a Date object explicitly:
-
-    - Give appropriate values to the `year`, `month`, `day`, `quarter`, `hours`, 
-      `minutes`, `seconds` arguments.
-      
-      >>> td.Date(freq='Q',year=2004,quarter=3)
-      >>> td.Date(freq='D',year=2001,month=1,day=1)
-      
-    - Use the `string` keyword. This method calls the `mx.DateTime.Parser`
-      submodule, more information is available in its documentation.
-      
-      >>> ts.Date('D', '2007-01-01')
-      
-    - Use the `datetime` keyword with an existing datetime.datetime object.
-
-      >>> td.Date('D', datetime=datetime.datetime.now())
-      """
-    default_fmtstr = {_c.FR_ANN: "%Y",
-                      _c.FR_QTR: "%YQ%q",
-                      _c.FR_MTH: "%b-%Y",
-                      _c.FR_WK: "%d-%b-%Y",
-                      _c.FR_BUS: "%d-%b-%Y",
-                      _c.FR_DAY: "%d-%b-%Y",
-                      _c.FR_UND: "%d-%b-%Y",
-                      _c.FR_HR: "%d-%b-%Y %H:00",
-                      _c.FR_MIN: "%d-%b-%Y %H:%M",
-                      _c.FR_SEC: "%d-%b-%Y %H:%M:%S"
-                      }
-    
-    for x in range(7): default_fmtstr[_c.FR_WK+x] = default_fmtstr[_c.FR_WK]
-    for x in range(12): default_fmtstr[_c.FR_ANN+x] = default_fmtstr[_c.FR_ANN]
-      
-    def __init__(self, freq, value=None, string=None,
-                 year=None, month=None, day=None, quarter=None, 
-                 hour=None, minute=None, second=None, 
-                 datetime=None):
-        
-        if hasattr(freq, 'freq'):
-            self.freq = corelib.check_freq(freq.freq)
-        else:
-            self.freq = corelib.check_freq(freq)
-        self.freqstr = corelib.freq_tostr(self.freq)
-        
-        _freqGroup = corelib.get_freq_group(self.freq)
-        
-        if isinstance(value, str):
-            if self.freq in (_c.FR_HR, _c.FR_MIN, _c.FR_SEC):
-                self.datetime = DateTimeFromString(value)
-            else:
-                self.datetime = DateFromString(value) 
-        elif value is not None:
-        
-            #value could be a numpy scalar, which is not acceptable
-            value = int(value)
-
-            if self.freq == _c.FR_SEC:
-                self.datetime = secondlyOriginDate + dt.timedelta(seconds=value)
-            elif self.freq == _c.FR_MIN:
-                self.datetime = minutelyOriginDate + dt.timedelta(minutes=value)
-            elif self.freq == _c.FR_HR:
-                self.datetime = hourlyOriginDate + dt.timedelta(hours=value)
-            elif self.freq == _c.FR_DAY:
-                self.datetime = dt.datetime.fromordinal(value)
-            elif self.freq == _c.FR_UND:
-                self.datetime = int(value)
-            elif self.freq == _c.FR_BUS:
-                valtmp = (value - 1)//5
-                self.datetime = dt.datetime.fromordinal(value + valtmp*2)
-            elif _freqGroup == _c.FR_WK:
-                """value=1 must correspond to first FULL week in the year 0001
-                ending on the given day of the week"""
-                self.datetime = dt.datetime(1,1,7) + \
-                                dt.timedelta(days=(value-1)*7 + (self.freq - _c.FR_WK))
-            elif self.freq == _c.FR_MTH:
-                year = (value - 1)//12 + 1
-                month = value - (year - 1)*12
-                self.datetime = dt.datetime(year, month, 1)
-            elif self.freq == _c.FR_QTR:
-                year = (value - 1)//4 + 1
-                month = (value - (year - 1)*4)*3
-                self.datetime = dt.datetime(year, month, 1)
-            elif _freqGroup == _c.FR_ANN:
-                if self.freq == _c.FR_ANNDEC:
-                    self.datetime = dt.datetime(value, 12, 1)
-                else:
-                    self.datetime = dt.datetime(value, self.freq - _c.FR_ANN, 1)
-            else:
-                raise ValueError("unrecognized frequency: "+str(self.freq))
-        
-        elif string is not None:
-            if self.freq in (_c.FR_HR, _c.FR_MIN, _c.FR_SEC):
-                self.datetime = DateTimeFromString(string)
-            else:
-                self.datetime = DateFromString(string)
-            
-        elif datetime is not None:
-            if isinstance(datetime, DateTimeType):
-                datetime = mx_to_datetime(datetime)
-            self.datetime = truncateDate(self.freq, datetime)
-            
-        else:
-            # First, some basic checks.....
-            if year is None:
-                raise InsufficientDateError            
-            if _freqGroup in (_c.FR_BUS, _c.FR_DAY, _c.FR_WK, _c.FR_UND):
-                if month is None or day is None: 
-                    raise InsufficientDateError
-            elif self.freq == _c.FR_MTH:
-                if month is None: 
-                    raise InsufficientDateError
-                day = 1
-            elif self.freq == _c.FR_QTR:
-                if quarter is None: 
-                    raise InsufficientDateError
-                month = quarter * 3
-                day = 1
-            elif _freqGroup == _c.FR_ANN:
-                month = self.freq - _freqGroup
-                if month == 0: month = 12
-                day = 1
-            elif self.freq == _c.FR_SEC:
-                if month is None or day is None or second is None: 
-                    raise InsufficientDateError
-                
-            if _freqGroup in (_c.FR_BUS, _c.FR_DAY, _c.FR_WK,
-                             _c.FR_MTH, _c.FR_QTR, _c.FR_ANN):
-                self.datetime = truncateDate(self.freq, dt.datetime(year, month, day))
-                if self.freq == _c.FR_BUS:
-                    if self.datetime.isoweekday() in [6,7]:
-                        raise ValueError("Weekend passed as business day")
-            elif self.freq in (_c.FR_HR, _c.FR_MIN, _c.FR_SEC):
-                if hour is None:
-                    if minute is None:
-                        if second is None:
-                            hour = 0
-                        else:
-                            hour = second//3600
-                    else:
-                        hour = minute // 60
-                if minute is None:
-                    if second is None:
-                        minute = 0
-                    else:
-                        minute = (second-hour*3600)//60
-                if second is None:
-                    second = 0
-                else:
-                    second = second % 60
-                self.datetime = truncateDate(self.freq,
-                                             dt.datetime(year, month, day, 
-                                                         hour, minute, second))
-            else:
-                raise ValueError("unrecognized frequency: "+str(self.freq))
-
-        self.value = self.__value()
-
-    def __getitem__(self, indx):
-        return self
-
-    @property
-    def day(self):          
-        "Returns the day of month."
-        return self.__getdateinfo__('D')
-    @property
-    def day_of_week(self):  
-        "Returns the day of week."
-        return self.__getdateinfo__('W')
-    @property
-    def day_of_year(self):  
-        "Returns the day of year."
-        return self.__getdateinfo__('R')
-    @property
-    def month(self):        
-        "Returns the month."
-        return self.__getdateinfo__('M')
-    @property
-    def quarter(self):   
-        "Returns the quarter."   
-        return self.__getdateinfo__('Q')
-    @property
-    def year(self):         
-        "Returns the year."
-        return self.__getdateinfo__('Y')
-    @property
-    def second(self):    
-        "Returns the seconds."  
-        return self.__getdateinfo__('S')
-    @property
-    def minute(self):     
-        "Returns the minutes."  
-        return self.__getdateinfo__('T')
-    @property
-    def hour(self):         
-        "Returns the hour."
-        return self.__getdateinfo__('H')
-    @property
-    def week(self):
-        "Returns the week."
-        return self.__getdateinfo__('I')
-        
-    def __getdateinfo__(self, info):
-        return int(cseries.getDateInfo(numpy.asarray(self.value), 
-                                       self.freq, info))
-    __getDateInfo = __getdateinfo__
- 
-    def __add__(self, other):
-        if isinstance(other, Date):
-            raise FrequencyDateError("Cannot add dates", 
-                                     self.freqstr, other.freqstr)
-        return Date(freq=self.freq, value=int(self) + other)
-    
-    def __radd__(self, other): 
-        return self+other
-    
-    def __sub__(self, other):
-        if isinstance(other, Date):
-            if self.freq != other.freq:
-                raise FrequencyDateError("Cannot subtract dates", \
-                                         self.freqstr, other.freqstr)
-            else:
-                return int(self) - int(other) 
-        else:
-            return self + (-1) * int(other)
-    
-    def __eq__(self, other):
-        if not hasattr(other, 'freq'):
-            return False
-        elif self.freq != other.freq:
-            raise FrequencyDateError("Cannot compare dates", \
-                                     self.freqstr, other.freqstr)
-        return int(self) == int(other) 
-    
-    def __cmp__(self, other): 
-        if not hasattr(other, 'freq'):
-            return False
-        elif self.freq != other.freq:
-            raise FrequencyDateError("Cannot compare dates", \
-                                     self.freqstr, other.freqstr)
-        return int(self)-int(other)    
-        
-    def __hash__(self): 
-        return hash(int(self)) ^ hash(self.freq)
-    
-    def __int__(self):
-        return self.value
-    
-    def __float__(self):
-        return float(self.value)
-    
-    def __value(self):   
-        "Converts the date to an integer, depending on the current frequency."
-        _freqGroup = corelib.get_freq_group(self.freq)
-        # Secondly......
-        if self.freq == _c.FR_SEC:
-            delta = (self.datetime - secondlyOriginDate)
-            val = delta.days*86400 + delta.seconds
-        # Minutely......
-        elif self.freq == _c.FR_MIN:
-            delta = (self.datetime - minutelyOriginDate)
-            val = delta.days*1440 + delta.seconds/(60)
-        # Hourly........
-        elif self.freq == _c.FR_HR:
-            delta = (self.datetime - hourlyOriginDate)
-            val = delta.days*24 + delta.seconds/(3600)
-        # Daily
-        elif self.freq == _c.FR_DAY:
-            val = self.datetime.toordinal()
-        # undefined
-        elif self.freq == _c.FR_UND:
-            if not hasattr(self.datetime, 'toordinal'):
-                val = self.datetime
-            else:
-                val = self.datetime.toordinal()
-        # Business days.
-        elif self.freq == _c.FR_BUS:
-            days = self.datetime.toordinal()
-            weeks = days // 7
-            val = days - weeks*2  
-        # Weekly........
-        elif _freqGroup == _c.FR_WK:
-            val = self.datetime.toordinal()//7
-        # Monthly.......
-        elif self.freq == _c.FR_MTH:
-            val = (self.datetime.year-1)*12 + self.datetime.month
-        # Quarterly.....
-        elif self.freq == _c.FR_QTR:
-            val = (self.datetime.year-1)*4 + self.datetime.month//3
-        # Annual .......
-        elif _freqGroup == _c.FR_ANN:
-            val = self.datetime.year
-
-        return int(val)
-    #......................................................        
-    def strfmt(self, fmt):
-        "Formats the date"
-        if fmt is None:
-            fmt = self.default_fmtstr[self.freq]
-        if self.freq == _c.FR_UND:
-            return str(self.value)
-        return cseries.strfmt(self.datetime, fmt)
-            
-    def __str__(self):
-        return self.strfmt(self.default_fmtstr[self.freq])
-
-    def __repr__(self): 
-        return "<%s : %s>" % (str(self.freqstr), str(self))
-    #......................................................
-    def toordinal(self):
-        "Returns the date as an ordinal."
-        # FIXME: We shouldn't need the test if we were in C
-        if self.freq == _c.FR_UND:
-            return self.value
-        return self.datetime.toordinal()
-
-    def fromordinal(self, ordinal):
-        "Returns the date as an ordinal."
-        return Date(self.freq, datetime=dt.datetime.fromordinal(ordinal))
-    
-    def tostring(self):
-        "Returns the date as a string."
-        return str(self)
-    
-    def toobject(self):
-        "Returns the date as itself."
-        return self
-    
-    def isvalid(self):
-        "Returns whether the DateArray is valid: no missing/duplicated dates."
-        # A date is always valid by itself, but we need the object to support the function
-        # when we're working with singletons.
-        return True
-    #......................................................
-        
-    
 #####---------------------------------------------------------------------------
 #---- --- Functions ---
 #####---------------------------------------------------------------------------
 
-def mx_to_datetime(mxDate):
-    microsecond = 1000000*(mxDate.second % 1)
-    return dt.datetime(mxDate.year, mxDate.month,
-                       mxDate.day, mxDate.hour,
-                       mxDate.minute,
-                       int(mxDate.second), microsecond)
-
-
-def truncateDate(freq, datetime):
-    "Chops off the irrelevant information from the datetime object passed in."
-    freq = corelib.check_freq(freq)
-    _freqGroup = corelib.get_freq_group(freq)
-    if freq == _c.FR_MIN:
-        return dt.datetime(datetime.year, datetime.month, datetime.day, \
-                           datetime.hour, datetime.minute)
-    elif freq == _c.FR_HR:
-        return dt.datetime(datetime.year, datetime.month, datetime.day, \
-                           datetime.hour)
-    elif freq in (_c.FR_BUS, _c.FR_DAY):
-        if freq == _c.FR_BUS and datetime.isoweekday() in (6,7):
-            raise ValueError("Weekend passed as business day")
-        return dt.datetime(datetime.year, datetime.month, datetime.day)
-    elif _freqGroup == _c.FR_WK:
-        d = datetime.toordinal()
-        day_adj = (7 - (freq - _c.FR_WK)) % 7
-        return dt.datetime.fromordinal(d + ((7 - day_adj) - d % 7) % 7)
-    elif freq == _c.FR_MTH:
-        return dt.datetime(datetime.year, datetime.month, 1)
-    elif freq == _c.FR_QTR:
-        return dt.datetime(datetime.year, monthToQuarter(datetime.month)*3, 1)
-    elif _freqGroup == _c.FR_ANN:
-        
-        if freq == _c.FR_ANNDEC: fr_month = 12
-        else: fr_month = freq - _c.FR_ANN
-        
-        if datetime.month <= fr_month:
-            return dt.datetime(datetime.year, fr_month, 1)
-        else:
-            return dt.datetime(datetime.year+1, fr_month, 1)
-
-    else:
-        return datetime
-    
-def monthToQuarter(monthNum):
-    """Returns the quarter corresponding to the month `monthnum`.
-    For example, December is the 4th quarter, Januray the first."""
-    return int((monthNum-1)/3)+1
-
-def thisday(freq):
-    "Returns today's date, at the given frequency `freq`."
-    freq = corelib.check_freq(freq)
-    _freqGroup = corelib.get_freq_group(freq)
-    tempDate = dt.datetime.now()
-    # if it is Saturday or Sunday currently, freq==B, then we want to use Friday
-    if freq == _c.FR_BUS and tempDate.isoweekday() >= 6:
-        tempDate = tempDate - dt.timedelta(days=(tempDate.isoweekday() - 5))
-    return Date(freq=freq, datetime=tempDate)
-today = thisday
-
 def prevbusday(day_end_hour=18, day_end_min=0):
     "Returns the previous business day."
     tempDate = dt.datetime.now()
     dateNum = tempDate.hour + float(tempDate.minute)/60
     checkNum = day_end_hour + float(day_end_min)/60
-    if dateNum < checkNum: 
+    if dateNum < checkNum:
         return thisday(_c.FR_BUS) - 1
-    else: 
+    else:
         return thisday(_c.FR_BUS)
-                
-def asfreq(date, toFreq, relation="BEFORE"):
-    """Returns a date converted to another frequency `toFreq`, according to the
-    relation `relation` ."""
-    tofreq = corelib.check_freq(toFreq)
-    _rel = relation.upper()[0]
-    if _rel not in ['B', 'A']:
-        msg = "Invalid relation '%s': Should be in ['before', 'after']"
-        raise ValueError, msg % relation
 
-    if not isinstance(date, Date):
-        raise DateError, "Date should be a valid Date instance!"
 
-    if date.freq == _c.FR_UND:
-        warnings.warn("Undefined frequency: assuming daily!")
-        fromfreq = _c.FR_DAY
-    else:
-        fromfreq = date.freq
-    
-    if fromfreq == tofreq:
-        return date
-    else:
-        value = cseries.asfreq(numeric.asarray(date.value), fromfreq, tofreq, _rel)
-        if value > 0:
-            return Date(freq=tofreq, value=value)
-        else:
-            return None
-Date.asfreq = asfreq
-            
 def isDate(data):
     "Returns whether `data` is an instance of Date."
     return isinstance(data, Date) or \
            (hasattr(data,'freq') and hasattr(data,'value'))
 
-            
+
 #####---------------------------------------------------------------------------
 #---- --- DateArray ---
-#####--------------------------------------------------------------------------- 
+#####---------------------------------------------------------------------------
 ufunc_dateOK = ['add','subtract',
                 'equal','not_equal','less','less_equal', 'greater','greater_equal',
                 'isnan']
 
 class _datearithmetics(object):
     """Defines a wrapper for arithmetic methods.
-Instead of directly calling a ufunc, the corresponding method of  the `array._data` 
+Instead of directly calling a ufunc, the corresponding method of  the `array._data`
 object is called instead.
 If `asdates` is True, a DateArray object is returned , else a regular ndarray
 is returned.
@@ -590,14 +152,14 @@
             if other.dtype.kind not in ['i','f']:
                 raise ArithmeticDateError
         if self._asdates:
-            return instance.__class__(method(other, *args), 
+            return instance.__class__(method(other, *args),
                                       freq=freq)
         else:
             return method(other, *args)
 
-class DateArray(ndarray):  
+class DateArray(ndarray):
     """Defines a ndarray of dates, as ordinals.
-    
+
 When viewed globally (array-wise), DateArray is an array of integers.
 When viewed element-wise, DateArray is a sequence of dates.
 For example, a test such as :
@@ -605,17 +167,17 @@
 will be valid only if value is an integer, not a Date
 However, a loop such as :
 >>> for d in DateArray(...):
-accesses the array element by element. Therefore, `d` is a Date object.    
+accesses the array element by element. Therefore, `d` is a Date object.
     """
-    _defcachedinfo = dict(toobj=None, tostr=None, toord=None, 
+    _defcachedinfo = dict(toobj=None, tostr=None, toord=None,
                           steps=None, full=None, hasdups=None)
     def __new__(cls, dates=None, freq=None, copy=False):
         # Get the frequency ......
         if freq is None:
             _freq = getattr(dates, 'freq', _c.FR_UND)
         else:
-            _freq = corelib.check_freq(freq)
-        cls._defaultfreq = corelib.check_freq(_freq)
+            _freq = check_freq(freq)
+        cls._defaultfreq = check_freq(_freq)
         # Get the dates ..........
         _dates = numeric.array(dates, copy=copy, dtype=int_, subok=1)
         if _dates.ndim == 0:
@@ -623,29 +185,29 @@
         _dates = _dates.view(cls)
         _dates.freq = _freq
         return _dates
-    
+
     def __array_wrap__(self, obj, context=None):
         if context is None:
             return self
         elif context[0].__name__ not in ufunc_dateOK:
             raise ArithmeticDateError, "(function %s)" % context[0].__name__
-    
+
     def __array_finalize__(self, obj):
         self.freq = getattr(obj, 'freq', _c.FR_UND)
-        self._cachedinfo = dict(toobj=None, tostr=None, toord=None, 
+        self._cachedinfo = dict(toobj=None, tostr=None, toord=None,
                                 steps=None, full=None, hasdups=None)
         if hasattr(obj,'_cachedinfo'):
             self._cachedinfo.update(obj._cachedinfo)
         return
-    
+
     def __getitem__(self, indx):
         if isinstance(indx, Date):
             indx = self.find_dates(indx)
         elif numeric.asarray(indx).dtype.kind == 'O':
             try:
-                indx = self.find_dates(indx)       
+                indx = self.find_dates(indx)
             except AttributeError:
-                pass     
+                pass
         r = ndarray.__getitem__(self, indx)
         if isinstance(r, (generic, int)):
             return Date(self.freq, value=r)
@@ -662,7 +224,7 @@
                     if r._cachedinfo[attr] is not None:
                         r._cachedinfo[attr] = r._cachedinfo[attr][indx]
             return r
-        
+
     def __repr__(self):
         return ndarray.__repr__(self)[:-1] + \
                ",\n          freq='%s')" % self.freqstr
@@ -681,41 +243,41 @@
     @property
     def freqstr(self):
         "Returns the frequency string code."
-        return corelib.freq_tostr(self.freq)
+        return check_freq_str(self.freq)
     @property
-    def day(self):          
+    def day(self):
         "Returns the day of month."
         return self.__getdateinfo__('D')
     @property
-    def day_of_week(self):  
+    def day_of_week(self):
         "Returns the day of week."
         return self.__getdateinfo__('W')
     @property
-    def day_of_year(self):  
+    def day_of_year(self):
         "Returns the day of year."
         return self.__getdateinfo__('R')
     @property
-    def month(self):        
+    def month(self):
         "Returns the month."
         return self.__getdateinfo__('M')
     @property
-    def quarter(self):   
-        "Returns the quarter."   
+    def quarter(self):
+        "Returns the quarter."
         return self.__getdateinfo__('Q')
     @property
-    def year(self):         
+    def year(self):
         "Returns the year."
         return self.__getdateinfo__('Y')
     @property
-    def second(self):    
-        "Returns the seconds."  
+    def second(self):
+        "Returns the seconds."
         return self.__getdateinfo__('S')
     @property
-    def minute(self):     
-        "Returns the minutes."  
+    def minute(self):
+        "Returns the minutes."
         return self.__getdateinfo__('T')
     @property
-    def hour(self):         
+    def hour(self):
         "Returns the hour."
         return self.__getdateinfo__('H')
     @property
@@ -733,12 +295,12 @@
     minutes = minute
     hours = hour
     weeks = week
-    
+
     def __getdateinfo__(self, info):
-        return numeric.asarray(cseries.getDateInfo(numeric.asarray(self), 
-                                                   self.freq, info), 
+        return numeric.asarray(cseries.DA_getDateInfo(numeric.asarray(self),
+                                                      self.freq, info),
                                dtype=int_)
-    __getDateInfo = __getdateinfo__    
+    __getDateInfo = __getdateinfo__
     #.... Conversion methods ....................
     #
     def tovalue(self):
@@ -771,20 +333,20 @@
                 tostr = firststr
             self._cachedinfo['tostr'] = tostr
         return self._cachedinfo['tostr']
-    #   
+    #
     def asfreq(self, freq=None, relation="BEFORE"):
         "Converts the dates to another frequency."
         # Note: As we define a new object, we don't need caching
         if freq is None or freq == _c.FR_UND:
             return self
-        tofreq = corelib.check_freq(freq)
+        tofreq = check_freq(freq)
         if tofreq == self.freq:
-            return self    
-        _rel = relation.upper()[0]    
+            return self
+        _rel = relation.upper()[0]
         fromfreq = self.freq
         if fromfreq == _c.FR_UND:
              fromfreq = _c.FR_DAY
-        new = cseries.asfreq(numeric.asarray(self), fromfreq, tofreq, _rel)
+        new = cseries.DA_asfreq(numeric.asarray(self), fromfreq, tofreq, _rel)
         return DateArray(new, freq=freq)
 
     #......................................................
@@ -799,7 +361,7 @@
         c = c.nonzero()
         if fromnumeric.size(c) == 0:
             raise IndexError, "Date out of bounds!"
-        return c  
+        return c
 
     def date_to_index(self, date):
         "Returns the index corresponding to one given date, as an integer."
@@ -811,9 +373,9 @@
         else:
             index_asarray = (self == date.value).nonzero()
             if fromnumeric.size(index_asarray) == 0:
-                raise IndexError, "Date out of bounds!" 
+                raise IndexError, "Date out of bounds!"
             return index_asarray[0][0]
-    #......................................................        
+    #......................................................
     def get_steps(self):
         """Returns the time steps between consecutive dates.
     The timesteps have the same unit as the frequency of the series."""
@@ -834,25 +396,25 @@
                 steps = numeric.array([], dtype=int_)
             self._cachedinfo['steps'] = steps
         return self._cachedinfo['steps']
-    
+
     def has_missing_dates(self):
         "Returns whether the DateArray have missing dates."
         if self._cachedinfo['full'] is None:
             steps = self.get_steps()
         return not(self._cachedinfo['full'])
-    
+
     def isfull(self):
         "Returns whether the DateArray has no missing dates."
         if self._cachedinfo['full'] is None:
             steps = self.get_steps()
         return self._cachedinfo['full']
-    
+
     def has_duplicated_dates(self):
         "Returns whether the DateArray has duplicated dates."
         if self._cachedinfo['hasdups'] is None:
             steps = self.get_steps()
         return self._cachedinfo['hasdups']
-    
+
     def isvalid(self):
         "Returns whether the DateArray is valid: no missing/duplicated dates."
         return  (self.isfull() and not self.has_duplicated_dates())
@@ -863,7 +425,7 @@
 
 #####---------------------------------------------------------------------------
 #---- --- DateArray functions ---
-#####---------------------------------------------------------------------------  
+#####---------------------------------------------------------------------------
 def isDateArray(a):
     "Tests whether an array is a DateArray object."
     return isinstance(a,DateArray)
@@ -915,14 +477,16 @@
                                float_)
         ords += 1
         #...try to guess the frequency
-        if freq is None:
+        if freq is None or freq == _c.FR_UND:
             freq = guess_freq(ords)
         #...construct a list of dates
+        for s in dlist:
+            x = Date(freq, string=s)
         dates = [Date(freq, string=s) for s in dlist]
     # Case #2: dates as numbers .................
     elif dlist.dtype.kind in 'if':
         #...hopefully, they are values
-        if freq is None:
+        if freq is None or freq == _c.FR_UND:
             freq = guess_freq(dlist)
         dates = dlist
     # Case #3: dates as objects .................
@@ -934,7 +498,7 @@
         #...as mx.DateTime objects
         elif hasattr(template,'absdays'):
             # no freq given: try to guess it from absdays
-            if freq is None:
+            if freq == _c.FR_UND:
                 ords = numpy.fromiter((s.absdays for s in dlist), float_)
                 ords += 1
                 freq = guess_freq(ords)
@@ -942,7 +506,7 @@
         #...as datetime objects
         elif hasattr(template, 'toordinal'):
             ords = numpy.fromiter((d.toordinal() for d in dlist), float_)
-            if freq is None:
+            if freq == _c.FR_UND:
                 freq = guess_freq(ords)
             dates = [Date(freq, datetime=dt.datetime.fromordinal(a)) for a in ords]
     #
@@ -950,18 +514,18 @@
     return result
 
 
-def date_array(dlist=None, start_date=None, end_date=None, length=None, 
+def date_array(dlist=None, start_date=None, end_date=None, length=None,
                include_last=True, freq=None):
     """Constructs a DateArray from:
     - a starting date and either an ending date or a given length.
     - a list of dates.
     """
-    freq = corelib.check_freq(freq)
+    freq = check_freq(freq)
     # Case #1: we have a list ...................
     if dlist is not None:
         # Already a DateArray....................
         if isinstance(dlist, DateArray):
-            if (freq is not None) and (dlist.freq != corelib.check_freq(freq)):
+            if (freq != _c.FR_UND) and (dlist.freq != check_freq(freq)):
                 return dlist.asfreq(freq)
             else:
                 return dlist
@@ -999,7 +563,7 @@
 #    dlist = [(start_date+i).value for i in range(length)]
     dlist = numeric.arange(length, dtype=int_)
     dlist += start_date.value
-    if freq is None:
+    if freq == _c.FR_UND:
         freq = start_date.freq
     return DateArray(dlist, freq=freq)
 datearray = date_array
@@ -1008,12 +572,12 @@
     "Constructs a DateArray from a list of dates."
     return date_array(dlist=dlist, freq=freq)
 
-def date_array_fromrange(start_date, end_date=None, length=None, 
+def date_array_fromrange(start_date, end_date=None, length=None,
                          include_last=True, freq=None):
-    """Constructs a DateArray from a starting date and either an ending date or 
+    """Constructs a DateArray from a starting date and either an ending date or
     a length."""
-    return date_array(start_date=start_date, end_date=end_date, 
-                      length=length, include_last=include_last, freq=freq)    
+    return date_array(start_date=start_date, end_date=end_date,
+                      length=length, include_last=include_last, freq=freq)
 
 #####---------------------------------------------------------------------------
 #---- --- Definition of functions from the corresponding methods ---
@@ -1089,7 +653,7 @@
         hodie = today('D')
         D = DateArray(today('D'))
         assert_equal(D.freq, 6000)
-    
+
     if 0:
         freqs = [x[0] for x in corelib.freq_dict.values() if x[0] != 'U']
         print freqs
@@ -1097,17 +661,17 @@
             print f
             today = thisday(f)
             assert(Date(freq=f, value=today.value) == today)
-    
+
     if 1:
         D = date_array(freq='U', start_date=Date('U',1), length=10)
-    
+
     if 1:
         dlist = ['2007-01-%02i' % i for i in (1,2,4,5,7,8,10,11,13)]
-        
-        
+
+
         ords = numpy.fromiter((DateTimeFromString(s).toordinal() for s in dlist),
                                float_)
-        
+
     if 1:
         "Tests the automatic sorting of dates."
         D = date_array_fromlist(dlist=['2006-01','2005-01','2004-01'],freq='M')

Modified: trunk/Lib/sandbox/timeseries/tests/test_dates.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tests/test_dates.py	2007-03-20 14:42:18 UTC (rev 2851)
+++ trunk/Lib/sandbox/timeseries/tests/test_dates.py	2007-03-20 14:44:08 UTC (rev 2852)
@@ -1,5 +1,5 @@
 # pylint: disable-msg=W0611, W0612, W0511,R0201
-"""Tests suite for timeseries.tdates.
+"""Tests suite for Date handling.
 
 :author: Pierre Gerard-Marchant & Matt Knox
 :contact: pierregm_at_uga_dot_edu - mattknow_ca_at_hotmail_dot_com
@@ -25,20 +25,20 @@
 import maskedarray.testutils
 from maskedarray.testutils import assert_equal, assert_array_equal
 
-import timeseries.tdates as tdates
-from timeseries.tdates import *
-from timeseries.parser import DateFromString
-from timeseries import tcore
+import timeseries as ts
+from timeseries import *
+from timeseries.cseries import freq_dict
 
 
 class test_creation(NumpyTestCase):
     "Base test class for MaskedArrays."
-    
+
     def __init__(self, *args, **kwds):
         NumpyTestCase.__init__(self, *args, **kwds)
-    
+
     def test_fromstrings(self):
         "Tests creation from list of strings"
+        print "starting test_fromstrings..."
         dlist = ['2007-01-%02i' % i for i in range(1,15)]
         # A simple case: daily data
         dates = date_array_fromlist(dlist, 'D')
@@ -72,9 +72,11 @@
         assert(dates.isfull())
         assert(not dates.has_duplicated_dates())
         assert_equal(dates, 24073 + numpy.arange(12))
-        
+        print "finished test_fromstrings"
+
     def test_fromstrings_wmissing(self):
         "Tests creation from list of strings w/ missing dates"
+        print "starting test_fromstrings_wmissing..."
         dlist = ['2007-01-%02i' % i for i in (1,2,4,5,7,8,10,11,13)]
         dates = date_array_fromlist(dlist)
         assert_equal(dates.freqstr,'U')
@@ -91,10 +93,12 @@
         assert_equal(mdates.freqstr,'M')
         assert(not dates.isfull())
         assert(mdates.has_duplicated_dates())
+        print "finished test_fromstrings_wmissing"
         #
-    
+
     def test_fromsobjects(self):
         "Tests creation from list of objects."
+        print "starting test_fromsobjects..."
         dlist = ['2007-01-%02i' % i for i in (1,2,4,5,7,8,10,11,13)]
         dates = date_array_fromlist(dlist)
         dobj = [datetime.datetime.fromordinal(d) for d in dates.toordinal()]
@@ -103,17 +107,21 @@
         dobj = [DateFromString(d) for d in dlist]
         odates = date_array_fromlist(dobj)
         assert_equal(dates,odates)
+        print "finished test_fromsobjects"
 
     def test_consistent_value(self):
         "Tests that values don't get mutated when constructing dates from a value"
-        freqs = [x[0] for x in tcore.freq_dict.values() if x[0] != 'U']
+        print "starting test_consistent_value..."
+        freqs = [x[0] for x in freq_dict.values() if x[0] != 'U']
         print freqs
         for f in freqs:
-            today = tdates.thisday(f)
-            assert_equal(tdates.Date(freq=f, value=today.value), today)
-            
+            today = thisday(f)
+            assert_equal(Date(freq=f, value=today.value), today)
+        print "finished test_consistent_value"
+
     def test_shortcuts(self):
         "Tests some creation shortcuts. Because I'm lazy like that."
+        print "starting test_shortcuts..."
         # Dates shortcuts
         assert_equal(Date('D','2007-01'), Date('D',string='2007-01'))
         assert_equal(Date('D','2007-01'), Date('D', value=732677))
@@ -123,26 +131,27 @@
         d = date_array(start_date=n, length=3)
         assert_equal(date_array(n,length=3), d)
         assert_equal(date_array(n, n+2), d)
+        print "finished test_shortcuts"
 
 class test_date_properties(NumpyTestCase):
     "Test properties such as year, month, day_of_week, etc...."
-    
+
     def __init__(self, *args, **kwds):
         NumpyTestCase.__init__(self, *args, **kwds)
 
     def test_properties(self):
-    
-        a_date = tdates.Date(freq='A', year=2007)
-        q_date = tdates.Date(freq='Q', year=2007, quarter=1)
-        m_date = tdates.Date(freq='M', year=2007, month=1)
-        w_date = tdates.Date(freq='W', year=2007, month=1, day=7)
-        b_date = tdates.Date(freq='B', year=2007, month=1, day=1)
-        d_date = tdates.Date(freq='D', year=2007, month=1, day=1)
-        h_date = tdates.Date(freq='H', year=2007, month=1, day=1,
+
+        a_date = Date(freq='A', year=2007)
+        q_date = Date(freq='Q', year=2007, quarter=1)
+        m_date = Date(freq='M', year=2007, month=1)
+        w_date = Date(freq='W', year=2007, month=1, day=7)
+        b_date = Date(freq='B', year=2007, month=1, day=1)
+        d_date = Date(freq='D', year=2007, month=1, day=1)
+        h_date = Date(freq='H', year=2007, month=1, day=1,
                                        hour=0)
-        t_date = tdates.Date(freq='T', year=2007, month=1, day=1,
+        t_date = Date(freq='T', year=2007, month=1, day=1,
                                        hour=0, minute=0)
-        s_date = tdates.Date(freq='T', year=2007, month=1, day=1,
+        s_date = Date(freq='T', year=2007, month=1, day=1,
                                        hour=0, minute=0, second=0)
 
         assert_equal(a_date.year, 2007)
@@ -219,12 +228,12 @@
 
 class test_freq_conversion(NumpyTestCase):
     "Test frequency conversion of date objects"
-    
+
     def __init__(self, *args, **kwds):
         NumpyTestCase.__init__(self, *args, **kwds)
         self.dateWrap = [(dArrayWrap, assert_array_equal),
                          (noWrap, assert_equal)]
-        
+
     def test_conv_annual(self):
         "frequency conversion tests: from Annual Frequency"
 
@@ -240,17 +249,17 @@
             date_A_to_B_after = dWrap(Date(freq='B', year=2007, month=12, day=31))
             date_A_to_D_before = dWrap(Date(freq='D', year=2007, month=1, day=1))
             date_A_to_D_after = dWrap(Date(freq='D', year=2007, month=12, day=31))
-            date_A_to_H_before = dWrap(Date(freq='H', year=2007, month=1, day=1, 
+            date_A_to_H_before = dWrap(Date(freq='H', year=2007, month=1, day=1,
                                       hour=0))
-            date_A_to_H_after = dWrap(Date(freq='H', year=2007, month=12, day=31, 
+            date_A_to_H_after = dWrap(Date(freq='H', year=2007, month=12, day=31,
                                      hour=23))
-            date_A_to_T_before = dWrap(Date(freq='T', year=2007, month=1, day=1, 
+            date_A_to_T_before = dWrap(Date(freq='T', year=2007, month=1, day=1,
                                       hour=0, minute=0))
-            date_A_to_T_after = dWrap(Date(freq='T', year=2007, month=12, day=31, 
+            date_A_to_T_after = dWrap(Date(freq='T', year=2007, month=12, day=31,
                                      hour=23, minute=59))
-            date_A_to_S_before = dWrap(Date(freq='S', year=2007, month=1, day=1, 
+            date_A_to_S_before = dWrap(Date(freq='S', year=2007, month=1, day=1,
                                       hour=0, minute=0, second=0))
-            date_A_to_S_after = dWrap(Date(freq='S', year=2007, month=12, day=31, 
+            date_A_to_S_after = dWrap(Date(freq='S', year=2007, month=12, day=31,
                                      hour=23, minute=59, second=59))
 
             assert_func(date_A.asfreq('Q', "BEFORE"), date_A_to_Q_before)
@@ -270,7 +279,7 @@
             assert_func(date_A.asfreq('S', "BEFORE"), date_A_to_S_before)
             assert_func(date_A.asfreq('S', "AFTER"), date_A_to_S_after)
 
-        
+
     def test_conv_quarterly(self):
         "frequency conversion tests: from Quarterly Frequency"
 
@@ -286,17 +295,17 @@
             date_Q_to_B_after = dWrap(Date(freq='B', year=2007, month=3, day=30))
             date_Q_to_D_before = dWrap(Date(freq='D', year=2007, month=1, day=1))
             date_Q_to_D_after = dWrap(Date(freq='D', year=2007, month=3, day=31))
-            date_Q_to_H_before = dWrap(Date(freq='H', year=2007, month=1, day=1, 
+            date_Q_to_H_before = dWrap(Date(freq='H', year=2007, month=1, day=1,
                                       hour=0))
-            date_Q_to_H_after = dWrap(Date(freq='H', year=2007, month=3, day=31, 
+            date_Q_to_H_after = dWrap(Date(freq='H', year=2007, month=3, day=31,
                                      hour=23))
-            date_Q_to_T_before = dWrap(Date(freq='T', year=2007, month=1, day=1, 
+            date_Q_to_T_before = dWrap(Date(freq='T', year=2007, month=1, day=1,
                                       hour=0, minute=0))
-            date_Q_to_T_after = dWrap(Date(freq='T', year=2007, month=3, day=31, 
+            date_Q_to_T_after = dWrap(Date(freq='T', year=2007, month=3, day=31,
                                      hour=23, minute=59))
-            date_Q_to_S_before = dWrap(Date(freq='S', year=2007, month=1, da