[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 ----