[Python-checkins] CVS: python/nondist/sandbox/datetime datetime.c,1.1,1.2

Fred L. Drake fdrake@users.sourceforge.net
Mon, 04 Mar 2002 12:43:18 -0800


Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory usw-pr-cvs1:/tmp/cvs-serv6488

Modified Files:
	datetime.c 
Log Message:
Added constructor & basic attributes (+ required type object).
Several slots have handlers that are dummied in.


Index: datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** datetime.c	4 Mar 2002 14:36:16 -0000	1.1
--- datetime.c	4 Mar 2002 20:43:16 -0000	1.2
***************
*** 1,4 ****
  /*  C implementation for the date/time type documented at
!  *  
   */
  
--- 1,4 ----
  /*  C implementation for the date/time type documented at
!  *  http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
   */
  
***************
*** 6,9 ****
--- 6,271 ----
  #include "modsupport.h"
  
+ #include "datetime.h"
+ 
+ #define MINYEAR 1
+ #define MAXYEAR 9999
+ 
+ /* Rename the long macros in datetime.h to more reasonable short names. */
+ #define GET_YEAR(o)        PyDateTime_GET_YEAR(o)
+ #define GET_MONTH(o)       PyDateTime_GET_MONTH(o)
+ #define GET_DAY(o)         PyDateTime_GET_DAY(o)
+ #define GET_HOUR(o)        PyDateTime_GET_HOUR(o)
+ #define GET_MINUTE(o)      PyDateTime_GET_MINUTE(o)
+ #define GET_SECOND(o)      PyDateTime_GET_SECOND(o)
+ #define GET_MICROSECOND(o) PyDateTime_GET_MICROSECOND(o)
+ #define GET_TZOFFSET(o)    PyDateTime_GET_TZOFFSET(o)
+ 
+ /* Set accessors. */
+ #define SET_YEAR(o, v)        (((o)->data[0] = ((v) & 0xff00) >> 8), \
+                                ((o)->data[1] = ((v) & 0x00ff)))
+ #define SET_MONTH(o, v)       (PyDateTime_GET_MONTH(o) = (v))
+ #define SET_DAY(o, v)         (PyDateTime_GET_DAY(o) = (v))
+ #define SET_HOUR(o, v)        (PyDateTime_GET_HOUR(o) = (v))
+ #define SET_MINUTE(o, v)      (PyDateTime_GET_MINUTE(o) = (v))
+ #define SET_SECOND(o, v)      (PyDateTime_GET_SECOND(o) = (v))
+ #define SET_MICROSECOND(o, v) (((o)->data[7] = ((v) & 0xff0000) >> 16), \
+                                ((o)->data[8] = ((v) & 0x00ff00) >> 0), \
+                                ((o)->data[9] = ((v) & 0x00ff00)))
+ #define SET_TZOFFSET(o, v)    (((o)->data[10] = ((v) & 0xff00) >> 8), \
+                                ((o)->data[11] = ((v) & 0x00ff)))
+ 
+ static PyObject *
+ datetime_compare(PyDateTime_Object *self, PyObject *other)
+ {
+     PyErr_SetString(PyExc_NotImplementedError,
+                     "not yet implemented");
+     return NULL;
+ }
+ 
+ static PyObject *
+ datetime_repr(PyDateTime_Object *self)
+ {
+     return PyString_FromString("<datetime.datetime instance>");
+ }
+ 
+ static PyObject *
+ datetime_str(PyDateTime_Object *self)
+ {
+     return datetime_repr(self);
+ }
+ 
+ static int
+ datetime_hash(PyDateTime_Object *self)
+ {
+     return -2;
+ }
+ 
+ static int
+ is_leap(int year)
+ {
+     return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
+ }
+ 
+ static int
+ days_in_month(int year, int month)
+ {
+     static int _days_in_month[] = {
+         0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+     };
+ 
+     assert(month >= 1);
+     assert(month <= 12);
+     if (month == 2 && is_leap(year))
+         return 29;
+     else
+         return _days_in_month[month];
+ }
+ 
+ static PyObject *
+ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+ {
+     PyDateTime_Object *self = NULL;
+     long int year, month, day, hour = 0, minute = 0, second = 0, usecond = 0;
+     long int tzoffset;
+     PyObject *tzoffset_object = Py_None;
+ 
+     static char * keywords[] = {
+         "year", "month", "day", "hour", "minute", "second", "microsecond",
+         "tzoffset", NULL
+     };
+ 
+     if (PyArg_ParseTupleAndKeywords(args, kw, "lll|llllO", keywords,
+                                     &year, &month, &day, &hour, &minute,
+                                     &second, &usecond, &tzoffset_object)) {
+         if (year < MINYEAR || year > MAXYEAR) {
+             PyErr_SetString(PyExc_ValueError, "year is out of range");
+             return NULL;
+         }
+         if (month < 1 || month > 12) {
+             PyErr_SetString(PyExc_ValueError, "month must be in 1..12");
+             return NULL;
+         }
+         if (day < 1 || day > days_in_month(year, month)) {
+             PyErr_SetString(PyExc_ValueError, "day is out of range for month");
+             return NULL;
+         }
+         if (hour < 0 || hour > 23) {
+             PyErr_SetString(PyExc_ValueError, "hour must be in 0..23");
+             return NULL;
+         }
+         if (minute < 0 || minute > 59) {
+             PyErr_SetString(PyExc_ValueError, "minute must be in 0..59");
+             return NULL;
+         }
+         if (second < 0 || second > 59) {
+             PyErr_SetString(PyExc_ValueError, "second must be in 0..59");
+             return NULL;
+         }
+         if (usecond < 0 || usecond > 999999) {
+             PyErr_SetString(PyExc_ValueError,
+                             "microsecond must be in 0..999999");
+             return NULL;
+         }
+         if (tzoffset_object == Py_None) {
+             /* tzoffset == None not yet implemented */
+             tzoffset = 0;
+         }
+         else {
+             tzoffset_object = PyNumber_Int(tzoffset_object);
+             if (tzoffset_object == NULL)
+                 return NULL;
+             tzoffset = PyInt_AS_LONG(tzoffset_object);
+             Py_DECREF(tzoffset_object);
+             if (tzoffset < -1439 || tzoffset > 1439) {
+                 PyErr_SetString(PyExc_ValueError,
+                                 "tzoffset must be in -1439..1439");
+                 return NULL;
+             }
+             tzoffset_object = NULL;
+         }
+         self = PyObject_New(PyDateTime_Object, &PyDateTime_Type);
+         if (self != NULL) {
+             SET_YEAR(self, year);
+             SET_MONTH(self, month);
+             SET_DAY(self, day);
+             SET_HOUR(self, hour);
+             SET_MINUTE(self, minute);
+             SET_SECOND(self, second);
+             SET_MICROSECOND(self, usecond);
+             SET_TZOFFSET(self, tzoffset);
+         }
+     }
+     return (PyObject *) self;
+ }
+ 
+ 
+ static PyObject *
+ datetime_year(PyDateTime_Object *self, void *unused)
+ {
+     return (PyInt_FromLong(GET_YEAR(self)));
+ }
+ 
+ static PyObject *
+ datetime_month(PyDateTime_Object *self, void *unused)
+ {
+     return (PyInt_FromLong(GET_MONTH(self)));
+ }
+ 
+ static PyObject *
+ datetime_day(PyDateTime_Object *self, void *unused)
+ {
+     return (PyInt_FromLong(GET_DAY(self)));
+ }
+ 
+ static PyObject *
+ datetime_hour(PyDateTime_Object *self, void *unused)
+ {
+     return (PyInt_FromLong(GET_HOUR(self)));
+ }
+ 
+ static PyObject *
+ datetime_minute(PyDateTime_Object *self, void *unused)
+ {
+     return (PyInt_FromLong(GET_MINUTE(self)));
+ }
+ 
+ static PyObject *
+ datetime_second(PyDateTime_Object *self, void *unused)
+ {
+     return (PyInt_FromLong(GET_SECOND(self)));
+ }
+ 
+ static PyObject *
+ datetime_microsecond(PyDateTime_Object *self, void *unused)
+ {
+     return (PyInt_FromLong(GET_MICROSECOND(self)));
+ }
+ 
+ static PyObject *
+ datetime_tzoffset(PyDateTime_Object *self, void *unused)
+ {
+     return (PyInt_FromLong(GET_TZOFFSET(self)));
+ }
+ 
+ static PyGetSetDef datetime_getset[] = {
+     {"year",(getter)datetime_year},
+     {"month",       (getter)datetime_month},
+     {"day",         (getter)datetime_day},
+     {"hour",        (getter)datetime_hour},
+     {"minute",      (getter)datetime_minute},
+     {"second",      (getter)datetime_second},
+     {"microsecond", (getter)datetime_microsecond},
+     {"tzoffset",    (getter)datetime_tzoffset},
+     {NULL}
+ };
+ 
+ static char datetime_doc[] =
+ "Basic date/time type.";
+ 
+ 
+ PyTypeObject PyDateTime_Type = {
+ 	PyObject_HEAD_INIT(&PyType_Type)
+ 	0,					/* ob_size */
+ 	"datetime.datetime",			/* tp_name */
+ 	sizeof(PyDateTime_Object),		/* tp_basicsize */
+ 	0,					/* tp_itemsize */
+ 	_PyObject_Del,				/* tp_dealloc */
+ 	0,					/* tp_print */
+ 	0,					/* tp_getattr */
+ 	0,					/* tp_setattr */
+ 	(cmpfunc)datetime_compare,		/* tp_compare */
+ 	(reprfunc)datetime_repr,		/* tp_repr */
+ 	0,					/* tp_as_number */
+ 	/*&datetime_as_number,			/* tp_as_number */
+ 	0,					/* tp_as_sequence */
+ 	0,					/* tp_as_mapping */
+ 	(hashfunc)datetime_hash,		/* tp_hash */
+         0,              			/* tp_call */
+         (reprfunc)datetime_str,			/* tp_str */
+ 	PyObject_GenericGetAttr,		/* tp_getattro */
+ 	0,					/* tp_setattro */
+ 	0,					/* tp_as_buffer */
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ 		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+ 	datetime_doc,				/* tp_doc */
+ 	0,					/* tp_traverse */
+ 	0,					/* tp_clear */
+ 	0,					/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	0,					/* tp_methods */
+ 	0,					/* tp_members */
+ 	datetime_getset,			/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_dictoffset */
+ 	0,					/* tp_init */
+ 	0,					/* tp_alloc */
+ 	datetime_new,				/* tp_new */
+ 	_PyObject_Del,				/* tp_free */
+ };
  
  
***************
*** 17,23 ****
  init_datetime(void)
  {
!     PyObject *m = Py_InitModule3("_datetime", functions,
!                                  "Fast implementation of the datetime type.");
      PyModule_AddIntConstant(m, "MINYEAR", 1);
      PyModule_AddIntConstant(m, "MAXYEAR", 9999);
  }
--- 279,292 ----
  init_datetime(void)
  {
!     PyObject *m;
! 
!     if (PyType_Ready(&PyDateTime_Type) < 0)
!         return;
! 
!     m = Py_InitModule3("_datetime", functions,
!                        "Fast implementation of the datetime type.");
      PyModule_AddIntConstant(m, "MINYEAR", 1);
      PyModule_AddIntConstant(m, "MAXYEAR", 9999);
+     Py_INCREF(&PyDateTime_Type);
+     PyModule_AddObject(m, "datetime", (PyObject *) &PyDateTime_Type);
  }