[Python-checkins] python/dist/src/Modules datetimemodule.c,1.21,1.22

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Tue, 31 Dec 2002 20:48:04 -0800


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv23078/Modules

Modified Files:
	datetimemodule.c 
Log Message:
datetimetz_astimezone():  Speed optimizations -- although I'd rather
find a more elegant algorithm (OTOH, the hairy new implementation allows
user-written tzinfo classes to be elegant, so it's a big win even if
astimezone() remains hairy).

Darn!  I've only got 10 minutes left to get falling-down drunk!  I suppose
I'll have to smoke crack instead now.


Index: datetimemodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** datetimemodule.c	31 Dec 2002 17:36:56 -0000	1.21
--- datetimemodule.c	1 Jan 2003 04:48:01 -0000	1.22
***************
*** 4754,4758 ****
  	PyObject *result;
  	PyObject *temp;
! 	int myoff, otoff, newoff;
  	int none;
  
--- 4754,4758 ----
  	PyObject *result;
  	PyObject *temp;
! 	int selfoff, resoff, tempoff, total_added_to_result;
  	int none;
  
***************
*** 4777,4795 ****
           * there's no conversion of date or time fields.
           */
! 	myoff = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
! 	if (myoff == -1 && PyErr_Occurred())
  		goto Fail;
  	if (none)
  		return result;
  
! 	otoff = call_utcoffset(tzinfo, result, &none);
! 	if (otoff == -1 && PyErr_Occurred())
  		goto Fail;
  	if (none)
  		return result;
  
! 	/* Add otoff-myoff to result. */
! 	mm += otoff - myoff;
! 	if (normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
  		goto Fail;
  	temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo);
--- 4777,4797 ----
           * there's no conversion of date or time fields.
           */
! 	selfoff = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
! 	if (selfoff == -1 && PyErr_Occurred())
  		goto Fail;
  	if (none)
  		return result;
  
! 	resoff = call_utcoffset(tzinfo, result, &none);
! 	if (resoff == -1 && PyErr_Occurred())
  		goto Fail;
  	if (none)
  		return result;
  
! 	/* Add resoff-selfoff to result. */
! 	total_added_to_result = resoff - selfoff;
! 	mm += total_added_to_result;
! 	if ((mm < 0 || mm >= 60) &&
! 	    normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
  		goto Fail;
  	temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo);
***************
*** 4806,4819 ****
  	 * DST boundary, if we landed on one of the DST "problem hours".
  	 */
! 	newoff = call_utcoffset(tzinfo, result, &none);
! 	if (newoff == -1 && PyErr_Occurred())
  		goto Fail;
  	if (none)
  		goto Inconsistent;
  
! 	if (newoff != otoff) {
  		/* We did cross a boundary.  Try to correct. */
! 		mm += newoff - otoff;
! 		if (normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
  			goto Fail;
  		temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo);
--- 4808,4824 ----
  	 * DST boundary, if we landed on one of the DST "problem hours".
  	 */
! 	tempoff = call_utcoffset(tzinfo, result, &none);
! 	if (tempoff == -1 && PyErr_Occurred())
  		goto Fail;
  	if (none)
  		goto Inconsistent;
  
! 	if (tempoff != resoff) {
  		/* We did cross a boundary.  Try to correct. */
! 		const int delta = tempoff - resoff;
! 		total_added_to_result += delta;
! 		mm += delta;
! 		if ((mm < 0 || mm >= 60) &&
! 		    normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
  			goto Fail;
  		temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo);
***************
*** 4823,4828 ****
  		result = temp;
  
! 		otoff = call_utcoffset(tzinfo, result, &none);
! 		if (otoff == -1 && PyErr_Occurred())
  			goto Fail;
  		if (none)
--- 4828,4833 ----
  		result = temp;
  
! 		resoff = call_utcoffset(tzinfo, result, &none);
! 		if (resoff == -1 && PyErr_Occurred())
  			goto Fail;
  		if (none)
***************
*** 4835,4845 ****
  	 */
  	hh -= 1;
! 	if (normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
  		goto Fail;
  	temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo);
  	if (temp == NULL)
  		goto Fail;
! 	newoff = call_utcoffset(tzinfo, temp, &none);
! 	if (newoff == -1 && PyErr_Occurred()) {
  		Py_DECREF(temp);
  		goto Fail;
--- 4840,4850 ----
  	 */
  	hh -= 1;
! 	if (hh < 0 && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
  		goto Fail;
  	temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo);
  	if (temp == NULL)
  		goto Fail;
! 	tempoff = call_utcoffset(tzinfo, temp, &none);
! 	if (tempoff == -1 && PyErr_Occurred()) {
  		Py_DECREF(temp);
  		goto Fail;
***************
*** 4850,4858 ****
  	}
  	/* Are temp and result really the same time?  temp == result iff
! 	 * temp - newoff == result - otoff, iff
! 	 * (result - HOUR) - newoff = result - otoff, iff
! 	 * otoff - newoff == HOUR
  	 */
! 	if (otoff - newoff == 60) {
  		/* use the local time that makes sense */
  		Py_DECREF(result);
--- 4855,4863 ----
  	}
  	/* Are temp and result really the same time?  temp == result iff
! 	 * temp - tempoff == result - resoff, iff
! 	 * (result - HOUR) - tempoff = result - resoff, iff
! 	 * resoff - tempoff == HOUR
  	 */
! 	if (resoff - tempoff == 60) {
  		/* use the local time that makes sense */
  		Py_DECREF(result);
***************
*** 4862,4877 ****
  
  	/* There's still a problem with the unspellable (in local time)
! 	 * hour after DST ends.
  	 */
! 	temp = datetime_richcompare((PyDateTime_DateTime *)self,
! 				    result, Py_EQ);
! 	if (temp == NULL)
! 		goto Fail;
! 	if (temp == Py_True) {
! 		Py_DECREF(temp);
  		return result;
! 	}
! 	Py_DECREF(temp);
!         /* Else there's no way to spell self in zone other.tz. */
          PyErr_SetString(PyExc_ValueError, "astimezone(): the source "
          		"datetimetz can't be expressed in the target "
--- 4867,4883 ----
  
  	/* There's still a problem with the unspellable (in local time)
! 	 * hour after DST ends.  If self and result map to the same UTC time
! 	 * time, we're OK, else the hour is unrepresentable in the tzinfo
! 	 * zone.  The result's local time now is
! 	 * self + total_added_to_result, so self == result iff
! 	 * self - selfoff == result - resoff, iff
! 	 * self - selfoff == (self + total_added_to_result) - resoff, iff
! 	 * - selfoff == total_added_to_result - resoff, iff
! 	 * total_added_to_result == resoff - selfoff
  	 */
! 	if (total_added_to_result == resoff - selfoff)
  		return result;
! 
!         /* Else there's no way to spell self in zone tzinfo. */
          PyErr_SetString(PyExc_ValueError, "astimezone(): the source "
          		"datetimetz can't be expressed in the target "