[Python-checkins] python/nondist/sandbox/datetime obj_date.c,1.33,1.34
tim_one@users.sourceforge.net
tim_one@users.sourceforge.net
Fri, 06 Dec 2002 09:14:39 -0800
Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv19571
Modified Files:
obj_date.c
Log Message:
Cleanup: rearranged the date code to follow the same ordering of
functions as was previously established for the datetime code.
Index: obj_date.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_date.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** obj_date.c 6 Dec 2002 17:05:13 -0000 1.33
--- obj_date.c 6 Dec 2002 17:14:21 -0000 1.34
***************
*** 3,166 ****
*/
! /* Fiddle out-of-bounds months and days so that the result makes some kind
! * of sense. The parameters are both inputs and outputs. Returns < 0 on
! * failure, where failure means the adjusted year is out of bounds.
! */
! static int
! normalize_date(long *year, long *month, long *day)
! {
! int result;
!
! normalize_y_m_d(year, month, day);
! if (MINYEAR <= *year && *year <= MAXYEAR)
! result = 0;
! else {
! PyErr_SetString(PyExc_OverflowError,
! "date value out of range");
! result = -1;
! }
! return result;
! }
!
! /* date + timedelta -> date. If arg negate is true, subtract the timedelta
! * instead.
! */
! static PyObject *
! add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
! {
! PyObject *result = NULL;
! long year = GET_YEAR(date);
! long month = GET_MONTH(date);
! long deltadays = GET_TD_DAYS(delta);
! /* C-level overflow is impossible because |deltadays| < 1e9. */
! long day = GET_DAY(date) + (negate ? -deltadays : deltadays);
!
! if (normalize_date(&year, &month, &day) >= 0)
! result = new_date(year, month, day);
! return result;
! }
!
! static PyObject *
! date_add(PyObject *left, PyObject *right)
! {
! PyTypeObject *left_type = left->ob_type;
! PyTypeObject *right_type = right->ob_type;
!
! if (PyType_IsSubtype(left_type, &PyDateTime_DateTimeType)
! || PyType_IsSubtype(right_type, &PyDateTime_DateTimeType)) {
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
! }
! if (PyType_IsSubtype(left_type, &PyDateTime_DateType)) {
! /* date + ??? */
! if (PyType_IsSubtype(right_type, &PyDateTime_DeltaType))
! /* date + delta */
! return add_date_timedelta((PyDateTime_Date *) left,
! (PyDateTime_Delta *) right,
! 0);
! }
! else {
! /* ??? + date
! * 'right' must be one of us, or we wouldn't have been called
! */
! if (PyType_IsSubtype(left_type, &PyDateTime_DeltaType))
! /* delta + date */
! return add_date_timedelta((PyDateTime_Date *) right,
! (PyDateTime_Delta *) left,
! 0);
! }
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
! }
!
! static PyObject *
! date_subtract(PyObject *left, PyObject *right)
! {
! PyTypeObject *left_type = left->ob_type;
! PyTypeObject *right_type = right->ob_type;
!
! if (PyType_IsSubtype(left_type, &PyDateTime_DateTimeType)
! || PyType_IsSubtype(right_type, &PyDateTime_DateTimeType)) {
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
! }
! if (PyType_IsSubtype(left_type, &PyDateTime_DateType)) {
! if (PyType_IsSubtype(right_type, &PyDateTime_DateType)) {
! /* date - date */
! long left_ord = ymd_to_ord(GET_YEAR(left),
! GET_MONTH(left),
! GET_DAY(left));
! long right_ord = ymd_to_ord(GET_YEAR(right),
! GET_MONTH(right),
! GET_DAY(right));
! return new_delta(left_ord - right_ord, 0, 0, 0);
! }
! if (PyType_IsSubtype(right_type, &PyDateTime_DeltaType)) {
! /* date - delta */
! return add_date_timedelta((PyDateTime_Date *) left,
! (PyDateTime_Delta *) right,
! 1);
! }
! }
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
! }
- /* This is more natural as a tp_compare, but doesn't work then: for whatever
- * reason, Python's try_3way_compare ignores tp_compare unless
- * PyInstance_Check returns true, but these aren't old-style classes.
- */
static PyObject *
! date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
{
! long diff;
!
! if (! PyType_IsSubtype(other->ob_type, &PyDateTime_DateType)) {
! PyErr_Format(PyExc_TypeError,
! "can't compare date to %s instance",
! other->ob_type->tp_name);
! return NULL;
! }
! diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
! _PyDateTime_DATE_DATA_SIZE);
! return diff_to_bool(diff, op);
}
static PyObject *
! date_ctime(PyDateTime_Date *self)
{
! return format_ctime(self, 0, 0, 0);
}
static PyObject *
! date_timetuple(PyDateTime_Date *self)
{
! const int year = GET_YEAR(self);
! const int month = GET_MONTH(self);
! const int day = GET_DAY(self);
!
! return Py_BuildValue("iiiiiiiii",
! year, month, day,
! 0, 0, 0,
! weekday(year, month, day),
! days_before_month(year, month) + day,
! -1);
}
! static long
! date_hash(PyDateTime_Date *self)
! {
! if (self->hashcode == -1) {
! PyObject *temp = Py_BuildValue("lll", GET_YEAR(self),
! GET_MONTH(self), GET_DAY(self));
! if (temp != NULL) {
! self->hashcode = PyObject_Hash(temp);
! Py_DECREF(temp);
! }
! }
! return self->hashcode;
! }
! /* Constructor. */
static PyObject *
--- 3,34 ----
*/
! /* Accessor properties. */
static PyObject *
! date_year(PyDateTime_Date *self, void *unused)
{
! return (PyInt_FromLong(GET_YEAR(self)));
}
static PyObject *
! date_month(PyDateTime_Date *self, void *unused)
{
! return (PyInt_FromLong(GET_MONTH(self)));
}
static PyObject *
! date_day(PyDateTime_Date *self, void *unused)
{
! return (PyInt_FromLong(GET_DAY(self)));
}
! static PyGetSetDef date_getset[] = {
! {"year", (getter)date_year},
! {"month", (getter)date_month},
! {"day", (getter)date_day},
! {NULL}
! };
! /* Constructors. */
static PyObject *
***************
*** 196,201 ****
}
- /* Class-method constructors. */
-
/* Return new date from localtime(t). */
static PyObject *
--- 64,67 ----
***************
*** 227,231 ****
date_today(PyObject *self, PyObject *cls)
{
! PyObject *time; /* the time module) */
PyObject *time_time; /* time.time() */
PyObject *result;
--- 93,97 ----
date_today(PyObject *self, PyObject *cls)
{
! PyObject *time; /* the time module */
PyObject *time_time; /* time.time() */
PyObject *result;
***************
*** 292,358 ****
}
! /* Attributes. */
! static PyObject *
! date_year(PyDateTime_Date *self, void *unused)
{
! return (PyInt_FromLong(GET_YEAR(self)));
! }
! static PyObject *
! date_month(PyDateTime_Date *self, void *unused)
! {
! return (PyInt_FromLong(GET_MONTH(self)));
}
static PyObject *
! date_day(PyDateTime_Date *self, void *unused)
{
! return (PyInt_FromLong(GET_DAY(self)));
! }
! static PyGetSetDef date_getset[] = {
! {"year", (getter)date_year},
! {"month", (getter)date_month},
! {"day", (getter)date_day},
! {NULL}
! };
static PyObject *
! date_isocalendar(PyDateTime_Date *self)
{
! int year = GET_YEAR(self);
! int week1_monday = iso_week1_monday(year);
! long today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
! long week;
! long day;
! week = divmod(today - week1_monday, 7, &day);
! if (week < 0) {
! --year;
! week1_monday = iso_week1_monday(year);
! week = divmod(today - week1_monday, 7, &day);
}
! else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
! ++year;
! week = 0;
}
! return Py_BuildValue("iii", year, (int)week + 1, (int)day + 1);
}
static PyObject *
! date_isoweekday(PyDateTime_Date *self)
{
! int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
! return PyInt_FromLong(dow + 1);
}
! static int
! date_nonzero(PyDateTime_Date *self)
! {
! assert(GET_YEAR(self) >= 1);
! return 1;
! }
static PyObject *
--- 158,269 ----
}
! /* date arithmetic. */
! /* Fiddle out-of-bounds months and days so that the result makes some kind
! * of sense. The parameters are both inputs and outputs. Returns < 0 on
! * failure, where failure means the adjusted year is out of bounds.
! */
! static int
! normalize_date(long *year, long *month, long *day)
{
! int result;
! normalize_y_m_d(year, month, day);
! if (MINYEAR <= *year && *year <= MAXYEAR)
! result = 0;
! else {
! PyErr_SetString(PyExc_OverflowError,
! "date value out of range");
! result = -1;
! }
! return result;
}
+ /* date + timedelta -> date. If arg negate is true, subtract the timedelta
+ * instead.
+ */
static PyObject *
! add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
{
! PyObject *result = NULL;
! long year = GET_YEAR(date);
! long month = GET_MONTH(date);
! long deltadays = GET_TD_DAYS(delta);
! /* C-level overflow is impossible because |deltadays| < 1e9. */
! long day = GET_DAY(date) + (negate ? -deltadays : deltadays);
! if (normalize_date(&year, &month, &day) >= 0)
! result = new_date(year, month, day);
! return result;
! }
static PyObject *
! date_add(PyObject *left, PyObject *right)
{
! PyTypeObject *left_type = left->ob_type;
! PyTypeObject *right_type = right->ob_type;
! if (PyType_IsSubtype(left_type, &PyDateTime_DateTimeType)
! || PyType_IsSubtype(right_type, &PyDateTime_DateTimeType)) {
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
}
! if (PyType_IsSubtype(left_type, &PyDateTime_DateType)) {
! /* date + ??? */
! if (PyType_IsSubtype(right_type, &PyDateTime_DeltaType))
! /* date + delta */
! return add_date_timedelta((PyDateTime_Date *) left,
! (PyDateTime_Delta *) right,
! 0);
}
! else {
! /* ??? + date
! * 'right' must be one of us, or we wouldn't have been called
! */
! if (PyType_IsSubtype(left_type, &PyDateTime_DeltaType))
! /* delta + date */
! return add_date_timedelta((PyDateTime_Date *) right,
! (PyDateTime_Delta *) left,
! 0);
! }
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
}
static PyObject *
! date_subtract(PyObject *left, PyObject *right)
{
! PyTypeObject *left_type = left->ob_type;
! PyTypeObject *right_type = right->ob_type;
! if (PyType_IsSubtype(left_type, &PyDateTime_DateTimeType)
! || PyType_IsSubtype(right_type, &PyDateTime_DateTimeType)) {
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
! }
! if (PyType_IsSubtype(left_type, &PyDateTime_DateType)) {
! if (PyType_IsSubtype(right_type, &PyDateTime_DateType)) {
! /* date - date */
! long left_ord = ymd_to_ord(GET_YEAR(left),
! GET_MONTH(left),
! GET_DAY(left));
! long right_ord = ymd_to_ord(GET_YEAR(right),
! GET_MONTH(right),
! GET_DAY(right));
! return new_delta(left_ord - right_ord, 0, 0, 0);
! }
! if (PyType_IsSubtype(right_type, &PyDateTime_DeltaType)) {
! /* date - delta */
! return add_date_timedelta((PyDateTime_Date *) left,
! (PyDateTime_Delta *) right,
! 1);
! }
! }
! Py_INCREF(Py_NotImplemented);
! return Py_NotImplemented;
}
!
! /* Various ways to turn a date into a string. */
static PyObject *
***************
*** 381,384 ****
--- 292,301 ----
static PyObject *
+ date_ctime(PyDateTime_Date *self)
+ {
+ return format_ctime(self, 0, 0, 0);
+ }
+
+ static PyObject *
date_strftime(PyDateTime_Date *self, PyObject *format)
{
***************
*** 398,401 ****
--- 315,408 ----
}
+ /* ISO methods. */
+
+ static PyObject *
+ date_isoweekday(PyDateTime_Date *self)
+ {
+ int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
+
+ return PyInt_FromLong(dow + 1);
+ }
+
+ static PyObject *
+ date_isocalendar(PyDateTime_Date *self)
+ {
+ int year = GET_YEAR(self);
+ int week1_monday = iso_week1_monday(year);
+ long today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
+ long week;
+ long day;
+
+ week = divmod(today - week1_monday, 7, &day);
+ if (week < 0) {
+ --year;
+ week1_monday = iso_week1_monday(year);
+ week = divmod(today - week1_monday, 7, &day);
+ }
+ else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
+ ++year;
+ week = 0;
+ }
+ return Py_BuildValue("iii", year, (int)week + 1, (int)day + 1);
+ }
+
+ /* Miscellaneous methods. */
+
+ /* This is more natural as a tp_compare, but doesn't work then: for whatever
+ * reason, Python's try_3way_compare ignores tp_compare unless
+ * PyInstance_Check returns true, but these aren't old-style classes.
+ */
+ static PyObject *
+ date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
+ {
+ long diff;
+
+ if (! PyType_IsSubtype(other->ob_type, &PyDateTime_DateType)) {
+ PyErr_Format(PyExc_TypeError,
+ "can't compare date to %s instance",
+ other->ob_type->tp_name);
+ return NULL;
+ }
+ diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
+ _PyDateTime_DATE_DATA_SIZE);
+ return diff_to_bool(diff, op);
+ }
+
+ static PyObject *
+ date_timetuple(PyDateTime_Date *self)
+ {
+ const int year = GET_YEAR(self);
+ const int month = GET_MONTH(self);
+ const int day = GET_DAY(self);
+
+ return Py_BuildValue("iiiiiiiii",
+ year, month, day,
+ 0, 0, 0,
+ weekday(year, month, day),
+ days_before_month(year, month) + day,
+ -1);
+ }
+
+ static long
+ date_hash(PyDateTime_Date *self)
+ {
+ if (self->hashcode == -1) {
+ PyObject *temp = Py_BuildValue("lll", GET_YEAR(self),
+ GET_MONTH(self), GET_DAY(self));
+ if (temp != NULL) {
+ self->hashcode = PyObject_Hash(temp);
+ Py_DECREF(temp);
+ }
+ }
+ return self->hashcode;
+ }
+
+ static int
+ date_nonzero(PyDateTime_Date *self)
+ {
+ assert(GET_YEAR(self) >= 1);
+ return 1;
+ }
+
static PyObject *
date_toordinal(PyDateTime_Date *self)
***************
*** 414,417 ****
--- 421,425 ----
/* Pickle support. Quite a maze! */
+
static PyObject *
date_getstate(PyDateTime_Date *self)
***************
*** 467,471 ****
}
- /* XXX strftime is missing. */
static PyMethodDef date_methods[] = {
/* Class methods: */
--- 475,478 ----