[Python-checkins] CVS: python/nondist/sandbox/datetime datetime.c,1.4,1.5
Fred L. Drake
fdrake@users.sourceforge.net
Tue, 05 Mar 2002 20:30:53 -0800
Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory usw-pr-cvs1:/tmp/cvs-serv5658
Modified Files:
datetime.c
Log Message:
Fix SET_MICROSECOND() macro to actually store the value correctly.
Add support for isoformat(), isoweekday(), weekday().
Added class attributes min, max.
Moved instance creation to a separate function from the tp_new
handler; this makes it easier to create instances using alternate
constructors, or just in C code.
Index: datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** datetime.c 6 Mar 2002 04:05:59 -0000 1.4
--- datetime.c 6 Mar 2002 04:30:51 -0000 1.5
***************
*** 29,34 ****
#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)))
static PyObject *
--- 29,103 ----
#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) >> 8), \
! ((o)->data[9] = ((v) & 0x0000ff)))
!
! /*
! * General calendrical helper functions
! */
!
! 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 long
! days_before_year(int year)
! {
! int y = year - 1;
! return y*365 + y/4 - y/100 + y/400;
! }
!
! /* Each entry at index 1..12 gives the number of days before each
! * month on non-leap years.
! */
! static int _days_before_month[] = {
! 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
! };
!
! static int
! days_before_month(int year, int month)
! {
! int days;
!
! assert(month >= 1);
! assert(month <= 12);
! days = _days_before_month[month];
! if (month > 2 && is_leap(year))
! ++days;
! return days;
! }
!
! static long
! ymd_to_ord(int year, int month, int day)
! {
! return days_before_year(year) + days_before_month(year, month) + day;
! }
!
! static int
! weekday(int year, int month, int day)
! {
! return (ymd_to_ord(year, month, day) + 6) % 7;
! }
!
!
! /*
! * PyDateTime_Object implementation
! */
static PyObject *
***************
*** 58,80 ****
}
! 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];
}
--- 127,148 ----
}
! /* Create a datetime instance with no range checking. */
! static PyObject *
! new_datetime(int year, int month, int day, int hour, int minute,
! int second, int usecond)
{
! PyDateTime_Object *self;
! 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);
! }
! return (PyObject *) self;
}
***************
*** 82,89 ****
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;
! static char * keywords[] = {
"year", "month", "day", "hour", "minute", "second", "microsecond", NULL
};
--- 150,157 ----
datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
! PyObject *self = NULL;
long int year, month, day, hour = 0, minute = 0, second = 0, usecond = 0;
! static char *keywords[] = {
"year", "month", "day", "hour", "minute", "second", "microsecond", NULL
};
***************
*** 121,136 ****
return 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);
! }
}
! return (PyObject *) self;
}
--- 189,195 ----
return NULL;
}
! self = new_datetime(year, month, day, hour, minute, second, usecond);
}
! return self;
}
***************
*** 189,192 ****
--- 248,300 ----
};
+ static PyObject *
+ datetime_isoformat(PyDateTime_Object *self, PyObject *args, PyObject *kw)
+ {
+ char buffer[128];
+ char sep = 'T';
+
+ static char *keywords[] = {"sep", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords, &sep))
+ return NULL;
+
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
+ GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
+ sep,
+ GET_HOUR(self), GET_MINUTE(self), GET_SECOND(self),
+ GET_MICROSECOND(self));
+ return PyString_FromString(buffer);
+ }
+
+ static PyObject *
+ datetime_isoweekday(PyDateTime_Object *self)
+ {
+ int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
+
+ return PyInt_FromLong(dow + 1);
+ }
+
+ static PyObject *
+ datetime_weekday(PyDateTime_Object *self)
+ {
+ int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
+
+ return PyInt_FromLong(dow);
+ }
+
+ static PyMethodDef datetime_methods[] = {
+ {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS|METH_KEYWORDS,
+ "Return the day of the week represented by the datetime.\n"
+ "Monday == 1 ... Sunday == 7"},
+ {"isoweekday", (PyCFunction)datetime_isoweekday, METH_NOARGS,
+ "Return the day of the week represented by the datetime.\n"
+ "Monday == 1 ... Sunday == 7"},
+ {"weekday", (PyCFunction)datetime_weekday, METH_NOARGS,
+ "Return the day of the week represented by the datetime.\n"
+ "Monday == 0 ... Sunday == 6"},
+ {NULL}
+ };
+
static char datetime_doc[] =
"Basic date/time type.";
***************
*** 223,227 ****
0, /* tp_iter */
0, /* tp_iternext */
! 0, /* tp_methods */
0, /* tp_members */
datetime_getset, /* tp_getset */
--- 331,335 ----
0, /* tp_iter */
0, /* tp_iternext */
! datetime_methods, /* tp_methods */
0, /* tp_members */
datetime_getset, /* tp_getset */
***************
*** 242,246 ****
{NULL, NULL, 0, NULL}
};
!
void
--- 350,354 ----
{NULL, NULL, 0, NULL}
};
!
void
***************
*** 248,254 ****
--- 356,373 ----
{
PyObject *m;
+ PyObject *d, *dt;
if (PyType_Ready(&PyDateTime_Type) < 0)
return;
+
+ d = PyDateTime_Type.tp_dict;
+ dt = new_datetime(1, 1, 1, 0, 0, 0, 0);
+ if (dt == NULL || PyDict_SetItemString(d, "min", dt) < 0)
+ return;
+ Py_DECREF(dt);
+ dt = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999);
+ if (dt == NULL || PyDict_SetItemString(d, "max", dt) < 0)
+ return;
+ Py_DECREF(dt);
m = Py_InitModule3("_datetime", functions,