[Python-checkins] python/nondist/sandbox/datetime obj_date.c,1.27,1.28

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Thu, 05 Dec 2002 11:03:21 -0800


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

Modified Files:
	obj_date.c 
Log Message:
Changed the C implementations of

    date + timedelta
    timedelta + date
    date - timedelta

to match the Python implementations (the docs were already changed to
match).  Despite the major simplification of the code, no tests failed
as a result.  This says, in part, that the tests weren't testing enough.
I'll add more tests next.


Index: obj_date.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_date.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -d -r1.27 -r1.28
*** obj_date.c	5 Dec 2002 17:07:20 -0000	1.27
--- obj_date.c	5 Dec 2002 19:03:17 -0000	1.28
***************
*** 23,62 ****
  }
  
  static PyObject *
! datetime_add(PyObject *left, PyObject *right);
! 
! static PyObject *
! datetime_subtract(PyObject *left, PyObject *right);
! 
! static PyObject *
! add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta)
  {
! 	PyObject *result;
! 	/* delta + date */
! 	if (GET_TD_SECONDS(delta) != 0
! 	    || GET_TD_MICROSECONDS(delta) != 0) {
! 		/* Convert to datetime and pass it off. */
! 		PyObject *dt = new_datetime(GET_YEAR(date), GET_MONTH(date),
! 					    GET_DAY(date), 0, 0, 0, 0);
! 		if (dt == NULL)
! 			return NULL;
! 		result = datetime_add((PyObject *)delta, dt);
! 		Py_DECREF(dt);
! 	}
! 	else if (GET_TD_DAYS(delta) != 0) {
! 		/* There's actually something to do. */
! 		long int year = GET_YEAR(date);
! 		long int month = GET_MONTH(date);
! 		long int day = GET_DAY(date) + GET_TD_DAYS(delta);
! 		if (normalize_date(&year, &month, &day) < 0)
! 			result = NULL;
! 		else
! 			result = new_date(year, month, day);
! 	}
! 	else {
! 		/* The delta is timedelta(0), so return the original date. */
! 		Py_INCREF(date);
! 		result = (PyObject *) date;
! 	}
  	return result;
  }
--- 23,41 ----
  }
  
+ /* 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;
  }
***************
*** 76,89 ****
  		/* date + ??? */
  		if (PyType_IsSubtype(right_type, &PyDateTime_DeltaType))
  			return add_date_timedelta((PyDateTime_Date *) left,
! 						  (PyDateTime_Delta *) right);
  	}
  	else {
! 		/* 'right' must be one of us, or we wouldn't have
! 		   been called */
  		if (PyType_IsSubtype(left_type, &PyDateTime_DeltaType))
  			return add_date_timedelta((PyDateTime_Date *) right,
! 						  (PyDateTime_Delta *) left);
! 		/* else fall through; we don't support it here */
  	}
  	Py_INCREF(Py_NotImplemented);
--- 55,72 ----
  		/* 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);
***************
*** 114,157 ****
  		}
  		if (PyType_IsSubtype(right_type, &PyDateTime_DeltaType)) {
! 			PyObject *result = NULL;
! 			if (GET_TD_SECONDS(right) != 0
! 			    || GET_TD_MICROSECONDS(right) != 0) {
! 				/* need to convert to datetime + delta */
! 				PyObject *dt = new_datetime(GET_YEAR(left),
! 							    GET_MONTH(left),
! 							    GET_DAY(left),
! 							    0, 0, 0, 0);
! 				if (dt != NULL) {
! 					result = datetime_subtract(dt, right);
! 					Py_DECREF(dt);
! 				}
! 			}
! 			else if (GET_TD_DAYS(right) == 0) {
! 				/* date - timedelta(0) */
! 				Py_INCREF(left);
! 				result = left;
! 			}
! 			else {
! 				long year, month, day;
! 				long ord = ymd_to_ord(GET_YEAR(left),
! 						      GET_MONTH(left),
! 						      GET_DAY(left));
! 				ord -= GET_TD_DAYS(right);
! 				if (ord < 1)
! 					goto Overflow;
! 				ord_to_ymd(ord, &year, &month, &day);
! 				if (year < MINYEAR || year > MAXYEAR)
! 					goto Overflow;
! 				result = new_date(year, month, day);
! 			}
! 			return result;
  		}
  	}
  	Py_INCREF(Py_NotImplemented);
  	return Py_NotImplemented;
- 
- Overflow:
- 	PyErr_SetString(PyExc_OverflowError, "date subtraction");
- 	return NULL;
  }
  
--- 97,108 ----
  		}
  		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;
  }