| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 1 | /*  C implementation for the date/time type documented at | 
 | 2 |  *  http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage | 
 | 3 |  */ | 
 | 4 |  | 
 | 5 | #include "Python.h" | 
 | 6 | #include "modsupport.h" | 
 | 7 | #include "structmember.h" | 
 | 8 |  | 
 | 9 | #include <time.h> | 
 | 10 |  | 
 | 11 | #include "datetime.h" | 
 | 12 |  | 
 | 13 | /* We require that C int be at least 32 bits, and use int virtually | 
 | 14 |  * everywhere.  In just a few cases we use a temp long, where a Python | 
 | 15 |  * API returns a C long.  In such cases, we have to ensure that the | 
 | 16 |  * final result fits in a C int (this can be an issue on 64-bit boxes). | 
 | 17 |  */ | 
 | 18 | #if SIZEOF_INT < 4 | 
 | 19 | #	error "datetime.c requires that C int have at least 32 bits" | 
 | 20 | #endif | 
 | 21 |  | 
 | 22 | #define MINYEAR 1 | 
 | 23 | #define MAXYEAR 9999 | 
 | 24 |  | 
 | 25 | /* Nine decimal digits is easy to communicate, and leaves enough room | 
 | 26 |  * so that two delta days can be added w/o fear of overflowing a signed | 
 | 27 |  * 32-bit int, and with plenty of room left over to absorb any possible | 
 | 28 |  * carries from adding seconds. | 
 | 29 |  */ | 
 | 30 | #define MAX_DELTA_DAYS 999999999 | 
 | 31 |  | 
 | 32 | /* Rename the long macros in datetime.h to more reasonable short names. */ | 
 | 33 | #define GET_YEAR		PyDateTime_GET_YEAR | 
 | 34 | #define GET_MONTH		PyDateTime_GET_MONTH | 
 | 35 | #define GET_DAY			PyDateTime_GET_DAY | 
 | 36 | #define DATE_GET_HOUR		PyDateTime_DATE_GET_HOUR | 
 | 37 | #define DATE_GET_MINUTE		PyDateTime_DATE_GET_MINUTE | 
 | 38 | #define DATE_GET_SECOND		PyDateTime_DATE_GET_SECOND | 
 | 39 | #define DATE_GET_MICROSECOND	PyDateTime_DATE_GET_MICROSECOND | 
 | 40 |  | 
 | 41 | /* Date accessors for date and datetime. */ | 
 | 42 | #define SET_YEAR(o, v)		(((o)->data[0] = ((v) & 0xff00) >> 8), \ | 
 | 43 |                                  ((o)->data[1] = ((v) & 0x00ff))) | 
 | 44 | #define SET_MONTH(o, v)		(PyDateTime_GET_MONTH(o) = (v)) | 
 | 45 | #define SET_DAY(o, v)		(PyDateTime_GET_DAY(o) = (v)) | 
 | 46 |  | 
 | 47 | /* Date/Time accessors for datetime. */ | 
 | 48 | #define DATE_SET_HOUR(o, v)	(PyDateTime_DATE_GET_HOUR(o) = (v)) | 
 | 49 | #define DATE_SET_MINUTE(o, v)	(PyDateTime_DATE_GET_MINUTE(o) = (v)) | 
 | 50 | #define DATE_SET_SECOND(o, v)	(PyDateTime_DATE_GET_SECOND(o) = (v)) | 
 | 51 | #define DATE_SET_MICROSECOND(o, v)	\ | 
 | 52 | 	(((o)->data[7] = ((v) & 0xff0000) >> 16), \ | 
 | 53 |          ((o)->data[8] = ((v) & 0x00ff00) >> 8), \ | 
 | 54 |          ((o)->data[9] = ((v) & 0x0000ff))) | 
 | 55 |  | 
 | 56 | /* Time accessors for time. */ | 
 | 57 | #define TIME_GET_HOUR		PyDateTime_TIME_GET_HOUR | 
 | 58 | #define TIME_GET_MINUTE		PyDateTime_TIME_GET_MINUTE | 
 | 59 | #define TIME_GET_SECOND		PyDateTime_TIME_GET_SECOND | 
 | 60 | #define TIME_GET_MICROSECOND	PyDateTime_TIME_GET_MICROSECOND | 
 | 61 | #define TIME_SET_HOUR(o, v)	(PyDateTime_TIME_GET_HOUR(o) = (v)) | 
 | 62 | #define TIME_SET_MINUTE(o, v)	(PyDateTime_TIME_GET_MINUTE(o) = (v)) | 
 | 63 | #define TIME_SET_SECOND(o, v)	(PyDateTime_TIME_GET_SECOND(o) = (v)) | 
 | 64 | #define TIME_SET_MICROSECOND(o, v)	\ | 
 | 65 | 	(((o)->data[3] = ((v) & 0xff0000) >> 16), \ | 
 | 66 |          ((o)->data[4] = ((v) & 0x00ff00) >> 8), \ | 
 | 67 |          ((o)->data[5] = ((v) & 0x0000ff))) | 
 | 68 |  | 
 | 69 | /* Delta accessors for timedelta. */ | 
 | 70 | #define GET_TD_DAYS(o)		(((PyDateTime_Delta *)(o))->days) | 
 | 71 | #define GET_TD_SECONDS(o)	(((PyDateTime_Delta *)(o))->seconds) | 
 | 72 | #define GET_TD_MICROSECONDS(o)	(((PyDateTime_Delta *)(o))->microseconds) | 
 | 73 |  | 
 | 74 | #define SET_TD_DAYS(o, v)	((o)->days = (v)) | 
 | 75 | #define SET_TD_SECONDS(o, v)	((o)->seconds = (v)) | 
 | 76 | #define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v)) | 
 | 77 |  | 
 | 78 | /* Forward declarations. */ | 
 | 79 | static PyTypeObject PyDateTime_DateType; | 
 | 80 | static PyTypeObject PyDateTime_DateTimeType; | 
 | 81 | static PyTypeObject PyDateTime_DateTimeTZType; | 
 | 82 | static PyTypeObject PyDateTime_DeltaType; | 
 | 83 | static PyTypeObject PyDateTime_TimeType; | 
 | 84 | static PyTypeObject PyDateTime_TZInfoType; | 
 | 85 | static PyTypeObject PyDateTime_TimeTZType; | 
 | 86 |  | 
 | 87 | /* --------------------------------------------------------------------------- | 
 | 88 |  * Math utilities. | 
 | 89 |  */ | 
 | 90 |  | 
 | 91 | /* k = i+j overflows iff k differs in sign from both inputs, | 
 | 92 |  * iff k^i has sign bit set and k^j has sign bit set, | 
 | 93 |  * iff (k^i)&(k^j) has sign bit set. | 
 | 94 |  */ | 
 | 95 | #define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \ | 
 | 96 | 	((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0) | 
 | 97 |  | 
 | 98 | /* Compute Python divmod(x, y), returning the quotient and storing the | 
 | 99 |  * remainder into *r.  The quotient is the floor of x/y, and that's | 
 | 100 |  * the real point of this.  C will probably truncate instead (C99 | 
 | 101 |  * requires truncation; C89 left it implementation-defined). | 
 | 102 |  * Simplification:  we *require* that y > 0 here.  That's appropriate | 
 | 103 |  * for all the uses made of it.  This simplifies the code and makes | 
 | 104 |  * the overflow case impossible (divmod(LONG_MIN, -1) is the only | 
 | 105 |  * overflow case). | 
 | 106 |  */ | 
 | 107 | static int | 
 | 108 | divmod(int x, int y, int *r) | 
 | 109 | { | 
 | 110 | 	int quo; | 
 | 111 |  | 
 | 112 | 	assert(y > 0); | 
 | 113 | 	quo = x / y; | 
 | 114 | 	*r = x - quo * y; | 
 | 115 | 	if (*r < 0) { | 
 | 116 | 		--quo; | 
 | 117 | 		*r += y; | 
 | 118 | 	} | 
 | 119 | 	assert(0 <= *r && *r < y); | 
 | 120 | 	return quo; | 
 | 121 | } | 
 | 122 |  | 
 | 123 | /* --------------------------------------------------------------------------- | 
 | 124 |  * General calendrical helper functions | 
 | 125 |  */ | 
 | 126 |  | 
 | 127 | /* For each month ordinal in 1..12, the number of days in that month, | 
 | 128 |  * and the number of days before that month in the same year.  These | 
 | 129 |  * are correct for non-leap years only. | 
 | 130 |  */ | 
 | 131 | static int _days_in_month[] = { | 
 | 132 | 	0, /* unused; this vector uses 1-based indexing */ | 
 | 133 | 	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 | 
 | 134 | }; | 
 | 135 |  | 
 | 136 | static int _days_before_month[] = { | 
 | 137 | 	0, /* unused; this vector uses 1-based indexing */ | 
 | 138 | 	0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 | 
 | 139 | }; | 
 | 140 |  | 
 | 141 | /* year -> 1 if leap year, else 0. */ | 
 | 142 | static int | 
 | 143 | is_leap(int year) | 
 | 144 | { | 
 | 145 | 	/* Cast year to unsigned.  The result is the same either way, but | 
 | 146 | 	 * C can generate faster code for unsigned mod than for signed | 
 | 147 | 	 * mod (especially for % 4 -- a good compiler should just grab | 
 | 148 | 	 * the last 2 bits when the LHS is unsigned). | 
 | 149 | 	 */ | 
 | 150 | 	const unsigned int ayear = (unsigned int)year; | 
 | 151 | 	return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0); | 
 | 152 | } | 
 | 153 |  | 
 | 154 | /* year, month -> number of days in that month in that year */ | 
 | 155 | static int | 
 | 156 | days_in_month(int year, int month) | 
 | 157 | { | 
 | 158 | 	assert(month >= 1); | 
 | 159 | 	assert(month <= 12); | 
 | 160 | 	if (month == 2 && is_leap(year)) | 
 | 161 | 		return 29; | 
 | 162 | 	else | 
 | 163 | 		return _days_in_month[month]; | 
 | 164 | } | 
 | 165 |  | 
 | 166 | /* year, month -> number of days in year preceeding first day of month */ | 
 | 167 | static int | 
 | 168 | days_before_month(int year, int month) | 
 | 169 | { | 
 | 170 | 	int days; | 
 | 171 |  | 
 | 172 | 	assert(month >= 1); | 
 | 173 | 	assert(month <= 12); | 
 | 174 | 	days = _days_before_month[month]; | 
 | 175 | 	if (month > 2 && is_leap(year)) | 
 | 176 | 		++days; | 
 | 177 | 	return days; | 
 | 178 | } | 
 | 179 |  | 
 | 180 | /* year -> number of days before January 1st of year.  Remember that we | 
 | 181 |  * start with year 1, so days_before_year(1) == 0. | 
 | 182 |  */ | 
 | 183 | static int | 
 | 184 | days_before_year(int year) | 
 | 185 | { | 
 | 186 | 	int y = year - 1; | 
 | 187 | 	/* This is incorrect if year <= 0; we really want the floor | 
 | 188 | 	 * here.  But so long as MINYEAR is 1, the smallest year this | 
 | 189 | 	 * can see is 0 (this can happen in some normalization endcases), | 
 | 190 | 	 * so we'll just special-case that. | 
 | 191 | 	 */ | 
 | 192 | 	assert (year >= 0); | 
 | 193 | 	if (y >= 0) | 
 | 194 | 		return y*365 + y/4 - y/100 + y/400; | 
 | 195 | 	else { | 
 | 196 | 		assert(y == -1); | 
 | 197 | 		return -366; | 
 | 198 | 	} | 
 | 199 | } | 
 | 200 |  | 
 | 201 | /* Number of days in 4, 100, and 400 year cycles.  That these have | 
 | 202 |  * the correct values is asserted in the module init function. | 
 | 203 |  */ | 
 | 204 | #define DI4Y	1461	/* days_before_year(5); days in 4 years */ | 
 | 205 | #define DI100Y	36524	/* days_before_year(101); days in 100 years */ | 
 | 206 | #define DI400Y	146097	/* days_before_year(401); days in 400 years  */ | 
 | 207 |  | 
 | 208 | /* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */ | 
 | 209 | static void | 
 | 210 | ord_to_ymd(int ordinal, int *year, int *month, int *day) | 
 | 211 | { | 
 | 212 | 	int n, n1, n4, n100, n400, leapyear, preceding; | 
 | 213 |  | 
 | 214 | 	/* ordinal is a 1-based index, starting at 1-Jan-1.  The pattern of | 
 | 215 | 	 * leap years repeats exactly every 400 years.  The basic strategy is | 
 | 216 | 	 * to find the closest 400-year boundary at or before ordinal, then | 
 | 217 | 	 * work with the offset from that boundary to ordinal.  Life is much | 
 | 218 | 	 * clearer if we subtract 1 from ordinal first -- then the values | 
 | 219 | 	 * of ordinal at 400-year boundaries are exactly those divisible | 
 | 220 | 	 * by DI400Y: | 
 | 221 | 	 * | 
 | 222 | 	 *    D  M   Y            n              n-1 | 
 | 223 | 	 *    -- --- ----        ----------     ---------------- | 
 | 224 | 	 *    31 Dec -400        -DI400Y       -DI400Y -1 | 
 | 225 | 	 *     1 Jan -399         -DI400Y +1   -DI400Y      400-year boundary | 
 | 226 | 	 *    ... | 
 | 227 | 	 *    30 Dec  000        -1             -2 | 
 | 228 | 	 *    31 Dec  000         0             -1 | 
 | 229 | 	 *     1 Jan  001         1              0          400-year boundary | 
 | 230 | 	 *     2 Jan  001         2              1 | 
 | 231 | 	 *     3 Jan  001         3              2 | 
 | 232 | 	 *    ... | 
 | 233 | 	 *    31 Dec  400         DI400Y        DI400Y -1 | 
 | 234 | 	 *     1 Jan  401         DI400Y +1     DI400Y      400-year boundary | 
 | 235 | 	 */ | 
 | 236 | 	assert(ordinal >= 1); | 
 | 237 | 	--ordinal; | 
 | 238 | 	n400 = ordinal / DI400Y; | 
 | 239 | 	n = ordinal % DI400Y; | 
 | 240 | 	*year = n400 * 400 + 1; | 
 | 241 |  | 
 | 242 | 	/* Now n is the (non-negative) offset, in days, from January 1 of | 
 | 243 | 	 * year, to the desired date.  Now compute how many 100-year cycles | 
 | 244 | 	 * precede n. | 
 | 245 | 	 * Note that it's possible for n100 to equal 4!  In that case 4 full | 
 | 246 | 	 * 100-year cycles precede the desired day, which implies the | 
 | 247 | 	 * desired day is December 31 at the end of a 400-year cycle. | 
 | 248 | 	 */ | 
 | 249 | 	n100 = n / DI100Y; | 
 | 250 | 	n = n % DI100Y; | 
 | 251 |  | 
 | 252 | 	/* Now compute how many 4-year cycles precede it. */ | 
 | 253 | 	n4 = n / DI4Y; | 
 | 254 | 	n = n % DI4Y; | 
 | 255 |  | 
 | 256 | 	/* And now how many single years.  Again n1 can be 4, and again | 
 | 257 | 	 * meaning that the desired day is December 31 at the end of the | 
 | 258 | 	 * 4-year cycle. | 
 | 259 | 	 */ | 
 | 260 | 	n1 = n / 365; | 
 | 261 | 	n = n % 365; | 
 | 262 |  | 
 | 263 | 	*year += n100 * 100 + n4 * 4 + n1; | 
 | 264 | 	if (n1 == 4 || n100 == 4) { | 
 | 265 | 		assert(n == 0); | 
 | 266 | 		*year -= 1; | 
 | 267 | 		*month = 12; | 
 | 268 | 		*day = 31; | 
 | 269 | 		return; | 
 | 270 | 	} | 
 | 271 |  | 
 | 272 | 	/* Now the year is correct, and n is the offset from January 1.  We | 
 | 273 | 	 * find the month via an estimate that's either exact or one too | 
 | 274 | 	 * large. | 
 | 275 | 	 */ | 
 | 276 | 	leapyear = n1 == 3 && (n4 != 24 || n100 == 3); | 
 | 277 | 	assert(leapyear == is_leap(*year)); | 
 | 278 | 	*month = (n + 50) >> 5; | 
 | 279 | 	preceding = (_days_before_month[*month] + (*month > 2 && leapyear)); | 
 | 280 | 	if (preceding > n) { | 
 | 281 | 		/* estimate is too large */ | 
 | 282 | 		*month -= 1; | 
 | 283 | 		preceding -= days_in_month(*year, *month); | 
 | 284 | 	} | 
 | 285 | 	n -= preceding; | 
 | 286 | 	assert(0 <= n); | 
 | 287 | 	assert(n < days_in_month(*year, *month)); | 
 | 288 |  | 
 | 289 | 	*day = n + 1; | 
 | 290 | } | 
 | 291 |  | 
 | 292 | /* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */ | 
 | 293 | static int | 
 | 294 | ymd_to_ord(int year, int month, int day) | 
 | 295 | { | 
 | 296 | 	return days_before_year(year) + days_before_month(year, month) + day; | 
 | 297 | } | 
 | 298 |  | 
 | 299 | /* Day of week, where Monday==0, ..., Sunday==6.  1/1/1 was a Monday. */ | 
 | 300 | static int | 
 | 301 | weekday(int year, int month, int day) | 
 | 302 | { | 
 | 303 | 	return (ymd_to_ord(year, month, day) + 6) % 7; | 
 | 304 | } | 
 | 305 |  | 
 | 306 | /* Ordinal of the Monday starting week 1 of the ISO year.  Week 1 is the | 
 | 307 |  * first calendar week containing a Thursday. | 
 | 308 |  */ | 
 | 309 | static int | 
 | 310 | iso_week1_monday(int year) | 
 | 311 | { | 
 | 312 | 	int first_day = ymd_to_ord(year, 1, 1);	/* ord of 1/1 */ | 
 | 313 | 	/* 0 if 1/1 is a Monday, 1 if a Tue, etc. */ | 
 | 314 | 	int first_weekday = (first_day + 6) % 7; | 
 | 315 | 	/* ordinal of closest Monday at or before 1/1 */ | 
 | 316 | 	int week1_monday  = first_day - first_weekday; | 
 | 317 |  | 
 | 318 | 	if (first_weekday > 3)	/* if 1/1 was Fri, Sat, Sun */ | 
 | 319 | 		week1_monday += 7; | 
 | 320 | 	return week1_monday; | 
 | 321 | } | 
 | 322 |  | 
 | 323 | /* --------------------------------------------------------------------------- | 
 | 324 |  * Range checkers. | 
 | 325 |  */ | 
 | 326 |  | 
 | 327 | /* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS.  If so, return 0. | 
 | 328 |  * If not, raise OverflowError and return -1. | 
 | 329 |  */ | 
 | 330 | static int | 
 | 331 | check_delta_day_range(int days) | 
 | 332 | { | 
 | 333 | 	if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS) | 
 | 334 | 		return 0; | 
 | 335 | 	PyErr_Format(PyExc_OverflowError, | 
 | 336 | 		     "days=%d; must have magnitude <= %d", | 
| Guido van Rossum | bd43e91 | 2002-12-16 20:34:55 +0000 | [diff] [blame] | 337 | 		     days, MAX_DELTA_DAYS); | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 338 | 	return -1; | 
 | 339 | } | 
 | 340 |  | 
 | 341 | /* Check that date arguments are in range.  Return 0 if they are.  If they | 
 | 342 |  * aren't, raise ValueError and return -1. | 
 | 343 |  */ | 
 | 344 | static int | 
 | 345 | check_date_args(int year, int month, int day) | 
 | 346 | { | 
 | 347 |  | 
 | 348 | 	if (year < MINYEAR || year > MAXYEAR) { | 
 | 349 | 		PyErr_SetString(PyExc_ValueError, | 
 | 350 | 				"year is out of range"); | 
 | 351 | 		return -1; | 
 | 352 | 	} | 
 | 353 | 	if (month < 1 || month > 12) { | 
 | 354 | 		PyErr_SetString(PyExc_ValueError, | 
 | 355 | 				"month must be in 1..12"); | 
 | 356 | 		return -1; | 
 | 357 | 	} | 
 | 358 | 	if (day < 1 || day > days_in_month(year, month)) { | 
 | 359 | 		PyErr_SetString(PyExc_ValueError, | 
 | 360 | 				"day is out of range for month"); | 
 | 361 | 		return -1; | 
 | 362 | 	} | 
 | 363 | 	return 0; | 
 | 364 | } | 
 | 365 |  | 
 | 366 | /* Check that time arguments are in range.  Return 0 if they are.  If they | 
 | 367 |  * aren't, raise ValueError and return -1. | 
 | 368 |  */ | 
 | 369 | static int | 
 | 370 | check_time_args(int h, int m, int s, int us) | 
 | 371 | { | 
 | 372 | 	if (h < 0 || h > 23) { | 
 | 373 | 		PyErr_SetString(PyExc_ValueError, | 
 | 374 | 				"hour must be in 0..23"); | 
 | 375 | 		return -1; | 
 | 376 | 	} | 
 | 377 | 	if (m < 0 || m > 59) { | 
 | 378 | 		PyErr_SetString(PyExc_ValueError, | 
 | 379 | 				"minute must be in 0..59"); | 
 | 380 | 		return -1; | 
 | 381 | 	} | 
 | 382 | 	if (s < 0 || s > 59) { | 
 | 383 | 		PyErr_SetString(PyExc_ValueError, | 
 | 384 | 				"second must be in 0..59"); | 
 | 385 | 		return -1; | 
 | 386 | 	} | 
 | 387 | 	if (us < 0 || us > 999999) { | 
 | 388 | 		PyErr_SetString(PyExc_ValueError, | 
 | 389 | 				"microsecond must be in 0..999999"); | 
 | 390 | 		return -1; | 
 | 391 | 	} | 
 | 392 | 	return 0; | 
 | 393 | } | 
 | 394 |  | 
 | 395 | /* --------------------------------------------------------------------------- | 
 | 396 |  * Normalization utilities. | 
 | 397 |  */ | 
 | 398 |  | 
 | 399 | /* One step of a mixed-radix conversion.  A "hi" unit is equivalent to | 
 | 400 |  * factor "lo" units.  factor must be > 0.  If *lo is less than 0, or | 
 | 401 |  * at least factor, enough of *lo is converted into "hi" units so that | 
 | 402 |  * 0 <= *lo < factor.  The input values must be such that int overflow | 
 | 403 |  * is impossible. | 
 | 404 |  */ | 
 | 405 | static void | 
 | 406 | normalize_pair(int *hi, int *lo, int factor) | 
 | 407 | { | 
 | 408 | 	assert(factor > 0); | 
 | 409 | 	assert(lo != hi); | 
 | 410 | 	if (*lo < 0 || *lo >= factor) { | 
 | 411 | 		const int num_hi = divmod(*lo, factor, lo); | 
 | 412 | 		const int new_hi = *hi + num_hi; | 
 | 413 | 		assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi)); | 
 | 414 | 		*hi = new_hi; | 
 | 415 | 	} | 
 | 416 | 	assert(0 <= *lo && *lo < factor); | 
 | 417 | } | 
 | 418 |  | 
 | 419 | /* Fiddle days (d), seconds (s), and microseconds (us) so that | 
 | 420 |  * 	0 <= *s < 24*3600 | 
 | 421 |  * 	0 <= *us < 1000000 | 
 | 422 |  * The input values must be such that the internals don't overflow. | 
 | 423 |  * The way this routine is used, we don't get close. | 
 | 424 |  */ | 
 | 425 | static void | 
 | 426 | normalize_d_s_us(int *d, int *s, int *us) | 
 | 427 | { | 
 | 428 | 	if (*us < 0 || *us >= 1000000) { | 
 | 429 | 		normalize_pair(s, us, 1000000); | 
 | 430 | 		/* |s| can't be bigger than about | 
 | 431 | 		 * |original s| + |original us|/1000000 now. | 
 | 432 | 		 */ | 
 | 433 |  | 
 | 434 | 	} | 
 | 435 | 	if (*s < 0 || *s >= 24*3600) { | 
 | 436 | 		normalize_pair(d, s, 24*3600); | 
 | 437 | 		/* |d| can't be bigger than about | 
 | 438 | 		 * |original d| + | 
 | 439 | 		 * (|original s| + |original us|/1000000) / (24*3600) now. | 
 | 440 | 		 */ | 
 | 441 | 	} | 
 | 442 | 	assert(0 <= *s && *s < 24*3600); | 
 | 443 | 	assert(0 <= *us && *us < 1000000); | 
 | 444 | } | 
 | 445 |  | 
 | 446 | /* Fiddle years (y), months (m), and days (d) so that | 
 | 447 |  * 	1 <= *m <= 12 | 
 | 448 |  * 	1 <= *d <= days_in_month(*y, *m) | 
 | 449 |  * The input values must be such that the internals don't overflow. | 
 | 450 |  * The way this routine is used, we don't get close. | 
 | 451 |  */ | 
 | 452 | static void | 
 | 453 | normalize_y_m_d(int *y, int *m, int *d) | 
 | 454 | { | 
 | 455 | 	int dim;	/* # of days in month */ | 
 | 456 |  | 
 | 457 | 	/* This gets muddy:  the proper range for day can't be determined | 
 | 458 | 	 * without knowing the correct month and year, but if day is, e.g., | 
 | 459 | 	 * plus or minus a million, the current month and year values make | 
 | 460 | 	 * no sense (and may also be out of bounds themselves). | 
 | 461 | 	 * Saying 12 months == 1 year should be non-controversial. | 
 | 462 | 	 */ | 
 | 463 | 	if (*m < 1 || *m > 12) { | 
 | 464 | 		--*m; | 
 | 465 | 		normalize_pair(y, m, 12); | 
 | 466 | 		++*m; | 
 | 467 | 		/* |y| can't be bigger than about | 
 | 468 | 		 * |original y| + |original m|/12 now. | 
 | 469 | 		 */ | 
 | 470 | 	} | 
 | 471 | 	assert(1 <= *m && *m <= 12); | 
 | 472 |  | 
 | 473 | 	/* Now only day can be out of bounds (year may also be out of bounds | 
 | 474 | 	 * for a datetime object, but we don't care about that here). | 
 | 475 | 	 * If day is out of bounds, what to do is arguable, but at least the | 
 | 476 | 	 * method here is principled and explainable. | 
 | 477 | 	 */ | 
 | 478 | 	dim = days_in_month(*y, *m); | 
 | 479 | 	if (*d < 1 || *d > dim) { | 
 | 480 | 		/* Move day-1 days from the first of the month.  First try to | 
 | 481 | 		 * get off cheap if we're only one day out of range | 
 | 482 | 		 * (adjustments for timezone alone can't be worse than that). | 
 | 483 | 		 */ | 
 | 484 | 		if (*d == 0) { | 
 | 485 | 			--*m; | 
 | 486 | 			if (*m > 0) | 
 | 487 | 				*d = days_in_month(*y, *m); | 
 | 488 | 			else { | 
 | 489 | 				--*y; | 
 | 490 | 				*m = 12; | 
 | 491 | 				*d = 31; | 
 | 492 | 			} | 
 | 493 | 		} | 
 | 494 | 		else if (*d == dim + 1) { | 
 | 495 | 			/* move forward a day */ | 
 | 496 | 			++*m; | 
 | 497 | 			*d = 1; | 
 | 498 | 			if (*m > 12) { | 
 | 499 | 				*m = 1; | 
 | 500 | 				++*y; | 
 | 501 | 			} | 
 | 502 | 		} | 
 | 503 | 		else { | 
 | 504 | 			int ordinal = ymd_to_ord(*y, *m, 1) + | 
 | 505 | 						  *d - 1; | 
 | 506 | 			ord_to_ymd(ordinal, y, m, d); | 
 | 507 | 		} | 
 | 508 | 	} | 
 | 509 | 	assert(*m > 0); | 
 | 510 | 	assert(*d > 0); | 
 | 511 | } | 
 | 512 |  | 
 | 513 | /* Fiddle out-of-bounds months and days so that the result makes some kind | 
 | 514 |  * of sense.  The parameters are both inputs and outputs.  Returns < 0 on | 
 | 515 |  * failure, where failure means the adjusted year is out of bounds. | 
 | 516 |  */ | 
 | 517 | static int | 
 | 518 | normalize_date(int *year, int *month, int *day) | 
 | 519 | { | 
 | 520 | 	int result; | 
 | 521 |  | 
 | 522 | 	normalize_y_m_d(year, month, day); | 
 | 523 | 	if (MINYEAR <= *year && *year <= MAXYEAR) | 
 | 524 | 		result = 0; | 
 | 525 | 	else { | 
 | 526 | 		PyErr_SetString(PyExc_OverflowError, | 
 | 527 | 				"date value out of range"); | 
 | 528 | 		result = -1; | 
 | 529 | 	} | 
 | 530 | 	return result; | 
 | 531 | } | 
 | 532 |  | 
 | 533 | /* Force all the datetime fields into range.  The parameters are both | 
 | 534 |  * inputs and outputs.  Returns < 0 on error. | 
 | 535 |  */ | 
 | 536 | static int | 
 | 537 | normalize_datetime(int *year, int *month, int *day, | 
 | 538 |                    int *hour, int *minute, int *second, | 
 | 539 |                    int *microsecond) | 
 | 540 | { | 
 | 541 | 	normalize_pair(second, microsecond, 1000000); | 
 | 542 | 	normalize_pair(minute, second, 60); | 
 | 543 | 	normalize_pair(hour, minute, 60); | 
 | 544 | 	normalize_pair(day, hour, 24); | 
 | 545 | 	return normalize_date(year, month, day); | 
 | 546 | } | 
 | 547 |  | 
 | 548 | /* --------------------------------------------------------------------------- | 
 | 549 |  * tzinfo helpers. | 
 | 550 |  */ | 
 | 551 |  | 
 | 552 | /* If self has a tzinfo member, return a BORROWED reference to it.  Else | 
 | 553 |  * return NULL, which is NOT AN ERROR.  There are no error returns here, | 
 | 554 |  * and the caller must not decref the result. | 
 | 555 |  */ | 
 | 556 | static PyObject * | 
 | 557 | get_tzinfo_member(PyObject *self) | 
 | 558 | { | 
 | 559 | 	PyObject *tzinfo = NULL; | 
 | 560 |  | 
 | 561 | 	if (PyDateTimeTZ_Check(self)) | 
 | 562 | 		tzinfo = ((PyDateTime_DateTimeTZ *)self)->tzinfo; | 
 | 563 | 	else if (PyTimeTZ_Check(self)) | 
 | 564 | 		tzinfo = ((PyDateTime_TimeTZ *)self)->tzinfo; | 
 | 565 |  | 
 | 566 | 	return tzinfo; | 
 | 567 | } | 
 | 568 |  | 
 | 569 | /* Ensure that p is None or of a tzinfo subclass.  Return 0 if OK; if not | 
 | 570 |  * raise TypeError and return -1. | 
 | 571 |  */ | 
 | 572 | static int | 
 | 573 | check_tzinfo_subclass(PyObject *p) | 
 | 574 | { | 
 | 575 | 	if (p == Py_None || PyTZInfo_Check(p)) | 
 | 576 | 		return 0; | 
 | 577 | 	PyErr_Format(PyExc_TypeError, | 
 | 578 | 		     "tzinfo argument must be None or of a tzinfo subclass, " | 
 | 579 | 		     "not type '%s'", | 
 | 580 | 		     p->ob_type->tp_name); | 
 | 581 | 	return -1; | 
 | 582 | } | 
 | 583 |  | 
 | 584 | /* Internal helper. | 
 | 585 |  * Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the | 
 | 586 |  * result.  tzinfo must be an instance of the tzinfo class.  If the method | 
 | 587 |  * returns None, this returns 0 and sets *none to 1.  If the method doesn't | 
 | 588 |  * return a Python int or long, TypeError is raised and this returns -1. | 
 | 589 |  * If it does return an int or long, but is outside the valid range for | 
 | 590 |  * a UTC minute offset, ValueError is raised and this returns -1. | 
 | 591 |  * Else *none is set to 0 and the integer method result is returned. | 
 | 592 |  */ | 
 | 593 | static int | 
 | 594 | call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg, | 
 | 595 | 		       int *none) | 
 | 596 | { | 
 | 597 | 	PyObject *u; | 
 | 598 | 	long result = -1;	/* Py{Int,Long}_AsLong return long */ | 
 | 599 |  | 
 | 600 | 	assert(tzinfo != NULL); | 
 | 601 | 	assert(PyTZInfo_Check(tzinfo)); | 
 | 602 | 	assert(tzinfoarg != NULL); | 
 | 603 |  | 
 | 604 | 	*none = 0; | 
 | 605 | 	u = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg); | 
 | 606 | 	if (u == NULL) | 
 | 607 | 		return -1; | 
 | 608 |  | 
 | 609 | 	if (u == Py_None) { | 
 | 610 | 		result = 0; | 
 | 611 | 		*none = 1; | 
 | 612 | 		goto Done; | 
 | 613 | 	} | 
 | 614 |  | 
 | 615 | 	if (PyInt_Check(u)) | 
 | 616 | 		result = PyInt_AS_LONG(u); | 
 | 617 | 	else if (PyLong_Check(u)) | 
 | 618 | 		result = PyLong_AsLong(u); | 
 | 619 | 	else { | 
 | 620 | 		PyErr_Format(PyExc_TypeError, | 
 | 621 | 			     "tzinfo.%s() must return None or int or long", | 
 | 622 | 			     name); | 
 | 623 | 		goto Done; | 
 | 624 | 	} | 
 | 625 |  | 
 | 626 | Done: | 
 | 627 | 	Py_DECREF(u); | 
 | 628 | 	if (result < -1439 || result > 1439) { | 
 | 629 | 		PyErr_Format(PyExc_ValueError, | 
 | 630 | 			     "tzinfo.%s() returned %ld; must be in " | 
 | 631 | 			     "-1439 .. 1439", | 
 | 632 | 			     name, result); | 
 | 633 | 		result = -1; | 
 | 634 | 	} | 
 | 635 | 	return (int)result; | 
 | 636 | } | 
 | 637 |  | 
 | 638 | /* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the | 
 | 639 |  * result.  tzinfo must be an instance of the tzinfo class.  If utcoffset() | 
 | 640 |  * returns None, call_utcoffset returns 0 and sets *none to 1.  If uctoffset() | 
 | 641 |  & doesn't return a Python int or long, TypeError is raised and this | 
 | 642 |  * returns -1.  If utcoffset() returns an int outside the legitimate range | 
 | 643 |  * for a UTC offset, ValueError is raised and this returns -1.  Else | 
 | 644 |  * *none is set to 0 and the offset is returned. | 
 | 645 |  */ | 
 | 646 | static int | 
 | 647 | call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none) | 
 | 648 | { | 
 | 649 | 	return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none); | 
 | 650 | } | 
 | 651 |  | 
 | 652 | /* Call tzinfo.dst(tzinfoarg), and extract an integer from the | 
 | 653 |  * result.  tzinfo must be an instance of the tzinfo class.  If dst() | 
 | 654 |  * returns None, call_dst returns 0 and sets *none to 1.  If dst() | 
 | 655 |  & doesn't return a Python int or long, TypeError is raised and this | 
 | 656 |  * returns -1.  If dst() returns an int outside the legitimate range | 
 | 657 |  * for a UTC offset, ValueError is raised and this returns -1.  Else | 
 | 658 |  * *none is set to 0 and the offset is returned. | 
 | 659 |  */ | 
 | 660 | static int | 
 | 661 | call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none) | 
 | 662 | { | 
 | 663 | 	return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none); | 
 | 664 | } | 
 | 665 |  | 
 | 666 | /* Call tzinfo.tzname(tzinfoarg), and return the result.  tzinfo must be | 
 | 667 |  * an instance of the tzinfo class.  If tzname() doesn't return None or | 
 | 668 |  * a string, TypeError is raised and this returns NULL. | 
 | 669 |  */ | 
 | 670 | static PyObject * | 
 | 671 | call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) | 
 | 672 | { | 
 | 673 | 	PyObject *result; | 
 | 674 |  | 
 | 675 | 	assert(tzinfo != NULL); | 
 | 676 | 	assert(PyTZInfo_Check(tzinfo)); | 
 | 677 | 	assert(tzinfoarg != NULL); | 
 | 678 |  | 
 | 679 | 	result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg); | 
 | 680 | 	if (result != NULL && result != Py_None && !PyString_Check(result)) { | 
 | 681 | 		PyErr_Format(PyExc_TypeError, ".tzinfo.tzname() must " | 
 | 682 | 			     "return None or a string, not '%s'", | 
 | 683 | 			     result->ob_type->tp_name); | 
 | 684 | 		Py_DECREF(result); | 
 | 685 | 		result = NULL; | 
 | 686 | 	} | 
 | 687 | 	return result; | 
 | 688 | } | 
 | 689 |  | 
 | 690 | typedef enum { | 
 | 691 | 	      /* an exception has been set; the caller should pass it on */ | 
 | 692 | 	      OFFSET_ERROR, | 
 | 693 |  | 
 | 694 | 	      /* type isn't date, datetime, datetimetz subclass, time, or | 
 | 695 | 	       * timetz subclass | 
 | 696 | 	       */ | 
 | 697 | 	      OFFSET_UNKNOWN, | 
 | 698 |  | 
 | 699 | 	      /* date, | 
 | 700 | 	       * datetime, | 
 | 701 | 	       * datetimetz with None tzinfo, | 
 | 702 | 	       * datetimetz where utcoffset() return None | 
 | 703 | 	       * time, | 
 | 704 | 	       * timetz with None tzinfo, | 
 | 705 | 	       * timetz where utcoffset() returns None | 
 | 706 | 	       */ | 
 | 707 | 	      OFFSET_NAIVE, | 
 | 708 |  | 
 | 709 | 	      /* timetz where utcoffset() doesn't return None, | 
 | 710 | 	       * datetimetz where utcoffset() doesn't return None | 
 | 711 | 	       */ | 
 | 712 | 	      OFFSET_AWARE, | 
 | 713 | } naivety; | 
 | 714 |  | 
 | 715 | /* Classify a datetime object as to whether it's naive or offset-aware.  See | 
 | 716 |  * the "naivety" typedef for details.  If the type is aware, *offset is set | 
 | 717 |  * to minutes east of UTC (as returned by the tzinfo.utcoffset() method). | 
 | 718 |  * If the type is offset-naive, *offset is set to 0. | 
 | 719 |  */ | 
 | 720 | static naivety | 
 | 721 | classify_object(PyObject *op, int *offset) | 
 | 722 | { | 
 | 723 | 	int none; | 
 | 724 | 	PyObject *tzinfo; | 
 | 725 |  | 
 | 726 | 	*offset = 0; | 
 | 727 | 	if (PyDateTime_CheckExact(op) || | 
 | 728 | 	    PyTime_CheckExact(op) || | 
 | 729 | 	    PyDate_CheckExact(op)) | 
 | 730 | 		return OFFSET_NAIVE; | 
 | 731 |  | 
 | 732 | 	tzinfo = get_tzinfo_member(op);	/* NULL means none, not error */ | 
 | 733 | 	if (tzinfo == Py_None) | 
 | 734 | 		return OFFSET_NAIVE; | 
 | 735 | 	if (tzinfo == NULL) | 
 | 736 | 		return OFFSET_UNKNOWN; | 
 | 737 |  | 
 | 738 | 	*offset = call_utcoffset(tzinfo, op, &none); | 
 | 739 | 	if (*offset == -1 && PyErr_Occurred()) | 
 | 740 | 		return OFFSET_ERROR; | 
 | 741 | 	return none ? OFFSET_NAIVE : OFFSET_AWARE; | 
 | 742 | } | 
 | 743 |  | 
 | 744 | /* repr is like "someclass(arg1, arg2)".  If tzinfo isn't None, | 
 | 745 |  * stuff | 
 | 746 |  *     ", tzinfo=" + repr(tzinfo) | 
 | 747 |  * before the closing ")". | 
 | 748 |  */ | 
 | 749 | static PyObject * | 
 | 750 | append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo) | 
 | 751 | { | 
 | 752 | 	PyObject *temp; | 
 | 753 |  | 
 | 754 | 	assert(PyString_Check(repr)); | 
 | 755 | 	assert(tzinfo); | 
 | 756 | 	if (tzinfo == Py_None) | 
 | 757 | 		return repr; | 
 | 758 | 	/* Get rid of the trailing ')'. */ | 
 | 759 | 	assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')'); | 
 | 760 | 	temp = PyString_FromStringAndSize(PyString_AsString(repr), | 
 | 761 | 					  PyString_Size(repr) - 1); | 
 | 762 | 	Py_DECREF(repr); | 
 | 763 | 	if (temp == NULL) | 
 | 764 | 		return NULL; | 
 | 765 | 	repr = temp; | 
 | 766 |  | 
 | 767 | 	/* Append ", tzinfo=". */ | 
 | 768 | 	PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo=")); | 
 | 769 |  | 
 | 770 | 	/* Append repr(tzinfo). */ | 
 | 771 | 	PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo)); | 
 | 772 |  | 
 | 773 | 	/* Add a closing paren. */ | 
 | 774 | 	PyString_ConcatAndDel(&repr, PyString_FromString(")")); | 
 | 775 | 	return repr; | 
 | 776 | } | 
 | 777 |  | 
 | 778 | /* --------------------------------------------------------------------------- | 
 | 779 |  * String format helpers. | 
 | 780 |  */ | 
 | 781 |  | 
 | 782 | static PyObject * | 
 | 783 | format_ctime(PyDateTime_Date *date, | 
 | 784 |              int hours, int minutes, int seconds) | 
 | 785 | { | 
 | 786 | 	static char *DayNames[] = { | 
 | 787 | 		"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" | 
 | 788 | 	}; | 
 | 789 | 	static char *MonthNames[] = { | 
 | 790 | 		"Jan", "Feb", "Mar", "Apr", "May", "Jun", | 
 | 791 | 		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" | 
 | 792 | 	}; | 
 | 793 |  | 
 | 794 | 	char buffer[128]; | 
 | 795 | 	int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date)); | 
 | 796 |  | 
 | 797 | 	PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d", | 
 | 798 | 		      DayNames[wday], MonthNames[GET_MONTH(date) - 1], | 
 | 799 | 		      GET_DAY(date), hours, minutes, seconds, | 
 | 800 | 		      GET_YEAR(date)); | 
 | 801 | 	return PyString_FromString(buffer); | 
 | 802 | } | 
 | 803 |  | 
 | 804 | /* Add an hours & minutes UTC offset string to buf.  buf has no more than | 
 | 805 |  * buflen bytes remaining.  The UTC offset is gotten by calling | 
 | 806 |  * tzinfo.uctoffset(tzinfoarg).  If that returns None, \0 is stored into | 
 | 807 |  * *buf, and that's all.  Else the returned value is checked for sanity (an | 
 | 808 |  * integer in range), and if that's OK it's converted to an hours & minutes | 
 | 809 |  * string of the form | 
 | 810 |  *   sign HH sep MM | 
 | 811 |  * Returns 0 if everything is OK.  If the return value from utcoffset() is | 
 | 812 |  * bogus, an appropriate exception is set and -1 is returned. | 
 | 813 |  */ | 
 | 814 | static int | 
 | 815 | format_utcoffset(char *buf, int buflen, const char *sep, | 
 | 816 | 		PyObject *tzinfo, PyObject *tzinfoarg) | 
 | 817 | { | 
 | 818 | 	int offset; | 
 | 819 | 	int hours; | 
 | 820 | 	int minutes; | 
 | 821 | 	char sign; | 
 | 822 | 	int none; | 
 | 823 |  | 
 | 824 | 	offset = call_utcoffset(tzinfo, tzinfoarg, &none); | 
 | 825 | 	if (offset == -1 && PyErr_Occurred()) | 
 | 826 | 		return -1; | 
 | 827 | 	if (none) { | 
 | 828 | 		*buf = '\0'; | 
 | 829 | 		return 0; | 
 | 830 | 	} | 
 | 831 | 	sign = '+'; | 
 | 832 | 	if (offset < 0) { | 
 | 833 | 		sign = '-'; | 
 | 834 | 		offset = - offset; | 
 | 835 | 	} | 
 | 836 | 	hours = divmod(offset, 60, &minutes); | 
 | 837 | 	PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes); | 
 | 838 | 	return 0; | 
 | 839 | } | 
 | 840 |  | 
 | 841 | /* I sure don't want to reproduce the strftime code from the time module, | 
 | 842 |  * so this imports the module and calls it.  All the hair is due to | 
 | 843 |  * giving special meanings to the %z and %Z format codes via a preprocessing | 
 | 844 |  * step on the format string. | 
 | 845 |  */ | 
 | 846 | static PyObject * | 
 | 847 | wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple) | 
 | 848 | { | 
 | 849 | 	PyObject *result = NULL;	/* guilty until proved innocent */ | 
 | 850 |  | 
 | 851 | 	PyObject *zreplacement = NULL;	/* py string, replacement for %z */ | 
 | 852 | 	PyObject *Zreplacement = NULL;	/* py string, replacement for %Z */ | 
 | 853 |  | 
 | 854 | 	char *pin;	/* pointer to next char in input format */ | 
 | 855 | 	char ch;	/* next char in input format */ | 
 | 856 |  | 
 | 857 | 	PyObject *newfmt = NULL;	/* py string, the output format */ | 
 | 858 | 	char *pnew;	/* pointer to available byte in output format */ | 
 | 859 | 	char totalnew;	/* number bytes total in output format buffer, | 
 | 860 | 			   exclusive of trailing \0 */ | 
 | 861 | 	char usednew;	/* number bytes used so far in output format buffer */ | 
 | 862 |  | 
 | 863 | 	char *ptoappend; /* pointer to string to append to output buffer */ | 
 | 864 | 	int ntoappend;	/* # of bytes to append to output buffer */ | 
 | 865 |  | 
 | 866 | 	char buf[100];	/* scratch buffer */ | 
 | 867 |  | 
 | 868 | 	assert(object && format && timetuple); | 
 | 869 | 	assert(PyString_Check(format)); | 
 | 870 |  | 
 | 871 | 	/* Scan the input format, looking for %z and %Z escapes, building | 
 | 872 | 	 * a new format. | 
 | 873 | 	 */ | 
 | 874 | 	totalnew = PyString_Size(format);	/* realistic if no %z/%Z */ | 
 | 875 | 	newfmt = PyString_FromStringAndSize(NULL, totalnew); | 
 | 876 | 	if (newfmt == NULL) goto Done; | 
 | 877 | 	pnew = PyString_AsString(newfmt); | 
 | 878 | 	usednew = 0; | 
 | 879 |  | 
 | 880 | 	pin = PyString_AsString(format); | 
 | 881 | 	while ((ch = *pin++) != '\0') { | 
 | 882 | 		if (ch != '%') { | 
 | 883 | 			buf[0] = ch; | 
 | 884 | 			ptoappend = buf; | 
 | 885 | 			ntoappend = 1; | 
 | 886 | 		} | 
 | 887 | 		else if ((ch = *pin++) == '\0') { | 
 | 888 | 			/* There's a lone trailing %; doesn't make sense. */ | 
 | 889 | 			PyErr_SetString(PyExc_ValueError, "strftime format " | 
 | 890 | 					"ends with raw %"); | 
 | 891 | 			goto Done; | 
 | 892 | 		} | 
 | 893 | 		/* A % has been seen and ch is the character after it. */ | 
 | 894 | 		else if (ch == 'z') { | 
 | 895 | 			if (zreplacement == NULL) { | 
 | 896 | 				/* format utcoffset */ | 
 | 897 | 				PyObject *tzinfo = get_tzinfo_member(object); | 
 | 898 | 				zreplacement = PyString_FromString(""); | 
 | 899 | 				if (zreplacement == NULL) goto Done; | 
 | 900 | 				if (tzinfo != Py_None && tzinfo != NULL) { | 
 | 901 | 					if (format_utcoffset(buf, | 
 | 902 | 							     (int)sizeof(buf), | 
 | 903 | 							     "", | 
 | 904 | 							     tzinfo, | 
 | 905 | 							     object) < 0) | 
 | 906 | 						goto Done; | 
 | 907 | 					Py_DECREF(zreplacement); | 
 | 908 | 					zreplacement = PyString_FromString(buf); | 
 | 909 | 					if (zreplacement == NULL) goto Done; | 
 | 910 | 				} | 
 | 911 | 			} | 
 | 912 | 			assert(zreplacement != NULL); | 
 | 913 | 			ptoappend = PyString_AsString(zreplacement); | 
 | 914 | 			ntoappend = PyString_Size(zreplacement); | 
 | 915 | 		} | 
 | 916 | 		else if (ch == 'Z') { | 
 | 917 | 			/* format tzname */ | 
 | 918 | 			if (Zreplacement == NULL) { | 
 | 919 | 				PyObject *tzinfo = get_tzinfo_member(object); | 
 | 920 | 				Zreplacement = PyString_FromString(""); | 
 | 921 | 				if (Zreplacement == NULL) goto Done; | 
 | 922 | 				if (tzinfo != Py_None && tzinfo != NULL) { | 
 | 923 | 					PyObject *temp = call_tzname(tzinfo, | 
 | 924 | 								     object); | 
 | 925 | 					if (temp == NULL) goto Done; | 
 | 926 | 					if (temp != Py_None) { | 
 | 927 | 						assert(PyString_Check(temp)); | 
 | 928 | 						/* Since the tzname is getting | 
 | 929 | 						 * stuffed into the format, we | 
 | 930 | 						 * have to double any % signs | 
 | 931 | 						 * so that strftime doesn't | 
 | 932 | 						 * treat them as format codes. | 
 | 933 | 						 */ | 
 | 934 | 						Py_DECREF(Zreplacement); | 
 | 935 | 						Zreplacement = PyObject_CallMethod( | 
 | 936 | 							temp, "replace", | 
 | 937 | 							"ss", "%", "%%"); | 
 | 938 | 						Py_DECREF(temp); | 
 | 939 | 						if (Zreplacement == NULL) | 
 | 940 | 							goto Done; | 
 | 941 | 					} | 
 | 942 | 					else | 
 | 943 | 						Py_DECREF(temp); | 
 | 944 | 				} | 
 | 945 | 			} | 
 | 946 | 			assert(Zreplacement != NULL); | 
 | 947 | 			ptoappend = PyString_AsString(Zreplacement); | 
 | 948 | 			ntoappend = PyString_Size(Zreplacement); | 
 | 949 | 		} | 
 | 950 | 		else { | 
 | 951 | 			buf[0] = '%'; | 
 | 952 | 			buf[1] = ch; | 
 | 953 | 			ptoappend = buf; | 
 | 954 | 			ntoappend = 2; | 
 | 955 | 		} | 
 | 956 |  | 
 | 957 |  		/* Append the ntoappend chars starting at ptoappend to | 
 | 958 |  		 * the new format. | 
 | 959 |  		 */ | 
 | 960 |  		assert(ntoappend >= 0); | 
 | 961 |  		if (ntoappend == 0) | 
 | 962 |  			continue; | 
 | 963 |  		while (usednew + ntoappend > totalnew) { | 
 | 964 |  			int bigger = totalnew << 1; | 
 | 965 |  			if ((bigger >> 1) != totalnew) { /* overflow */ | 
 | 966 |  				PyErr_NoMemory(); | 
 | 967 |  				goto Done; | 
 | 968 |  			} | 
 | 969 |  			if (_PyString_Resize(&newfmt, bigger) < 0) | 
 | 970 |  				goto Done; | 
 | 971 |  			totalnew = bigger; | 
 | 972 |  			pnew = PyString_AsString(newfmt) + usednew; | 
 | 973 |  		} | 
 | 974 | 		memcpy(pnew, ptoappend, ntoappend); | 
 | 975 | 		pnew += ntoappend; | 
 | 976 | 		usednew += ntoappend; | 
 | 977 | 		assert(usednew <= totalnew); | 
 | 978 | 	}  /* end while() */ | 
 | 979 |  | 
 | 980 | 	if (_PyString_Resize(&newfmt, usednew) < 0) | 
 | 981 | 		goto Done; | 
 | 982 | 	{ | 
 | 983 | 		PyObject *time = PyImport_ImportModule("time"); | 
 | 984 | 		if (time == NULL) | 
 | 985 | 			goto Done; | 
 | 986 | 		result = PyObject_CallMethod(time, "strftime", "OO", | 
 | 987 | 					     newfmt, timetuple); | 
 | 988 | 		Py_DECREF(time); | 
 | 989 |     	} | 
 | 990 |  Done: | 
 | 991 | 	Py_XDECREF(zreplacement); | 
 | 992 | 	Py_XDECREF(Zreplacement); | 
 | 993 | 	Py_XDECREF(newfmt); | 
 | 994 |     	return result; | 
 | 995 | } | 
 | 996 |  | 
 | 997 | static char * | 
 | 998 | isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen) | 
 | 999 | { | 
 | 1000 | 	int x; | 
 | 1001 | 	x = PyOS_snprintf(buffer, bufflen, | 
 | 1002 | 			  "%04d-%02d-%02d", | 
 | 1003 | 			  GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt)); | 
 | 1004 | 	return buffer + x; | 
 | 1005 | } | 
 | 1006 |  | 
 | 1007 | static void | 
 | 1008 | isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen) | 
 | 1009 | { | 
 | 1010 | 	int us = DATE_GET_MICROSECOND(dt); | 
 | 1011 |  | 
 | 1012 | 	PyOS_snprintf(buffer, bufflen, | 
 | 1013 | 		      "%02d:%02d:%02d",	/* 8 characters */ | 
 | 1014 | 		      DATE_GET_HOUR(dt), | 
 | 1015 | 		      DATE_GET_MINUTE(dt), | 
 | 1016 | 		      DATE_GET_SECOND(dt)); | 
 | 1017 | 	if (us) | 
 | 1018 | 		PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us); | 
 | 1019 | } | 
 | 1020 |  | 
 | 1021 | /* --------------------------------------------------------------------------- | 
 | 1022 |  * Wrap functions from the time module.  These aren't directly available | 
 | 1023 |  * from C.  Perhaps they should be. | 
 | 1024 |  */ | 
 | 1025 |  | 
 | 1026 | /* Call time.time() and return its result (a Python float). */ | 
 | 1027 | static PyObject * | 
| Guido van Rossum | bd43e91 | 2002-12-16 20:34:55 +0000 | [diff] [blame] | 1028 | time_time(void) | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 1029 | { | 
 | 1030 | 	PyObject *result = NULL; | 
 | 1031 | 	PyObject *time = PyImport_ImportModule("time"); | 
 | 1032 |  | 
 | 1033 | 	if (time != NULL) { | 
 | 1034 | 		result = PyObject_CallMethod(time, "time", "()"); | 
 | 1035 | 		Py_DECREF(time); | 
 | 1036 | 	} | 
 | 1037 | 	return result; | 
 | 1038 | } | 
 | 1039 |  | 
 | 1040 | /* Build a time.struct_time.  The weekday and day number are automatically | 
 | 1041 |  * computed from the y,m,d args. | 
 | 1042 |  */ | 
 | 1043 | static PyObject * | 
 | 1044 | build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) | 
 | 1045 | { | 
 | 1046 | 	PyObject *time; | 
 | 1047 | 	PyObject *result = NULL; | 
 | 1048 |  | 
 | 1049 | 	time = PyImport_ImportModule("time"); | 
 | 1050 | 	if (time != NULL) { | 
 | 1051 | 		result = PyObject_CallMethod(time, "struct_time", | 
 | 1052 | 					     "((iiiiiiiii))", | 
 | 1053 | 					     y, m, d, | 
 | 1054 | 					     hh, mm, ss, | 
 | 1055 | 				 	     weekday(y, m, d), | 
 | 1056 | 				 	     days_before_month(y, m) + d, | 
 | 1057 | 				 	     dstflag); | 
 | 1058 | 		Py_DECREF(time); | 
 | 1059 | 	} | 
 | 1060 | 	return result; | 
 | 1061 | } | 
 | 1062 |  | 
 | 1063 | /* --------------------------------------------------------------------------- | 
 | 1064 |  * Miscellaneous helpers. | 
 | 1065 |  */ | 
 | 1066 |  | 
 | 1067 | /* For obscure reasons, we need to use tp_richcompare instead of tp_compare. | 
 | 1068 |  * The comparisons here all most naturally compute a cmp()-like result. | 
 | 1069 |  * This little helper turns that into a bool result for rich comparisons. | 
 | 1070 |  */ | 
 | 1071 | static PyObject * | 
 | 1072 | diff_to_bool(int diff, int op) | 
 | 1073 | { | 
 | 1074 | 	PyObject *result; | 
 | 1075 | 	int istrue; | 
 | 1076 |  | 
 | 1077 | 	switch (op) { | 
 | 1078 | 		case Py_EQ: istrue = diff == 0; break; | 
 | 1079 | 		case Py_NE: istrue = diff != 0; break; | 
 | 1080 | 		case Py_LE: istrue = diff <= 0; break; | 
 | 1081 | 		case Py_GE: istrue = diff >= 0; break; | 
 | 1082 | 		case Py_LT: istrue = diff < 0; break; | 
 | 1083 | 		case Py_GT: istrue = diff > 0; break; | 
 | 1084 | 		default: | 
 | 1085 | 			assert(! "op unknown"); | 
 | 1086 | 			istrue = 0; /* To shut up compiler */ | 
 | 1087 | 	} | 
 | 1088 | 	result = istrue ? Py_True : Py_False; | 
 | 1089 | 	Py_INCREF(result); | 
 | 1090 | 	return result; | 
 | 1091 | } | 
 | 1092 |  | 
 | 1093 | /* --------------------------------------------------------------------------- | 
 | 1094 |  * Helpers for setting object fields.  These work on pointers to the | 
 | 1095 |  * appropriate base class. | 
 | 1096 |  */ | 
 | 1097 |  | 
 | 1098 | /* For date, datetime and datetimetz. */ | 
 | 1099 | static void | 
 | 1100 | set_date_fields(PyDateTime_Date *self, int y, int m, int d) | 
 | 1101 | { | 
 | 1102 | 	self->hashcode = -1; | 
 | 1103 | 	SET_YEAR(self, y); | 
 | 1104 | 	SET_MONTH(self, m); | 
 | 1105 | 	SET_DAY(self, d); | 
 | 1106 | } | 
 | 1107 |  | 
 | 1108 | /* For datetime and datetimetz. */ | 
 | 1109 | static void | 
 | 1110 | set_datetime_time_fields(PyDateTime_Date *self, int h, int m, int s, int us) | 
 | 1111 | { | 
 | 1112 | 	DATE_SET_HOUR(self, h); | 
 | 1113 | 	DATE_SET_MINUTE(self, m); | 
 | 1114 | 	DATE_SET_SECOND(self, s); | 
 | 1115 | 	DATE_SET_MICROSECOND(self, us); | 
 | 1116 | } | 
 | 1117 |  | 
 | 1118 | /* For time and timetz. */ | 
 | 1119 | static void | 
 | 1120 | set_time_fields(PyDateTime_Time *self, int h, int m, int s, int us) | 
 | 1121 | { | 
 | 1122 | 	self->hashcode = -1; | 
 | 1123 | 	TIME_SET_HOUR(self, h); | 
 | 1124 | 	TIME_SET_MINUTE(self, m); | 
 | 1125 | 	TIME_SET_SECOND(self, s); | 
 | 1126 | 	TIME_SET_MICROSECOND(self, us); | 
 | 1127 | } | 
 | 1128 |  | 
 | 1129 | /* --------------------------------------------------------------------------- | 
 | 1130 |  * Create various objects, mostly without range checking. | 
 | 1131 |  */ | 
 | 1132 |  | 
 | 1133 | /* Create a date instance with no range checking. */ | 
 | 1134 | static PyObject * | 
 | 1135 | new_date(int year, int month, int day) | 
 | 1136 | { | 
 | 1137 | 	PyDateTime_Date *self; | 
 | 1138 |  | 
 | 1139 | 	self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType); | 
 | 1140 | 	if (self != NULL) | 
 | 1141 | 		set_date_fields(self, year, month, day); | 
 | 1142 | 	return (PyObject *) self; | 
 | 1143 | } | 
 | 1144 |  | 
 | 1145 | /* Create a datetime instance with no range checking. */ | 
 | 1146 | static PyObject * | 
 | 1147 | new_datetime(int year, int month, int day, int hour, int minute, | 
 | 1148 |              int second, int usecond) | 
 | 1149 | { | 
 | 1150 | 	PyDateTime_DateTime *self; | 
 | 1151 |  | 
 | 1152 | 	self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType); | 
 | 1153 | 	if (self != NULL) { | 
 | 1154 | 		set_date_fields((PyDateTime_Date *)self, year, month, day); | 
 | 1155 | 		set_datetime_time_fields((PyDateTime_Date *)self, | 
 | 1156 | 					 hour, minute, second, usecond); | 
 | 1157 | 	} | 
 | 1158 | 	return (PyObject *) self; | 
 | 1159 | } | 
 | 1160 |  | 
 | 1161 | /* Create a datetimetz instance with no range checking. */ | 
 | 1162 | static PyObject * | 
 | 1163 | new_datetimetz(int year, int month, int day, int hour, int minute, | 
 | 1164 | 	       int second, int usecond, PyObject *tzinfo) | 
 | 1165 | { | 
 | 1166 | 	PyDateTime_DateTimeTZ *self; | 
 | 1167 |  | 
 | 1168 | 	self = PyObject_New(PyDateTime_DateTimeTZ, &PyDateTime_DateTimeTZType); | 
 | 1169 | 	if (self != NULL) { | 
 | 1170 | 		set_date_fields((PyDateTime_Date *)self, year, month, day); | 
 | 1171 | 		set_datetime_time_fields((PyDateTime_Date *)self, | 
 | 1172 | 					 hour, minute, second, usecond); | 
 | 1173 | 		Py_INCREF(tzinfo); | 
 | 1174 | 		self->tzinfo = tzinfo; | 
 | 1175 | 	} | 
 | 1176 | 	return (PyObject *) self; | 
 | 1177 | } | 
 | 1178 |  | 
 | 1179 | /* Create a time instance with no range checking. */ | 
 | 1180 | static PyObject * | 
 | 1181 | new_time(int hour, int minute, int second, int usecond) | 
 | 1182 | { | 
 | 1183 | 	PyDateTime_Time *self; | 
 | 1184 |  | 
 | 1185 | 	self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType); | 
 | 1186 | 	if (self != NULL) | 
 | 1187 | 		set_time_fields(self, hour, minute, second, usecond); | 
 | 1188 | 	return (PyObject *) self; | 
 | 1189 | } | 
 | 1190 |  | 
 | 1191 | /* Create a timetz instance with no range checking. */ | 
 | 1192 | static PyObject * | 
 | 1193 | new_timetz(int hour, int minute, int second, int usecond, PyObject *tzinfo) | 
 | 1194 | { | 
 | 1195 | 	PyDateTime_TimeTZ *self; | 
 | 1196 |  | 
 | 1197 | 	self = PyObject_New(PyDateTime_TimeTZ, &PyDateTime_TimeTZType); | 
 | 1198 | 	if (self != NULL) { | 
 | 1199 | 		set_time_fields((PyDateTime_Time *)self, | 
 | 1200 | 				hour, minute, second, usecond); | 
 | 1201 | 		Py_INCREF(tzinfo); | 
 | 1202 | 		self->tzinfo = tzinfo; | 
 | 1203 | 	} | 
 | 1204 | 	return (PyObject *) self; | 
 | 1205 | } | 
 | 1206 |  | 
 | 1207 | /* Create a timedelta instance.  Normalize the members iff normalize is | 
 | 1208 |  * true.  Passing false is a speed optimization, if you know for sure | 
 | 1209 |  * that seconds and microseconds are already in their proper ranges.  In any | 
 | 1210 |  * case, raises OverflowError and returns NULL if the normalized days is out | 
 | 1211 |  * of range). | 
 | 1212 |  */ | 
 | 1213 | static PyObject * | 
 | 1214 | new_delta(int days, int seconds, int microseconds, int normalize) | 
 | 1215 | { | 
 | 1216 | 	PyDateTime_Delta *self; | 
 | 1217 |  | 
 | 1218 | 	if (normalize) | 
 | 1219 | 		normalize_d_s_us(&days, &seconds, µseconds); | 
 | 1220 | 	assert(0 <= seconds && seconds < 24*3600); | 
 | 1221 | 	assert(0 <= microseconds && microseconds < 1000000); | 
 | 1222 |  | 
 | 1223 |  	if (check_delta_day_range(days) < 0) | 
 | 1224 |  		return NULL; | 
 | 1225 |  | 
 | 1226 | 	self = PyObject_New(PyDateTime_Delta, &PyDateTime_DeltaType); | 
 | 1227 | 	if (self != NULL) { | 
 | 1228 | 		self->hashcode = -1; | 
 | 1229 | 		SET_TD_DAYS(self, days); | 
 | 1230 | 		SET_TD_SECONDS(self, seconds); | 
 | 1231 | 		SET_TD_MICROSECONDS(self, microseconds); | 
 | 1232 | 	} | 
 | 1233 | 	return (PyObject *) self; | 
 | 1234 | } | 
 | 1235 |  | 
 | 1236 |  | 
 | 1237 | /* --------------------------------------------------------------------------- | 
 | 1238 |  * Cached Python objects; these are set by the module init function. | 
 | 1239 |  */ | 
 | 1240 |  | 
 | 1241 | /* Conversion factors. */ | 
 | 1242 | static PyObject *us_per_us = NULL;	/* 1 */ | 
 | 1243 | static PyObject *us_per_ms = NULL;	/* 1000 */ | 
 | 1244 | static PyObject *us_per_second = NULL;	/* 1000000 */ | 
 | 1245 | static PyObject *us_per_minute = NULL;	/* 1e6 * 60 as Python int */ | 
 | 1246 | static PyObject *us_per_hour = NULL;	/* 1e6 * 3600 as Python long */ | 
 | 1247 | static PyObject *us_per_day = NULL;	/* 1e6 * 3600 * 24 as Python long */ | 
 | 1248 | static PyObject *us_per_week = NULL;	/* 1e6*3600*24*7 as Python long */ | 
 | 1249 | static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */ | 
 | 1250 |  | 
 | 1251 | /* Callables to support unpickling. */ | 
 | 1252 | static PyObject *date_unpickler_object = NULL; | 
 | 1253 | static PyObject *datetime_unpickler_object = NULL; | 
 | 1254 | static PyObject *datetimetz_unpickler_object = NULL; | 
 | 1255 | static PyObject *tzinfo_unpickler_object = NULL; | 
 | 1256 | static PyObject *time_unpickler_object = NULL; | 
 | 1257 | static PyObject *timetz_unpickler_object = NULL; | 
 | 1258 |  | 
 | 1259 | /* --------------------------------------------------------------------------- | 
 | 1260 |  * Class implementations. | 
 | 1261 |  */ | 
 | 1262 |  | 
 | 1263 | /* | 
 | 1264 |  * PyDateTime_Delta implementation. | 
 | 1265 |  */ | 
 | 1266 |  | 
 | 1267 | /* Convert a timedelta to a number of us, | 
 | 1268 |  * 	(24*3600*self.days + self.seconds)*1000000 + self.microseconds | 
 | 1269 |  * as a Python int or long. | 
 | 1270 |  * Doing mixed-radix arithmetic by hand instead is excruciating in C, | 
 | 1271 |  * due to ubiquitous overflow possibilities. | 
 | 1272 |  */ | 
 | 1273 | static PyObject * | 
 | 1274 | delta_to_microseconds(PyDateTime_Delta *self) | 
 | 1275 | { | 
 | 1276 | 	PyObject *x1 = NULL; | 
 | 1277 | 	PyObject *x2 = NULL; | 
 | 1278 | 	PyObject *x3 = NULL; | 
 | 1279 | 	PyObject *result = NULL; | 
 | 1280 |  | 
 | 1281 | 	x1 = PyInt_FromLong(GET_TD_DAYS(self)); | 
 | 1282 | 	if (x1 == NULL) | 
 | 1283 | 		goto Done; | 
 | 1284 | 	x2 = PyNumber_Multiply(x1, seconds_per_day);	/* days in seconds */ | 
 | 1285 | 	if (x2 == NULL) | 
 | 1286 | 		goto Done; | 
 | 1287 | 	Py_DECREF(x1); | 
 | 1288 | 	x1 = NULL; | 
 | 1289 |  | 
 | 1290 | 	/* x2 has days in seconds */ | 
 | 1291 | 	x1 = PyInt_FromLong(GET_TD_SECONDS(self));	/* seconds */ | 
 | 1292 | 	if (x1 == NULL) | 
 | 1293 | 		goto Done; | 
 | 1294 | 	x3 = PyNumber_Add(x1, x2);	/* days and seconds in seconds */ | 
 | 1295 | 	if (x3 == NULL) | 
 | 1296 | 		goto Done; | 
 | 1297 | 	Py_DECREF(x1); | 
 | 1298 | 	Py_DECREF(x2); | 
 | 1299 | 	x1 = x2 = NULL; | 
 | 1300 |  | 
 | 1301 | 	/* x3 has days+seconds in seconds */ | 
 | 1302 | 	x1 = PyNumber_Multiply(x3, us_per_second);	/* us */ | 
 | 1303 | 	if (x1 == NULL) | 
 | 1304 | 		goto Done; | 
 | 1305 | 	Py_DECREF(x3); | 
 | 1306 | 	x3 = NULL; | 
 | 1307 |  | 
 | 1308 | 	/* x1 has days+seconds in us */ | 
 | 1309 | 	x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self)); | 
 | 1310 | 	if (x2 == NULL) | 
 | 1311 | 		goto Done; | 
 | 1312 | 	result = PyNumber_Add(x1, x2); | 
 | 1313 |  | 
 | 1314 | Done: | 
 | 1315 | 	Py_XDECREF(x1); | 
 | 1316 | 	Py_XDECREF(x2); | 
 | 1317 | 	Py_XDECREF(x3); | 
 | 1318 | 	return result; | 
 | 1319 | } | 
 | 1320 |  | 
 | 1321 | /* Convert a number of us (as a Python int or long) to a timedelta. | 
 | 1322 |  */ | 
 | 1323 | static PyObject * | 
 | 1324 | microseconds_to_delta(PyObject *pyus) | 
 | 1325 | { | 
 | 1326 | 	int us; | 
 | 1327 | 	int s; | 
 | 1328 | 	int d; | 
 | 1329 |  | 
 | 1330 | 	PyObject *tuple = NULL; | 
 | 1331 | 	PyObject *num = NULL; | 
 | 1332 | 	PyObject *result = NULL; | 
 | 1333 |  | 
 | 1334 | 	tuple = PyNumber_Divmod(pyus, us_per_second); | 
 | 1335 | 	if (tuple == NULL) | 
 | 1336 | 		goto Done; | 
 | 1337 |  | 
 | 1338 | 	num = PyTuple_GetItem(tuple, 1);	/* us */ | 
 | 1339 | 	if (num == NULL) | 
 | 1340 | 		goto Done; | 
 | 1341 | 	us = PyLong_AsLong(num); | 
 | 1342 | 	num = NULL; | 
 | 1343 | 	if (us < 0) { | 
 | 1344 | 		/* The divisor was positive, so this must be an error. */ | 
 | 1345 | 		assert(PyErr_Occurred()); | 
 | 1346 | 		goto Done; | 
 | 1347 | 	} | 
 | 1348 |  | 
 | 1349 | 	num = PyTuple_GetItem(tuple, 0);	/* leftover seconds */ | 
 | 1350 | 	if (num == NULL) | 
 | 1351 | 		goto Done; | 
 | 1352 | 	Py_INCREF(num); | 
 | 1353 | 	Py_DECREF(tuple); | 
 | 1354 |  | 
 | 1355 | 	tuple = PyNumber_Divmod(num, seconds_per_day); | 
 | 1356 | 	if (tuple == NULL) | 
 | 1357 | 		goto Done; | 
 | 1358 | 	Py_DECREF(num); | 
 | 1359 |  | 
 | 1360 | 	num = PyTuple_GetItem(tuple, 1); 	/* seconds */ | 
 | 1361 | 	if (num == NULL) | 
 | 1362 | 		goto Done; | 
 | 1363 | 	s = PyLong_AsLong(num); | 
 | 1364 | 	num = NULL; | 
 | 1365 | 	if (s < 0) { | 
 | 1366 | 		/* The divisor was positive, so this must be an error. */ | 
 | 1367 | 		assert(PyErr_Occurred()); | 
 | 1368 | 		goto Done; | 
 | 1369 | 	} | 
 | 1370 |  | 
 | 1371 | 	num = PyTuple_GetItem(tuple, 0);	/* leftover days */ | 
 | 1372 | 	if (num == NULL) | 
 | 1373 | 		goto Done; | 
 | 1374 | 	Py_INCREF(num); | 
 | 1375 |  | 
 | 1376 | 	d = PyLong_AsLong(num); | 
 | 1377 | 	if (d == -1 && PyErr_Occurred()) | 
 | 1378 | 		goto Done; | 
 | 1379 | 	result = new_delta(d, s, us, 0); | 
 | 1380 |  | 
 | 1381 | Done: | 
 | 1382 | 	Py_XDECREF(tuple); | 
 | 1383 | 	Py_XDECREF(num); | 
 | 1384 | 	return result; | 
 | 1385 | } | 
 | 1386 |  | 
 | 1387 | static PyObject * | 
 | 1388 | multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta) | 
 | 1389 | { | 
 | 1390 | 	PyObject *pyus_in; | 
 | 1391 | 	PyObject *pyus_out; | 
 | 1392 | 	PyObject *result; | 
 | 1393 |  | 
 | 1394 | 	pyus_in = delta_to_microseconds(delta); | 
 | 1395 | 	if (pyus_in == NULL) | 
 | 1396 | 		return NULL; | 
 | 1397 |  | 
 | 1398 | 	pyus_out = PyNumber_Multiply(pyus_in, intobj); | 
 | 1399 | 	Py_DECREF(pyus_in); | 
 | 1400 | 	if (pyus_out == NULL) | 
 | 1401 | 		return NULL; | 
 | 1402 |  | 
 | 1403 | 	result = microseconds_to_delta(pyus_out); | 
 | 1404 | 	Py_DECREF(pyus_out); | 
 | 1405 | 	return result; | 
 | 1406 | } | 
 | 1407 |  | 
 | 1408 | static PyObject * | 
 | 1409 | divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj) | 
 | 1410 | { | 
 | 1411 | 	PyObject *pyus_in; | 
 | 1412 | 	PyObject *pyus_out; | 
 | 1413 | 	PyObject *result; | 
 | 1414 |  | 
 | 1415 | 	pyus_in = delta_to_microseconds(delta); | 
 | 1416 | 	if (pyus_in == NULL) | 
 | 1417 | 		return NULL; | 
 | 1418 |  | 
 | 1419 | 	pyus_out = PyNumber_FloorDivide(pyus_in, intobj); | 
 | 1420 | 	Py_DECREF(pyus_in); | 
 | 1421 | 	if (pyus_out == NULL) | 
 | 1422 | 		return NULL; | 
 | 1423 |  | 
 | 1424 | 	result = microseconds_to_delta(pyus_out); | 
 | 1425 | 	Py_DECREF(pyus_out); | 
 | 1426 | 	return result; | 
 | 1427 | } | 
 | 1428 |  | 
 | 1429 | static PyObject * | 
 | 1430 | delta_add(PyObject *left, PyObject *right) | 
 | 1431 | { | 
 | 1432 | 	PyObject *result = Py_NotImplemented; | 
 | 1433 |  | 
 | 1434 | 	if (PyDelta_Check(left) && PyDelta_Check(right)) { | 
 | 1435 | 		/* delta + delta */ | 
 | 1436 | 		/* The C-level additions can't overflow because of the | 
 | 1437 | 		 * invariant bounds. | 
 | 1438 | 		 */ | 
 | 1439 | 		int days = GET_TD_DAYS(left) + GET_TD_DAYS(right); | 
 | 1440 | 		int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right); | 
 | 1441 | 		int microseconds = GET_TD_MICROSECONDS(left) + | 
 | 1442 | 				   GET_TD_MICROSECONDS(right); | 
 | 1443 | 		result = new_delta(days, seconds, microseconds, 1); | 
 | 1444 | 	} | 
 | 1445 |  | 
 | 1446 | 	if (result == Py_NotImplemented) | 
 | 1447 | 		Py_INCREF(result); | 
 | 1448 | 	return result; | 
 | 1449 | } | 
 | 1450 |  | 
 | 1451 | static PyObject * | 
 | 1452 | delta_negative(PyDateTime_Delta *self) | 
 | 1453 | { | 
 | 1454 | 	return new_delta(-GET_TD_DAYS(self), | 
 | 1455 | 			 -GET_TD_SECONDS(self), | 
 | 1456 | 			 -GET_TD_MICROSECONDS(self), | 
 | 1457 | 			 1); | 
 | 1458 | } | 
 | 1459 |  | 
 | 1460 | static PyObject * | 
 | 1461 | delta_positive(PyDateTime_Delta *self) | 
 | 1462 | { | 
 | 1463 | 	/* Could optimize this (by returning self) if this isn't a | 
 | 1464 | 	 * subclass -- but who uses unary + ?  Approximately nobody. | 
 | 1465 | 	 */ | 
 | 1466 | 	return new_delta(GET_TD_DAYS(self), | 
 | 1467 | 			 GET_TD_SECONDS(self), | 
 | 1468 | 			 GET_TD_MICROSECONDS(self), | 
 | 1469 | 			 0); | 
 | 1470 | } | 
 | 1471 |  | 
 | 1472 | static PyObject * | 
 | 1473 | delta_abs(PyDateTime_Delta *self) | 
 | 1474 | { | 
 | 1475 | 	PyObject *result; | 
 | 1476 |  | 
 | 1477 | 	assert(GET_TD_MICROSECONDS(self) >= 0); | 
 | 1478 | 	assert(GET_TD_SECONDS(self) >= 0); | 
 | 1479 |  | 
 | 1480 | 	if (GET_TD_DAYS(self) < 0) | 
 | 1481 | 		result = delta_negative(self); | 
 | 1482 | 	else | 
 | 1483 | 		result = delta_positive(self); | 
 | 1484 |  | 
 | 1485 | 	return result; | 
 | 1486 | } | 
 | 1487 |  | 
 | 1488 | static PyObject * | 
 | 1489 | delta_subtract(PyObject *left, PyObject *right) | 
 | 1490 | { | 
 | 1491 | 	PyObject *result = Py_NotImplemented; | 
 | 1492 |  | 
 | 1493 | 	if (PyDelta_Check(left) && PyDelta_Check(right)) { | 
 | 1494 | 	    	/* delta - delta */ | 
 | 1495 | 	    	PyObject *minus_right = PyNumber_Negative(right); | 
 | 1496 | 	    	if (minus_right) { | 
 | 1497 | 	    		result = delta_add(left, minus_right); | 
 | 1498 | 	    		Py_DECREF(minus_right); | 
 | 1499 | 	    	} | 
 | 1500 | 	    	else | 
 | 1501 | 	    		result = NULL; | 
 | 1502 | 	} | 
 | 1503 |  | 
 | 1504 | 	if (result == Py_NotImplemented) | 
 | 1505 | 		Py_INCREF(result); | 
 | 1506 | 	return result; | 
 | 1507 | } | 
 | 1508 |  | 
 | 1509 | /* This is more natural as a tp_compare, but doesn't work then:  for whatever | 
 | 1510 |  * reason, Python's try_3way_compare ignores tp_compare unless | 
 | 1511 |  * PyInstance_Check returns true, but these aren't old-style classes. | 
 | 1512 |  */ | 
 | 1513 | static PyObject * | 
 | 1514 | delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op) | 
 | 1515 | { | 
 | 1516 | 	int diff; | 
 | 1517 |  | 
 | 1518 | 	if (! PyDelta_CheckExact(other)) { | 
 | 1519 | 		PyErr_Format(PyExc_TypeError, | 
 | 1520 | 			     "can't compare %s to %s instance", | 
 | 1521 | 			     self->ob_type->tp_name, other->ob_type->tp_name); | 
 | 1522 | 		return NULL; | 
 | 1523 | 	} | 
 | 1524 | 	diff = GET_TD_DAYS(self) - GET_TD_DAYS(other); | 
 | 1525 | 	if (diff == 0) { | 
 | 1526 | 		diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other); | 
 | 1527 | 		if (diff == 0) | 
 | 1528 | 			diff = GET_TD_MICROSECONDS(self) - | 
 | 1529 | 			       GET_TD_MICROSECONDS(other); | 
 | 1530 | 	} | 
 | 1531 | 	return diff_to_bool(diff, op); | 
 | 1532 | } | 
 | 1533 |  | 
 | 1534 | static PyObject *delta_getstate(PyDateTime_Delta *self); | 
 | 1535 |  | 
 | 1536 | static long | 
 | 1537 | delta_hash(PyDateTime_Delta *self) | 
 | 1538 | { | 
 | 1539 | 	if (self->hashcode == -1) { | 
 | 1540 | 		PyObject *temp = delta_getstate(self); | 
 | 1541 | 		if (temp != NULL) { | 
 | 1542 | 			self->hashcode = PyObject_Hash(temp); | 
 | 1543 | 			Py_DECREF(temp); | 
 | 1544 | 		} | 
 | 1545 | 	} | 
 | 1546 | 	return self->hashcode; | 
 | 1547 | } | 
 | 1548 |  | 
 | 1549 | static PyObject * | 
 | 1550 | delta_multiply(PyObject *left, PyObject *right) | 
 | 1551 | { | 
 | 1552 | 	PyObject *result = Py_NotImplemented; | 
 | 1553 |  | 
 | 1554 | 	if (PyDelta_Check(left)) { | 
 | 1555 | 		/* delta * ??? */ | 
 | 1556 | 		if (PyInt_Check(right) || PyLong_Check(right)) | 
 | 1557 | 			result = multiply_int_timedelta(right, | 
 | 1558 | 					(PyDateTime_Delta *) left); | 
 | 1559 | 	} | 
 | 1560 | 	else if (PyInt_Check(left) || PyLong_Check(left)) | 
 | 1561 | 		result = multiply_int_timedelta(left, | 
 | 1562 | 						(PyDateTime_Delta *) right); | 
 | 1563 |  | 
 | 1564 | 	if (result == Py_NotImplemented) | 
 | 1565 | 		Py_INCREF(result); | 
 | 1566 | 	return result; | 
 | 1567 | } | 
 | 1568 |  | 
 | 1569 | static PyObject * | 
 | 1570 | delta_divide(PyObject *left, PyObject *right) | 
 | 1571 | { | 
 | 1572 | 	PyObject *result = Py_NotImplemented; | 
 | 1573 |  | 
 | 1574 | 	if (PyDelta_Check(left)) { | 
 | 1575 | 		/* delta * ??? */ | 
 | 1576 | 		if (PyInt_Check(right) || PyLong_Check(right)) | 
 | 1577 | 			result = divide_timedelta_int( | 
 | 1578 | 					(PyDateTime_Delta *)left, | 
 | 1579 | 					right); | 
 | 1580 | 	} | 
 | 1581 |  | 
 | 1582 | 	if (result == Py_NotImplemented) | 
 | 1583 | 		Py_INCREF(result); | 
 | 1584 | 	return result; | 
 | 1585 | } | 
 | 1586 |  | 
 | 1587 | /* Fold in the value of the tag ("seconds", "weeks", etc) component of a | 
 | 1588 |  * timedelta constructor.  sofar is the # of microseconds accounted for | 
 | 1589 |  * so far, and there are factor microseconds per current unit, the number | 
 | 1590 |  * of which is given by num.  num * factor is added to sofar in a | 
 | 1591 |  * numerically careful way, and that's the result.  Any fractional | 
 | 1592 |  * microseconds left over (this can happen if num is a float type) are | 
 | 1593 |  * added into *leftover. | 
 | 1594 |  * Note that there are many ways this can give an error (NULL) return. | 
 | 1595 |  */ | 
 | 1596 | static PyObject * | 
 | 1597 | accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor, | 
 | 1598 |       double *leftover) | 
 | 1599 | { | 
 | 1600 | 	PyObject *prod; | 
 | 1601 | 	PyObject *sum; | 
 | 1602 |  | 
 | 1603 | 	assert(num != NULL); | 
 | 1604 |  | 
 | 1605 | 	if (PyInt_Check(num) || PyLong_Check(num)) { | 
 | 1606 | 		prod = PyNumber_Multiply(num, factor); | 
 | 1607 | 		if (prod == NULL) | 
 | 1608 | 			return NULL; | 
 | 1609 | 		sum = PyNumber_Add(sofar, prod); | 
 | 1610 | 		Py_DECREF(prod); | 
 | 1611 | 		return sum; | 
 | 1612 | 	} | 
 | 1613 |  | 
 | 1614 | 	if (PyFloat_Check(num)) { | 
 | 1615 | 		double dnum; | 
 | 1616 | 		double fracpart; | 
 | 1617 | 		double intpart; | 
 | 1618 | 		PyObject *x; | 
 | 1619 | 		PyObject *y; | 
 | 1620 |  | 
 | 1621 | 		/* The Plan:  decompose num into an integer part and a | 
 | 1622 | 		 * fractional part, num = intpart + fracpart. | 
 | 1623 | 		 * Then num * factor == | 
 | 1624 | 		 *      intpart * factor + fracpart * factor | 
 | 1625 | 		 * and the LHS can be computed exactly in long arithmetic. | 
 | 1626 | 		 * The RHS is again broken into an int part and frac part. | 
 | 1627 | 		 * and the frac part is added into *leftover. | 
 | 1628 | 		 */ | 
 | 1629 | 		dnum = PyFloat_AsDouble(num); | 
 | 1630 | 		if (dnum == -1.0 && PyErr_Occurred()) | 
 | 1631 | 			return NULL; | 
 | 1632 | 		fracpart = modf(dnum, &intpart); | 
 | 1633 | 		x = PyLong_FromDouble(intpart); | 
 | 1634 | 		if (x == NULL) | 
 | 1635 | 			return NULL; | 
 | 1636 |  | 
 | 1637 | 		prod = PyNumber_Multiply(x, factor); | 
 | 1638 | 		Py_DECREF(x); | 
 | 1639 | 		if (prod == NULL) | 
 | 1640 | 			return NULL; | 
 | 1641 |  | 
 | 1642 | 		sum = PyNumber_Add(sofar, prod); | 
 | 1643 | 		Py_DECREF(prod); | 
 | 1644 | 		if (sum == NULL) | 
 | 1645 | 			return NULL; | 
 | 1646 |  | 
 | 1647 | 		if (fracpart == 0.0) | 
 | 1648 | 			return sum; | 
 | 1649 | 		/* So far we've lost no information.  Dealing with the | 
 | 1650 | 		 * fractional part requires float arithmetic, and may | 
 | 1651 | 		 * lose a little info. | 
 | 1652 | 		 */ | 
 | 1653 | 		assert(PyInt_Check(factor) || PyLong_Check(factor)); | 
 | 1654 | 		if (PyInt_Check(factor)) | 
 | 1655 | 			dnum = (double)PyInt_AsLong(factor); | 
 | 1656 | 		else | 
 | 1657 | 			dnum = PyLong_AsDouble(factor); | 
 | 1658 |  | 
 | 1659 | 		dnum *= fracpart; | 
 | 1660 | 		fracpart = modf(dnum, &intpart); | 
 | 1661 | 		x = PyLong_FromDouble(intpart); | 
 | 1662 | 		if (x == NULL) { | 
 | 1663 | 			Py_DECREF(sum); | 
 | 1664 | 			return NULL; | 
 | 1665 | 		} | 
 | 1666 |  | 
 | 1667 | 		y = PyNumber_Add(sum, x); | 
 | 1668 | 		Py_DECREF(sum); | 
 | 1669 | 		Py_DECREF(x); | 
 | 1670 | 		*leftover += fracpart; | 
 | 1671 | 		return y; | 
 | 1672 | 	} | 
 | 1673 |  | 
 | 1674 | 	PyErr_Format(PyExc_TypeError, | 
 | 1675 | 		     "unsupported type for timedelta %s component: %s", | 
 | 1676 | 		     tag, num->ob_type->tp_name); | 
 | 1677 | 	return NULL; | 
 | 1678 | } | 
 | 1679 |  | 
 | 1680 | static PyObject * | 
 | 1681 | delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) | 
 | 1682 | { | 
 | 1683 | 	PyObject *self = NULL; | 
 | 1684 |  | 
 | 1685 | 	/* Argument objects. */ | 
 | 1686 | 	PyObject *day = NULL; | 
 | 1687 | 	PyObject *second = NULL; | 
 | 1688 | 	PyObject *us = NULL; | 
 | 1689 | 	PyObject *ms = NULL; | 
 | 1690 | 	PyObject *minute = NULL; | 
 | 1691 | 	PyObject *hour = NULL; | 
 | 1692 | 	PyObject *week = NULL; | 
 | 1693 |  | 
 | 1694 | 	PyObject *x = NULL;	/* running sum of microseconds */ | 
 | 1695 | 	PyObject *y = NULL;	/* temp sum of microseconds */ | 
 | 1696 | 	double leftover_us = 0.0; | 
 | 1697 |  | 
 | 1698 | 	static char *keywords[] = { | 
 | 1699 | 		"days", "seconds", "microseconds", "milliseconds", | 
 | 1700 | 		"minutes", "hours", "weeks", NULL | 
 | 1701 | 	}; | 
 | 1702 |  | 
 | 1703 | 	if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__", | 
 | 1704 | 					keywords, | 
 | 1705 | 					&day, &second, &us, | 
 | 1706 | 					&ms, &minute, &hour, &week) == 0) | 
 | 1707 | 		goto Done; | 
 | 1708 |  | 
 | 1709 | 	x = PyInt_FromLong(0); | 
 | 1710 | 	if (x == NULL) | 
 | 1711 | 		goto Done; | 
 | 1712 |  | 
 | 1713 | #define CLEANUP 	\ | 
 | 1714 | 	Py_DECREF(x);	\ | 
 | 1715 | 	x = y;		\ | 
 | 1716 | 	if (x == NULL)	\ | 
 | 1717 | 		goto Done | 
 | 1718 |  | 
 | 1719 | 	if (us) { | 
 | 1720 | 		y = accum("microseconds", x, us, us_per_us, &leftover_us); | 
 | 1721 | 		CLEANUP; | 
 | 1722 | 	} | 
 | 1723 | 	if (ms) { | 
 | 1724 | 		y = accum("milliseconds", x, ms, us_per_ms, &leftover_us); | 
 | 1725 | 		CLEANUP; | 
 | 1726 | 	} | 
 | 1727 | 	if (second) { | 
 | 1728 | 		y = accum("seconds", x, second, us_per_second, &leftover_us); | 
 | 1729 | 		CLEANUP; | 
 | 1730 | 	} | 
 | 1731 | 	if (minute) { | 
 | 1732 | 		y = accum("minutes", x, minute, us_per_minute, &leftover_us); | 
 | 1733 | 		CLEANUP; | 
 | 1734 | 	} | 
 | 1735 | 	if (hour) { | 
 | 1736 | 		y = accum("hours", x, hour, us_per_hour, &leftover_us); | 
 | 1737 | 		CLEANUP; | 
 | 1738 | 	} | 
 | 1739 | 	if (day) { | 
 | 1740 | 		y = accum("days", x, day, us_per_day, &leftover_us); | 
 | 1741 | 		CLEANUP; | 
 | 1742 | 	} | 
 | 1743 | 	if (week) { | 
 | 1744 | 		y = accum("weeks", x, week, us_per_week, &leftover_us); | 
 | 1745 | 		CLEANUP; | 
 | 1746 | 	} | 
 | 1747 | 	if (leftover_us) { | 
 | 1748 | 		/* Round to nearest whole # of us, and add into x. */ | 
 | 1749 | 		PyObject *temp; | 
 | 1750 | 		if (leftover_us >= 0.0) | 
 | 1751 | 			leftover_us = floor(leftover_us + 0.5); | 
 | 1752 | 		else | 
 | 1753 | 			leftover_us = ceil(leftover_us - 0.5); | 
 | 1754 | 		temp = PyLong_FromDouble(leftover_us); | 
 | 1755 | 		if (temp == NULL) { | 
 | 1756 | 			Py_DECREF(x); | 
 | 1757 | 			goto Done; | 
 | 1758 | 		} | 
 | 1759 | 		y = PyNumber_Add(x, temp); | 
 | 1760 | 		Py_DECREF(temp); | 
 | 1761 | 		CLEANUP; | 
 | 1762 | 	} | 
 | 1763 |  | 
 | 1764 | 	self = microseconds_to_delta(x); | 
 | 1765 | 	Py_DECREF(x); | 
 | 1766 | Done: | 
 | 1767 | 	return self; | 
 | 1768 |  | 
 | 1769 | #undef CLEANUP | 
 | 1770 | } | 
 | 1771 |  | 
 | 1772 | static int | 
 | 1773 | delta_nonzero(PyDateTime_Delta *self) | 
 | 1774 | { | 
 | 1775 | 	return (GET_TD_DAYS(self) != 0 | 
 | 1776 | 		|| GET_TD_SECONDS(self) != 0 | 
 | 1777 | 		|| GET_TD_MICROSECONDS(self) != 0); | 
 | 1778 | } | 
 | 1779 |  | 
 | 1780 | static PyObject * | 
 | 1781 | delta_repr(PyDateTime_Delta *self) | 
 | 1782 | { | 
 | 1783 | 	if (GET_TD_MICROSECONDS(self) != 0) | 
 | 1784 | 		return PyString_FromFormat("%s(%d, %d, %d)", | 
 | 1785 | 					   self->ob_type->tp_name, | 
 | 1786 | 					   GET_TD_DAYS(self), | 
 | 1787 | 					   GET_TD_SECONDS(self), | 
 | 1788 | 					   GET_TD_MICROSECONDS(self)); | 
 | 1789 | 	if (GET_TD_SECONDS(self) != 0) | 
 | 1790 | 		return PyString_FromFormat("%s(%d, %d)", | 
 | 1791 | 					   self->ob_type->tp_name, | 
 | 1792 | 					   GET_TD_DAYS(self), | 
 | 1793 | 					   GET_TD_SECONDS(self)); | 
 | 1794 |  | 
 | 1795 | 	return PyString_FromFormat("%s(%d)", | 
 | 1796 | 				   self->ob_type->tp_name, | 
 | 1797 | 				   GET_TD_DAYS(self)); | 
 | 1798 | } | 
 | 1799 |  | 
 | 1800 | static PyObject * | 
 | 1801 | delta_str(PyDateTime_Delta *self) | 
 | 1802 | { | 
 | 1803 | 	int days = GET_TD_DAYS(self); | 
 | 1804 | 	int seconds = GET_TD_SECONDS(self); | 
 | 1805 | 	int us = GET_TD_MICROSECONDS(self); | 
 | 1806 | 	int hours; | 
 | 1807 | 	int minutes; | 
| Tim Peters | ba87347 | 2002-12-18 20:19:21 +0000 | [diff] [blame^] | 1808 | 	char buf[100]; | 
 | 1809 | 	char *pbuf = buf; | 
 | 1810 | 	size_t buflen = sizeof(buf); | 
 | 1811 | 	int n; | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 1812 |  | 
 | 1813 | 	minutes = divmod(seconds, 60, &seconds); | 
 | 1814 | 	hours = divmod(minutes, 60, &minutes); | 
 | 1815 |  | 
 | 1816 | 	if (days) { | 
| Tim Peters | ba87347 | 2002-12-18 20:19:21 +0000 | [diff] [blame^] | 1817 | 		n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days, | 
 | 1818 | 				  (days == 1 || days == -1) ? "" : "s"); | 
 | 1819 | 		if (n < 0 || (size_t)n >= buflen) | 
 | 1820 | 			goto Fail; | 
 | 1821 | 		pbuf += n; | 
 | 1822 | 		buflen -= (size_t)n; | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 1823 | 	} | 
 | 1824 |  | 
| Tim Peters | ba87347 | 2002-12-18 20:19:21 +0000 | [diff] [blame^] | 1825 | 	n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d", | 
 | 1826 | 			  hours, minutes, seconds); | 
 | 1827 | 	if (n < 0 || (size_t)n >= buflen) | 
 | 1828 | 		goto Fail; | 
 | 1829 | 	pbuf += n; | 
 | 1830 | 	buflen -= (size_t)n; | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 1831 |  | 
 | 1832 | 	if (us) { | 
| Tim Peters | ba87347 | 2002-12-18 20:19:21 +0000 | [diff] [blame^] | 1833 | 		n = PyOS_snprintf(pbuf, buflen, ".%06d", us); | 
 | 1834 | 		if (n < 0 || (size_t)n >= buflen) | 
 | 1835 | 			goto Fail; | 
 | 1836 | 		pbuf += n; | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 1837 | 	} | 
 | 1838 |  | 
| Tim Peters | ba87347 | 2002-12-18 20:19:21 +0000 | [diff] [blame^] | 1839 | 	return PyString_FromStringAndSize(buf, pbuf - buf); | 
 | 1840 |  | 
 | 1841 |  Fail: | 
 | 1842 | 	PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf"); | 
 | 1843 | 	return NULL; | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 1844 | } | 
 | 1845 |  | 
 | 1846 | /* Pickle support.  Quite a maze!  While __getstate__/__setstate__ sufficed | 
 | 1847 |  * in the Python implementation, the C implementation also requires | 
 | 1848 |  * __reduce__, and a __safe_for_unpickling__ attr in the type object. | 
 | 1849 |  */ | 
 | 1850 | static PyObject * | 
 | 1851 | delta_getstate(PyDateTime_Delta *self) | 
 | 1852 | { | 
 | 1853 | 	return Py_BuildValue("iii", GET_TD_DAYS(self), | 
 | 1854 | 				    GET_TD_SECONDS(self), | 
 | 1855 | 				    GET_TD_MICROSECONDS(self)); | 
 | 1856 | } | 
 | 1857 |  | 
 | 1858 | static PyObject * | 
 | 1859 | delta_setstate(PyDateTime_Delta *self, PyObject *state) | 
 | 1860 | { | 
 | 1861 | 	int day; | 
 | 1862 | 	int second; | 
 | 1863 | 	int us; | 
 | 1864 |  | 
 | 1865 | 	if (!PyArg_ParseTuple(state, "iii:__setstate__", &day, &second, &us)) | 
 | 1866 | 		return NULL; | 
 | 1867 |  | 
 | 1868 | 	self->hashcode = -1; | 
 | 1869 | 	SET_TD_DAYS(self, day); | 
 | 1870 | 	SET_TD_SECONDS(self, second); | 
 | 1871 | 	SET_TD_MICROSECONDS(self, us); | 
 | 1872 |  | 
 | 1873 | 	Py_INCREF(Py_None); | 
 | 1874 | 	return Py_None; | 
 | 1875 | } | 
 | 1876 |  | 
 | 1877 | static PyObject * | 
 | 1878 | delta_reduce(PyDateTime_Delta* self) | 
 | 1879 | { | 
 | 1880 | 	PyObject* result = NULL; | 
 | 1881 | 	PyObject* state  = delta_getstate(self); | 
 | 1882 |  | 
 | 1883 | 	if (state != NULL) { | 
 | 1884 | 		/* The funky "()" in the format string creates an empty | 
 | 1885 | 		 * tuple as the 2nd component of the result 3-tuple. | 
 | 1886 | 		 */ | 
 | 1887 | 		result = Py_BuildValue("O()O", self->ob_type, state); | 
 | 1888 | 		Py_DECREF(state); | 
 | 1889 | 	} | 
 | 1890 | 	return result; | 
 | 1891 | } | 
 | 1892 |  | 
 | 1893 | #define OFFSET(field)  offsetof(PyDateTime_Delta, field) | 
 | 1894 |  | 
 | 1895 | static PyMemberDef delta_members[] = { | 
 | 1896 | 	{"days",         T_LONG, OFFSET(days),         READONLY, | 
 | 1897 | 	 PyDoc_STR("Number of days.")}, | 
 | 1898 |  | 
 | 1899 | 	{"seconds",      T_LONG, OFFSET(seconds),      READONLY, | 
 | 1900 | 	 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")}, | 
 | 1901 |  | 
 | 1902 | 	{"microseconds", T_LONG, OFFSET(microseconds), READONLY, | 
 | 1903 | 	 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")}, | 
 | 1904 | 	{NULL} | 
 | 1905 | }; | 
 | 1906 |  | 
 | 1907 | static PyMethodDef delta_methods[] = { | 
 | 1908 | 	{"__setstate__", (PyCFunction)delta_setstate, METH_O, | 
 | 1909 | 	 PyDoc_STR("__setstate__(state)")}, | 
 | 1910 |  | 
 | 1911 | 	{"__reduce__", (PyCFunction)delta_reduce,     METH_NOARGS, | 
 | 1912 | 	 PyDoc_STR("__setstate__(state)")}, | 
 | 1913 |  | 
 | 1914 | 	{"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS, | 
 | 1915 | 	 PyDoc_STR("__getstate__() -> state")}, | 
 | 1916 | 	{NULL,	NULL}, | 
 | 1917 | }; | 
 | 1918 |  | 
 | 1919 | static char delta_doc[] = | 
 | 1920 | PyDoc_STR("Difference between two datetime values."); | 
 | 1921 |  | 
 | 1922 | static PyNumberMethods delta_as_number = { | 
 | 1923 | 	delta_add,				/* nb_add */ | 
 | 1924 | 	delta_subtract,				/* nb_subtract */ | 
 | 1925 | 	delta_multiply,				/* nb_multiply */ | 
 | 1926 | 	delta_divide,				/* nb_divide */ | 
 | 1927 | 	0,					/* nb_remainder */ | 
 | 1928 | 	0,					/* nb_divmod */ | 
 | 1929 | 	0,					/* nb_power */ | 
 | 1930 | 	(unaryfunc)delta_negative,		/* nb_negative */ | 
 | 1931 | 	(unaryfunc)delta_positive,		/* nb_positive */ | 
 | 1932 | 	(unaryfunc)delta_abs,			/* nb_absolute */ | 
 | 1933 | 	(inquiry)delta_nonzero,			/* nb_nonzero */ | 
 | 1934 | 	0,					/*nb_invert*/ | 
 | 1935 | 	0,					/*nb_lshift*/ | 
 | 1936 | 	0,					/*nb_rshift*/ | 
 | 1937 | 	0,					/*nb_and*/ | 
 | 1938 | 	0,					/*nb_xor*/ | 
 | 1939 | 	0,					/*nb_or*/ | 
 | 1940 | 	0,					/*nb_coerce*/ | 
 | 1941 | 	0,					/*nb_int*/ | 
 | 1942 | 	0,					/*nb_long*/ | 
 | 1943 | 	0,					/*nb_float*/ | 
 | 1944 | 	0,					/*nb_oct*/ | 
 | 1945 | 	0, 					/*nb_hex*/ | 
 | 1946 | 	0,					/*nb_inplace_add*/ | 
 | 1947 | 	0,					/*nb_inplace_subtract*/ | 
 | 1948 | 	0,					/*nb_inplace_multiply*/ | 
 | 1949 | 	0,					/*nb_inplace_divide*/ | 
 | 1950 | 	0,					/*nb_inplace_remainder*/ | 
 | 1951 | 	0,					/*nb_inplace_power*/ | 
 | 1952 | 	0,					/*nb_inplace_lshift*/ | 
 | 1953 | 	0,					/*nb_inplace_rshift*/ | 
 | 1954 | 	0,					/*nb_inplace_and*/ | 
 | 1955 | 	0,					/*nb_inplace_xor*/ | 
 | 1956 | 	0,					/*nb_inplace_or*/ | 
 | 1957 | 	delta_divide,				/* nb_floor_divide */ | 
 | 1958 | 	0,					/* nb_true_divide */ | 
 | 1959 | 	0,					/* nb_inplace_floor_divide */ | 
 | 1960 | 	0,					/* nb_inplace_true_divide */ | 
 | 1961 | }; | 
 | 1962 |  | 
 | 1963 | static PyTypeObject PyDateTime_DeltaType = { | 
 | 1964 | 	PyObject_HEAD_INIT(NULL) | 
 | 1965 | 	0,						/* ob_size */ | 
 | 1966 | 	"datetime.timedelta",				/* tp_name */ | 
 | 1967 | 	sizeof(PyDateTime_Delta),			/* tp_basicsize */ | 
 | 1968 | 	0,						/* tp_itemsize */ | 
 | 1969 | 	0,						/* tp_dealloc */ | 
 | 1970 | 	0,						/* tp_print */ | 
 | 1971 | 	0,						/* tp_getattr */ | 
 | 1972 | 	0,						/* tp_setattr */ | 
 | 1973 | 	0,						/* tp_compare */ | 
 | 1974 | 	(reprfunc)delta_repr,				/* tp_repr */ | 
 | 1975 | 	&delta_as_number,				/* tp_as_number */ | 
 | 1976 | 	0,						/* tp_as_sequence */ | 
 | 1977 | 	0,						/* tp_as_mapping */ | 
 | 1978 | 	(hashfunc)delta_hash,				/* tp_hash */ | 
 | 1979 | 	0,              				/* tp_call */ | 
 | 1980 | 	(reprfunc)delta_str,				/* tp_str */ | 
 | 1981 | 	PyObject_GenericGetAttr,			/* tp_getattro */ | 
 | 1982 | 	0,						/* tp_setattro */ | 
 | 1983 | 	0,						/* tp_as_buffer */ | 
 | 1984 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,	/* tp_flags */ | 
 | 1985 | 	delta_doc,					/* tp_doc */ | 
 | 1986 | 	0,						/* tp_traverse */ | 
 | 1987 | 	0,						/* tp_clear */ | 
 | 1988 | 	(richcmpfunc)delta_richcompare,			/* tp_richcompare */ | 
 | 1989 | 	0,						/* tp_weaklistoffset */ | 
 | 1990 | 	0,						/* tp_iter */ | 
 | 1991 | 	0,						/* tp_iternext */ | 
 | 1992 | 	delta_methods,					/* tp_methods */ | 
 | 1993 | 	delta_members,					/* tp_members */ | 
 | 1994 | 	0,						/* tp_getset */ | 
 | 1995 | 	0,						/* tp_base */ | 
 | 1996 | 	0,						/* tp_dict */ | 
 | 1997 | 	0,						/* tp_descr_get */ | 
 | 1998 | 	0,						/* tp_descr_set */ | 
 | 1999 | 	0,						/* tp_dictoffset */ | 
 | 2000 | 	0,						/* tp_init */ | 
 | 2001 | 	0,						/* tp_alloc */ | 
 | 2002 | 	delta_new,					/* tp_new */ | 
 | 2003 | 	_PyObject_Del,					/* tp_free */ | 
 | 2004 | }; | 
 | 2005 |  | 
 | 2006 | /* | 
 | 2007 |  * PyDateTime_Date implementation. | 
 | 2008 |  */ | 
 | 2009 |  | 
 | 2010 | /* Accessor properties. */ | 
 | 2011 |  | 
 | 2012 | static PyObject * | 
 | 2013 | date_year(PyDateTime_Date *self, void *unused) | 
 | 2014 | { | 
 | 2015 | 	return PyInt_FromLong(GET_YEAR(self)); | 
 | 2016 | } | 
 | 2017 |  | 
 | 2018 | static PyObject * | 
 | 2019 | date_month(PyDateTime_Date *self, void *unused) | 
 | 2020 | { | 
 | 2021 | 	return PyInt_FromLong(GET_MONTH(self)); | 
 | 2022 | } | 
 | 2023 |  | 
 | 2024 | static PyObject * | 
 | 2025 | date_day(PyDateTime_Date *self, void *unused) | 
 | 2026 | { | 
 | 2027 | 	return PyInt_FromLong(GET_DAY(self)); | 
 | 2028 | } | 
 | 2029 |  | 
 | 2030 | static PyGetSetDef date_getset[] = { | 
 | 2031 | 	{"year",        (getter)date_year}, | 
 | 2032 | 	{"month",       (getter)date_month}, | 
 | 2033 | 	{"day",         (getter)date_day}, | 
 | 2034 | 	{NULL} | 
 | 2035 | }; | 
 | 2036 |  | 
 | 2037 | /* Constructors. */ | 
 | 2038 |  | 
 | 2039 | static PyObject * | 
 | 2040 | date_new(PyTypeObject *type, PyObject *args, PyObject *kw) | 
 | 2041 | { | 
 | 2042 | 	PyObject *self = NULL; | 
 | 2043 | 	int year; | 
 | 2044 | 	int month; | 
 | 2045 | 	int day; | 
 | 2046 |  | 
 | 2047 | 	static char *keywords[] = { | 
 | 2048 | 		"year", "month", "day", NULL | 
 | 2049 | 	}; | 
 | 2050 |  | 
 | 2051 | 	if (PyArg_ParseTupleAndKeywords(args, kw, "iii", keywords, | 
 | 2052 | 					&year, &month, &day)) { | 
 | 2053 | 		if (check_date_args(year, month, day) < 0) | 
 | 2054 | 			return NULL; | 
 | 2055 | 		self = new_date(year, month, day); | 
 | 2056 | 	} | 
 | 2057 | 	return self; | 
 | 2058 | } | 
 | 2059 |  | 
 | 2060 | /* Return new date from localtime(t). */ | 
 | 2061 | static PyObject * | 
 | 2062 | date_local_from_time_t(PyObject *cls, time_t t) | 
 | 2063 | { | 
 | 2064 | 	struct tm *tm; | 
 | 2065 | 	PyObject *result = NULL; | 
 | 2066 |  | 
 | 2067 | 	tm = localtime(&t); | 
 | 2068 | 	if (tm) | 
 | 2069 | 		result = PyObject_CallFunction(cls, "iii", | 
 | 2070 | 					       tm->tm_year + 1900, | 
 | 2071 | 					       tm->tm_mon + 1, | 
 | 2072 | 					       tm->tm_mday); | 
 | 2073 | 	else | 
 | 2074 | 		PyErr_SetString(PyExc_ValueError, | 
 | 2075 | 				"timestamp out of range for " | 
 | 2076 | 				"platform localtime() function"); | 
 | 2077 | 	return result; | 
 | 2078 | } | 
 | 2079 |  | 
 | 2080 | /* Return new date from current time. | 
 | 2081 |  * We say this is equivalent to fromtimestamp(time.time()), and the | 
 | 2082 |  * only way to be sure of that is to *call* time.time().  That's not | 
 | 2083 |  * generally the same as calling C's time. | 
 | 2084 |  */ | 
 | 2085 | static PyObject * | 
 | 2086 | date_today(PyObject *cls, PyObject *dummy) | 
 | 2087 | { | 
 | 2088 | 	PyObject *time; | 
 | 2089 | 	PyObject *result; | 
 | 2090 |  | 
 | 2091 | 	time = time_time(); | 
 | 2092 | 	if (time == NULL) | 
 | 2093 | 		return NULL; | 
 | 2094 |  | 
 | 2095 | 	/* Note well:  today() is a class method, so this may not call | 
 | 2096 | 	 * date.fromtimestamp.  For example, it may call | 
 | 2097 | 	 * datetime.fromtimestamp.  That's why we need all the accuracy | 
 | 2098 | 	 * time.time() delivers; if someone were gonzo about optimization, | 
 | 2099 | 	 * date.today() could get away with plain C time(). | 
 | 2100 | 	 */ | 
 | 2101 | 	result = PyObject_CallMethod(cls, "fromtimestamp", "O", time); | 
 | 2102 | 	Py_DECREF(time); | 
 | 2103 | 	return result; | 
 | 2104 | } | 
 | 2105 |  | 
 | 2106 | /* Return new date from given timestamp (Python timestamp -- a double). */ | 
 | 2107 | static PyObject * | 
 | 2108 | date_fromtimestamp(PyObject *cls, PyObject *args) | 
 | 2109 | { | 
 | 2110 | 	double timestamp; | 
 | 2111 | 	PyObject *result = NULL; | 
 | 2112 |  | 
 | 2113 | 	if (PyArg_ParseTuple(args, "d:fromtimestamp", ×tamp)) | 
 | 2114 | 		result = date_local_from_time_t(cls, (time_t)timestamp); | 
 | 2115 | 	return result; | 
 | 2116 | } | 
 | 2117 |  | 
 | 2118 | /* Return new date from proleptic Gregorian ordinal.  Raises ValueError if | 
 | 2119 |  * the ordinal is out of range. | 
 | 2120 |  */ | 
 | 2121 | static PyObject * | 
 | 2122 | date_fromordinal(PyObject *cls, PyObject *args) | 
 | 2123 | { | 
 | 2124 | 	PyObject *result = NULL; | 
 | 2125 | 	int ordinal; | 
 | 2126 |  | 
 | 2127 | 	if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) { | 
 | 2128 | 		int year; | 
 | 2129 | 		int month; | 
 | 2130 | 		int day; | 
 | 2131 |  | 
 | 2132 | 		if (ordinal < 1) | 
 | 2133 | 			PyErr_SetString(PyExc_ValueError, "ordinal must be " | 
 | 2134 | 							  ">= 1"); | 
 | 2135 | 		else { | 
 | 2136 | 			ord_to_ymd(ordinal, &year, &month, &day); | 
 | 2137 | 			result = PyObject_CallFunction(cls, "iii", | 
 | 2138 | 						       year, month, day); | 
 | 2139 | 		} | 
 | 2140 | 	} | 
 | 2141 | 	return result; | 
 | 2142 | } | 
 | 2143 |  | 
 | 2144 | /* | 
 | 2145 |  * Date arithmetic. | 
 | 2146 |  */ | 
 | 2147 |  | 
 | 2148 | /* date + timedelta -> date.  If arg negate is true, subtract the timedelta | 
 | 2149 |  * instead. | 
 | 2150 |  */ | 
 | 2151 | static PyObject * | 
 | 2152 | add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate) | 
 | 2153 | { | 
 | 2154 | 	PyObject *result = NULL; | 
 | 2155 | 	int year = GET_YEAR(date); | 
 | 2156 | 	int month = GET_MONTH(date); | 
 | 2157 | 	int deltadays = GET_TD_DAYS(delta); | 
 | 2158 | 	/* C-level overflow is impossible because |deltadays| < 1e9. */ | 
 | 2159 | 	int day = GET_DAY(date) + (negate ? -deltadays : deltadays); | 
 | 2160 |  | 
 | 2161 | 	if (normalize_date(&year, &month, &day) >= 0) | 
 | 2162 | 		result = new_date(year, month, day); | 
 | 2163 | 	return result; | 
 | 2164 | } | 
 | 2165 |  | 
 | 2166 | static PyObject * | 
 | 2167 | date_add(PyObject *left, PyObject *right) | 
 | 2168 | { | 
 | 2169 | 	if (PyDateTime_Check(left) || PyDateTime_Check(right)) { | 
 | 2170 | 		Py_INCREF(Py_NotImplemented); | 
 | 2171 | 		return Py_NotImplemented; | 
 | 2172 | 	} | 
 | 2173 | 	if (PyDate_CheckExact(left)) { | 
 | 2174 | 		/* date + ??? */ | 
 | 2175 | 		if (PyDelta_Check(right)) | 
 | 2176 | 			/* date + delta */ | 
 | 2177 | 			return add_date_timedelta((PyDateTime_Date *) left, | 
 | 2178 | 						  (PyDateTime_Delta *) right, | 
 | 2179 | 						  0); | 
 | 2180 | 	} | 
 | 2181 | 	else { | 
 | 2182 | 		/* ??? + date | 
 | 2183 | 		 * 'right' must be one of us, or we wouldn't have been called | 
 | 2184 | 		 */ | 
 | 2185 | 		if (PyDelta_Check(left)) | 
 | 2186 | 			/* delta + date */ | 
 | 2187 | 			return add_date_timedelta((PyDateTime_Date *) right, | 
 | 2188 | 						  (PyDateTime_Delta *) left, | 
 | 2189 | 						  0); | 
 | 2190 | 	} | 
 | 2191 | 	Py_INCREF(Py_NotImplemented); | 
 | 2192 | 	return Py_NotImplemented; | 
 | 2193 | } | 
 | 2194 |  | 
 | 2195 | static PyObject * | 
 | 2196 | date_subtract(PyObject *left, PyObject *right) | 
 | 2197 | { | 
 | 2198 | 	if (PyDateTime_Check(left) || PyDateTime_Check(right)) { | 
 | 2199 | 		Py_INCREF(Py_NotImplemented); | 
 | 2200 | 		return Py_NotImplemented; | 
 | 2201 | 	} | 
 | 2202 | 	if (PyDate_CheckExact(left)) { | 
 | 2203 | 		if (PyDate_CheckExact(right)) { | 
 | 2204 | 			/* date - date */ | 
 | 2205 | 			int left_ord = ymd_to_ord(GET_YEAR(left), | 
 | 2206 | 						  GET_MONTH(left), | 
 | 2207 | 						  GET_DAY(left)); | 
 | 2208 | 			int right_ord = ymd_to_ord(GET_YEAR(right), | 
 | 2209 | 						   GET_MONTH(right), | 
 | 2210 | 						   GET_DAY(right)); | 
 | 2211 | 			return new_delta(left_ord - right_ord, 0, 0, 0); | 
 | 2212 | 		} | 
 | 2213 | 		if (PyDelta_Check(right)) { | 
 | 2214 | 			/* date - delta */ | 
 | 2215 | 			return add_date_timedelta((PyDateTime_Date *) left, | 
 | 2216 | 						  (PyDateTime_Delta *) right, | 
 | 2217 | 						  1); | 
 | 2218 | 		} | 
 | 2219 | 	} | 
 | 2220 | 	Py_INCREF(Py_NotImplemented); | 
 | 2221 | 	return Py_NotImplemented; | 
 | 2222 | } | 
 | 2223 |  | 
 | 2224 |  | 
 | 2225 | /* Various ways to turn a date into a string. */ | 
 | 2226 |  | 
 | 2227 | static PyObject * | 
 | 2228 | date_repr(PyDateTime_Date *self) | 
 | 2229 | { | 
 | 2230 | 	char buffer[1028]; | 
 | 2231 | 	char *typename; | 
 | 2232 |  | 
 | 2233 | 	typename = self->ob_type->tp_name; | 
 | 2234 | 	PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)", | 
 | 2235 | 		      typename, | 
 | 2236 | 		      GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); | 
 | 2237 |  | 
 | 2238 | 	return PyString_FromString(buffer); | 
 | 2239 | } | 
 | 2240 |  | 
 | 2241 | static PyObject * | 
 | 2242 | date_isoformat(PyDateTime_Date *self) | 
 | 2243 | { | 
 | 2244 | 	char buffer[128]; | 
 | 2245 |  | 
 | 2246 | 	isoformat_date(self, buffer, sizeof(buffer)); | 
 | 2247 | 	return PyString_FromString(buffer); | 
 | 2248 | } | 
 | 2249 |  | 
 | 2250 | /* str() calls the appropriate isofomat() method. */ | 
 | 2251 | static PyObject * | 
 | 2252 | date_str(PyDateTime_Date *self) | 
 | 2253 | { | 
 | 2254 | 	return PyObject_CallMethod((PyObject *)self, "isoformat", "()"); | 
 | 2255 | } | 
 | 2256 |  | 
 | 2257 |  | 
 | 2258 | static PyObject * | 
 | 2259 | date_ctime(PyDateTime_Date *self) | 
 | 2260 | { | 
 | 2261 | 	return format_ctime(self, 0, 0, 0); | 
 | 2262 | } | 
 | 2263 |  | 
 | 2264 | static PyObject * | 
 | 2265 | date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) | 
 | 2266 | { | 
 | 2267 | 	/* This method can be inherited, and needs to call the | 
 | 2268 | 	 * timetuple() method appropriate to self's class. | 
 | 2269 | 	 */ | 
 | 2270 | 	PyObject *result; | 
 | 2271 | 	PyObject *format; | 
 | 2272 | 	PyObject *tuple; | 
 | 2273 | 	static char *keywords[] = {"format", NULL}; | 
 | 2274 |  | 
 | 2275 | 	if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords, | 
 | 2276 | 					  &PyString_Type, &format)) | 
 | 2277 | 		return NULL; | 
 | 2278 |  | 
 | 2279 | 	tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()"); | 
 | 2280 | 	if (tuple == NULL) | 
 | 2281 | 		return NULL; | 
 | 2282 | 	result = wrap_strftime((PyObject *)self, format, tuple); | 
 | 2283 | 	Py_DECREF(tuple); | 
 | 2284 | 	return result; | 
 | 2285 | } | 
 | 2286 |  | 
 | 2287 | /* ISO methods. */ | 
 | 2288 |  | 
 | 2289 | static PyObject * | 
 | 2290 | date_isoweekday(PyDateTime_Date *self) | 
 | 2291 | { | 
 | 2292 | 	int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); | 
 | 2293 |  | 
 | 2294 | 	return PyInt_FromLong(dow + 1); | 
 | 2295 | } | 
 | 2296 |  | 
 | 2297 | static PyObject * | 
 | 2298 | date_isocalendar(PyDateTime_Date *self) | 
 | 2299 | { | 
 | 2300 | 	int  year         = GET_YEAR(self); | 
 | 2301 | 	int  week1_monday = iso_week1_monday(year); | 
 | 2302 | 	int today         = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self)); | 
 | 2303 | 	int  week; | 
 | 2304 | 	int  day; | 
 | 2305 |  | 
 | 2306 | 	week = divmod(today - week1_monday, 7, &day); | 
 | 2307 | 	if (week < 0) { | 
 | 2308 | 		--year; | 
 | 2309 | 		week1_monday = iso_week1_monday(year); | 
 | 2310 | 		week = divmod(today - week1_monday, 7, &day); | 
 | 2311 | 	} | 
 | 2312 | 	else if (week >= 52 && today >= iso_week1_monday(year + 1)) { | 
 | 2313 | 		++year; | 
 | 2314 | 		week = 0; | 
 | 2315 | 	} | 
 | 2316 | 	return Py_BuildValue("iii", year, week + 1, day + 1); | 
 | 2317 | } | 
 | 2318 |  | 
 | 2319 | /* Miscellaneous methods. */ | 
 | 2320 |  | 
 | 2321 | /* This is more natural as a tp_compare, but doesn't work then:  for whatever | 
 | 2322 |  * reason, Python's try_3way_compare ignores tp_compare unless | 
 | 2323 |  * PyInstance_Check returns true, but these aren't old-style classes. | 
 | 2324 |  */ | 
 | 2325 | static PyObject * | 
 | 2326 | date_richcompare(PyDateTime_Date *self, PyObject *other, int op) | 
 | 2327 | { | 
 | 2328 | 	int diff; | 
 | 2329 |  | 
 | 2330 | 	if (! PyDate_Check(other)) { | 
 | 2331 | 		PyErr_Format(PyExc_TypeError, | 
 | 2332 | 			     "can't compare date to %s instance", | 
 | 2333 | 			     other->ob_type->tp_name); | 
 | 2334 | 		return NULL; | 
 | 2335 | 	} | 
 | 2336 | 	diff = memcmp(self->data, ((PyDateTime_Date *)other)->data, | 
 | 2337 | 		      _PyDateTime_DATE_DATASIZE); | 
 | 2338 | 	return diff_to_bool(diff, op); | 
 | 2339 | } | 
 | 2340 |  | 
 | 2341 | static PyObject * | 
 | 2342 | date_timetuple(PyDateTime_Date *self) | 
 | 2343 | { | 
 | 2344 | 	return build_struct_time(GET_YEAR(self), | 
 | 2345 | 				 GET_MONTH(self), | 
 | 2346 | 				 GET_DAY(self), | 
 | 2347 | 				 0, 0, 0, -1); | 
 | 2348 | } | 
 | 2349 |  | 
 | 2350 | static PyObject *date_getstate(PyDateTime_Date *self); | 
 | 2351 |  | 
 | 2352 | static long | 
 | 2353 | date_hash(PyDateTime_Date *self) | 
 | 2354 | { | 
 | 2355 | 	if (self->hashcode == -1) { | 
 | 2356 | 		PyObject *temp = date_getstate(self); | 
 | 2357 | 		if (temp != NULL) { | 
 | 2358 | 			self->hashcode = PyObject_Hash(temp); | 
 | 2359 | 			Py_DECREF(temp); | 
 | 2360 | 		} | 
 | 2361 | 	} | 
 | 2362 | 	return self->hashcode; | 
 | 2363 | } | 
 | 2364 |  | 
 | 2365 | static PyObject * | 
 | 2366 | date_toordinal(PyDateTime_Date *self) | 
 | 2367 | { | 
 | 2368 | 	return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self), | 
 | 2369 | 					 GET_DAY(self))); | 
 | 2370 | } | 
 | 2371 |  | 
 | 2372 | static PyObject * | 
 | 2373 | date_weekday(PyDateTime_Date *self) | 
 | 2374 | { | 
 | 2375 | 	int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); | 
 | 2376 |  | 
 | 2377 | 	return PyInt_FromLong(dow); | 
 | 2378 | } | 
 | 2379 |  | 
 | 2380 | /* Pickle support.  Quite a maze! */ | 
 | 2381 |  | 
 | 2382 | static PyObject * | 
 | 2383 | date_getstate(PyDateTime_Date *self) | 
 | 2384 | { | 
 | 2385 | 	return PyString_FromStringAndSize(self->data, | 
 | 2386 | 					  _PyDateTime_DATE_DATASIZE); | 
 | 2387 | } | 
 | 2388 |  | 
 | 2389 | static PyObject * | 
 | 2390 | date_setstate(PyDateTime_Date *self, PyObject *state) | 
 | 2391 | { | 
 | 2392 | 	const int len = PyString_Size(state); | 
 | 2393 | 	unsigned char *pdata = (unsigned char*)PyString_AsString(state); | 
 | 2394 |  | 
 | 2395 | 	if (! PyString_Check(state) || | 
 | 2396 | 	    len != _PyDateTime_DATE_DATASIZE) { | 
 | 2397 | 		PyErr_SetString(PyExc_TypeError, | 
 | 2398 | 				"bad argument to date.__setstate__"); | 
 | 2399 | 		return NULL; | 
 | 2400 | 	} | 
 | 2401 | 	memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE); | 
 | 2402 | 	self->hashcode = -1; | 
 | 2403 |  | 
 | 2404 | 	Py_INCREF(Py_None); | 
 | 2405 | 	return Py_None; | 
 | 2406 | } | 
 | 2407 |  | 
 | 2408 | /* XXX This seems a ridiculously inefficient way to pickle a short string. */ | 
 | 2409 | static PyObject * | 
 | 2410 | date_pickler(PyObject *module, PyDateTime_Date *date) | 
 | 2411 | { | 
 | 2412 | 	PyObject *state; | 
 | 2413 | 	PyObject *result = NULL; | 
 | 2414 |  | 
 | 2415 | 	if (! PyDate_CheckExact(date)) { | 
 | 2416 | 		PyErr_Format(PyExc_TypeError, | 
 | 2417 | 			     "bad type passed to date pickler: %s", | 
 | 2418 | 			     date->ob_type->tp_name); | 
 | 2419 | 		return NULL; | 
 | 2420 | 	} | 
 | 2421 | 	state = date_getstate(date); | 
 | 2422 | 	if (state) { | 
 | 2423 | 		result = Py_BuildValue("O(O)", date_unpickler_object, state); | 
 | 2424 | 		Py_DECREF(state); | 
 | 2425 | 	} | 
 | 2426 | 	return result; | 
 | 2427 | } | 
 | 2428 |  | 
 | 2429 | static PyObject * | 
 | 2430 | date_unpickler(PyObject *module, PyObject *arg) | 
 | 2431 | { | 
 | 2432 | 	PyDateTime_Date *self; | 
 | 2433 |  | 
 | 2434 | 	if (! PyString_CheckExact(arg)) { | 
 | 2435 | 		PyErr_Format(PyExc_TypeError, | 
 | 2436 | 			     "bad type passed to date unpickler: %s", | 
 | 2437 | 			     arg->ob_type->tp_name); | 
 | 2438 | 		return NULL; | 
 | 2439 | 	} | 
 | 2440 | 	self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType); | 
 | 2441 | 	if (self != NULL) { | 
 | 2442 | 		PyObject *res = date_setstate(self, arg); | 
 | 2443 | 		if (res == NULL) { | 
 | 2444 | 			Py_DECREF(self); | 
 | 2445 | 			return NULL; | 
 | 2446 | 		} | 
 | 2447 | 		Py_DECREF(res); | 
 | 2448 | 	} | 
 | 2449 | 	return (PyObject *)self; | 
 | 2450 | } | 
 | 2451 |  | 
 | 2452 | static PyMethodDef date_methods[] = { | 
 | 2453 | 	/* Class methods: */ | 
 | 2454 | 	{"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS | | 
 | 2455 | 							   METH_CLASS, | 
 | 2456 | 	 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like " | 
 | 2457 | 	 	   "time.time()).")}, | 
 | 2458 |  | 
 | 2459 | 	{"fromordinal", (PyCFunction)date_fromordinal,	METH_VARARGS | | 
 | 2460 | 							METH_CLASS, | 
 | 2461 | 	 PyDoc_STR("int -> date corresponding to a proleptic Gregorian " | 
 | 2462 | 	 	   "ordinal.")}, | 
 | 2463 |  | 
 | 2464 | 	{"today",         (PyCFunction)date_today,   METH_NOARGS | METH_CLASS, | 
 | 2465 | 	 PyDoc_STR("Current date or datetime:  same as " | 
 | 2466 | 	 	   "self.__class__.fromtimestamp(time.time()).")}, | 
 | 2467 |  | 
 | 2468 | 	/* Instance methods: */ | 
 | 2469 |  | 
 | 2470 | 	{"ctime",       (PyCFunction)date_ctime,        METH_NOARGS, | 
 | 2471 | 	 PyDoc_STR("Return ctime() style string.")}, | 
 | 2472 |  | 
 | 2473 | 	{"strftime",   	(PyCFunction)date_strftime,	METH_KEYWORDS, | 
 | 2474 | 	 PyDoc_STR("format -> strftime() style string.")}, | 
 | 2475 |  | 
 | 2476 | 	{"timetuple",   (PyCFunction)date_timetuple,    METH_NOARGS, | 
 | 2477 |          PyDoc_STR("Return time tuple, compatible with time.localtime().")}, | 
 | 2478 |  | 
 | 2479 | 	{"isocalendar", (PyCFunction)date_isocalendar,  METH_NOARGS, | 
 | 2480 | 	 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and " | 
 | 2481 | 	 	   "weekday.")}, | 
 | 2482 |  | 
 | 2483 | 	{"isoformat",   (PyCFunction)date_isoformat,	METH_NOARGS, | 
 | 2484 | 	 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")}, | 
 | 2485 |  | 
 | 2486 | 	{"isoweekday",  (PyCFunction)date_isoweekday,   METH_NOARGS, | 
 | 2487 | 	 PyDoc_STR("Return the day of the week represented by the date.\n" | 
 | 2488 | 	 	   "Monday == 1 ... Sunday == 7")}, | 
 | 2489 |  | 
 | 2490 | 	{"toordinal",   (PyCFunction)date_toordinal,    METH_NOARGS, | 
 | 2491 | 	 PyDoc_STR("Return proleptic Gregorian ordinal.  January 1 of year " | 
 | 2492 | 	 	   "1 is day 1.")}, | 
 | 2493 |  | 
 | 2494 | 	{"weekday",     (PyCFunction)date_weekday,      METH_NOARGS, | 
 | 2495 | 	 PyDoc_STR("Return the day of the week represented by the date.\n" | 
 | 2496 | 		   "Monday == 0 ... Sunday == 6")}, | 
 | 2497 |  | 
 | 2498 | 	{"__setstate__", (PyCFunction)date_setstate,	METH_O, | 
 | 2499 | 	 PyDoc_STR("__setstate__(state)")}, | 
 | 2500 |  | 
 | 2501 | 	{"__getstate__", (PyCFunction)date_getstate,	METH_NOARGS, | 
 | 2502 | 	 PyDoc_STR("__getstate__() -> state")}, | 
 | 2503 |  | 
 | 2504 | 	{NULL,	NULL} | 
 | 2505 | }; | 
 | 2506 |  | 
 | 2507 | static char date_doc[] = | 
 | 2508 | PyDoc_STR("Basic date type."); | 
 | 2509 |  | 
 | 2510 | static PyNumberMethods date_as_number = { | 
 | 2511 | 	date_add,					/* nb_add */ | 
 | 2512 | 	date_subtract,					/* nb_subtract */ | 
 | 2513 | 	0,						/* nb_multiply */ | 
 | 2514 | 	0,						/* nb_divide */ | 
 | 2515 | 	0,						/* nb_remainder */ | 
 | 2516 | 	0,						/* nb_divmod */ | 
 | 2517 | 	0,						/* nb_power */ | 
 | 2518 | 	0,						/* nb_negative */ | 
 | 2519 | 	0,						/* nb_positive */ | 
 | 2520 | 	0,						/* nb_absolute */ | 
 | 2521 | 	0,						/* nb_nonzero */ | 
 | 2522 | }; | 
 | 2523 |  | 
 | 2524 | static PyTypeObject PyDateTime_DateType = { | 
 | 2525 | 	PyObject_HEAD_INIT(NULL) | 
 | 2526 | 	0,						/* ob_size */ | 
 | 2527 | 	"datetime.date",				/* tp_name */ | 
 | 2528 | 	sizeof(PyDateTime_Date),			/* tp_basicsize */ | 
 | 2529 | 	0,						/* tp_itemsize */ | 
 | 2530 | 	(destructor)PyObject_Del,			/* tp_dealloc */ | 
 | 2531 | 	0,						/* tp_print */ | 
 | 2532 | 	0,						/* tp_getattr */ | 
 | 2533 | 	0,						/* tp_setattr */ | 
 | 2534 | 	0,						/* tp_compare */ | 
 | 2535 | 	(reprfunc)date_repr,				/* tp_repr */ | 
 | 2536 | 	&date_as_number,				/* tp_as_number */ | 
 | 2537 | 	0,						/* tp_as_sequence */ | 
 | 2538 | 	0,						/* tp_as_mapping */ | 
 | 2539 | 	(hashfunc)date_hash,				/* tp_hash */ | 
 | 2540 | 	0,              				/* tp_call */ | 
 | 2541 | 	(reprfunc)date_str,				/* tp_str */ | 
 | 2542 | 	PyObject_GenericGetAttr,			/* tp_getattro */ | 
 | 2543 | 	0,						/* tp_setattro */ | 
 | 2544 | 	0,						/* tp_as_buffer */ | 
 | 2545 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | | 
 | 2546 |         Py_TPFLAGS_BASETYPE,				/* tp_flags */ | 
 | 2547 | 	date_doc,					/* tp_doc */ | 
 | 2548 | 	0,						/* tp_traverse */ | 
 | 2549 | 	0,						/* tp_clear */ | 
 | 2550 | 	(richcmpfunc)date_richcompare,			/* tp_richcompare */ | 
 | 2551 | 	0,						/* tp_weaklistoffset */ | 
 | 2552 | 	0,						/* tp_iter */ | 
 | 2553 | 	0,						/* tp_iternext */ | 
 | 2554 | 	date_methods,					/* tp_methods */ | 
 | 2555 | 	0,						/* tp_members */ | 
 | 2556 | 	date_getset,					/* tp_getset */ | 
 | 2557 | 	0,						/* tp_base */ | 
 | 2558 | 	0,						/* tp_dict */ | 
 | 2559 | 	0,						/* tp_descr_get */ | 
 | 2560 | 	0,						/* tp_descr_set */ | 
 | 2561 | 	0,						/* tp_dictoffset */ | 
 | 2562 | 	0,						/* tp_init */ | 
 | 2563 | 	0,						/* tp_alloc */ | 
 | 2564 | 	date_new,					/* tp_new */ | 
 | 2565 | 	_PyObject_Del,					/* tp_free */ | 
 | 2566 | }; | 
 | 2567 |  | 
 | 2568 | /* | 
 | 2569 |  * PyDateTime_DateTime implementation. | 
 | 2570 |  */ | 
 | 2571 |  | 
 | 2572 | /* Accessor properties. */ | 
 | 2573 |  | 
 | 2574 | static PyObject * | 
 | 2575 | datetime_hour(PyDateTime_DateTime *self, void *unused) | 
 | 2576 | { | 
 | 2577 | 	return PyInt_FromLong(DATE_GET_HOUR(self)); | 
 | 2578 | } | 
 | 2579 |  | 
 | 2580 | static PyObject * | 
 | 2581 | datetime_minute(PyDateTime_DateTime *self, void *unused) | 
 | 2582 | { | 
 | 2583 | 	return PyInt_FromLong(DATE_GET_MINUTE(self)); | 
 | 2584 | } | 
 | 2585 |  | 
 | 2586 | static PyObject * | 
 | 2587 | datetime_second(PyDateTime_DateTime *self, void *unused) | 
 | 2588 | { | 
 | 2589 | 	return PyInt_FromLong(DATE_GET_SECOND(self)); | 
 | 2590 | } | 
 | 2591 |  | 
 | 2592 | static PyObject * | 
 | 2593 | datetime_microsecond(PyDateTime_DateTime *self, void *unused) | 
 | 2594 | { | 
 | 2595 | 	return PyInt_FromLong(DATE_GET_MICROSECOND(self)); | 
 | 2596 | } | 
 | 2597 |  | 
 | 2598 | static PyGetSetDef datetime_getset[] = { | 
 | 2599 | 	{"hour",        (getter)datetime_hour}, | 
 | 2600 | 	{"minute",      (getter)datetime_minute}, | 
 | 2601 | 	{"second",      (getter)datetime_second}, | 
 | 2602 | 	{"microsecond", (getter)datetime_microsecond}, | 
 | 2603 | 	{NULL} | 
 | 2604 | }; | 
 | 2605 |  | 
 | 2606 | /* Constructors. */ | 
 | 2607 |  | 
 | 2608 | static PyObject * | 
 | 2609 | datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) | 
 | 2610 | { | 
 | 2611 | 	PyObject *self = NULL; | 
 | 2612 | 	int year; | 
 | 2613 | 	int month; | 
 | 2614 | 	int day; | 
 | 2615 | 	int hour = 0; | 
 | 2616 | 	int minute = 0; | 
 | 2617 | 	int second = 0; | 
 | 2618 | 	int usecond = 0; | 
 | 2619 |  | 
 | 2620 | 	static char *keywords[] = { | 
 | 2621 | 		"year", "month", "day", "hour", "minute", "second", | 
 | 2622 | 		"microsecond", NULL | 
 | 2623 | 	}; | 
 | 2624 |  | 
 | 2625 | 	if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiii", keywords, | 
 | 2626 | 					&year, &month, &day, &hour, &minute, | 
 | 2627 | 					&second, &usecond)) { | 
 | 2628 | 		if (check_date_args(year, month, day) < 0) | 
 | 2629 | 			return NULL; | 
 | 2630 | 		if (check_time_args(hour, minute, second, usecond) < 0) | 
 | 2631 | 			return NULL; | 
 | 2632 | 		self = new_datetime(year, month, day, | 
 | 2633 | 				    hour, minute, second, usecond); | 
 | 2634 | 	} | 
 | 2635 | 	return self; | 
 | 2636 | } | 
 | 2637 |  | 
 | 2638 |  | 
 | 2639 | /* TM_FUNC is the shared type of localtime() and gmtime(). */ | 
 | 2640 | typedef struct tm *(*TM_FUNC)(const time_t *timer); | 
 | 2641 |  | 
 | 2642 | /* Internal helper. | 
 | 2643 |  * Build datetime from a time_t and a distinct count of microseconds. | 
 | 2644 |  * Pass localtime or gmtime for f, to control the interpretation of timet. | 
 | 2645 |  */ | 
 | 2646 | static PyObject * | 
 | 2647 | datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us) | 
 | 2648 | { | 
 | 2649 | 	struct tm *tm; | 
 | 2650 | 	PyObject *result = NULL; | 
 | 2651 |  | 
 | 2652 | 	tm = f(&timet); | 
 | 2653 | 	if (tm) | 
 | 2654 | 		result = PyObject_CallFunction(cls, "iiiiiii", | 
 | 2655 | 					       tm->tm_year + 1900, | 
 | 2656 | 					       tm->tm_mon + 1, | 
 | 2657 | 					       tm->tm_mday, | 
 | 2658 | 					       tm->tm_hour, | 
 | 2659 | 					       tm->tm_min, | 
 | 2660 | 					       tm->tm_sec, | 
 | 2661 | 					       us); | 
 | 2662 | 	else | 
 | 2663 | 		PyErr_SetString(PyExc_ValueError, | 
 | 2664 | 				"timestamp out of range for " | 
 | 2665 | 				"platform localtime()/gmtime() function"); | 
 | 2666 | 	return result; | 
 | 2667 | } | 
 | 2668 |  | 
 | 2669 | /* Internal helper. | 
 | 2670 |  * Build datetime from a Python timestamp.  Pass localtime or gmtime for f, | 
 | 2671 |  * to control the interpretation of the timestamp.  Since a double doesn't | 
 | 2672 |  * have enough bits to cover a datetime's full range of precision, it's | 
 | 2673 |  * better to call datetime_from_timet_and_us provided you have a way | 
 | 2674 |  * to get that much precision (e.g., C time() isn't good enough). | 
 | 2675 |  */ | 
 | 2676 | static PyObject * | 
 | 2677 | datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp) | 
 | 2678 | { | 
 | 2679 | 	time_t timet = (time_t)timestamp; | 
 | 2680 | 	int us = (int)((timestamp - (double)timet) * 1e6); | 
 | 2681 |  | 
 | 2682 | 	return datetime_from_timet_and_us(cls, f, timet, us); | 
 | 2683 | } | 
 | 2684 |  | 
 | 2685 | /* Internal helper. | 
 | 2686 |  * Build most accurate possible datetime for current time.  Pass localtime or | 
 | 2687 |  * gmtime for f as appropriate. | 
 | 2688 |  */ | 
 | 2689 | static PyObject * | 
 | 2690 | datetime_best_possible(PyObject *cls, TM_FUNC f) | 
 | 2691 | { | 
 | 2692 | #ifdef HAVE_GETTIMEOFDAY | 
 | 2693 | 	struct timeval t; | 
 | 2694 |  | 
 | 2695 | #ifdef GETTIMEOFDAY_NO_TZ | 
 | 2696 | 	gettimeofday(&t); | 
 | 2697 | #else | 
 | 2698 | 	gettimeofday(&t, (struct timezone *)NULL); | 
 | 2699 | #endif | 
 | 2700 | 	return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec); | 
 | 2701 |  | 
 | 2702 | #else	/* ! HAVE_GETTIMEOFDAY */ | 
 | 2703 | 	/* No flavor of gettimeofday exists on this platform.  Python's | 
 | 2704 | 	 * time.time() does a lot of other platform tricks to get the | 
 | 2705 | 	 * best time it can on the platform, and we're not going to do | 
 | 2706 | 	 * better than that (if we could, the better code would belong | 
 | 2707 | 	 * in time.time()!)  We're limited by the precision of a double, | 
 | 2708 | 	 * though. | 
 | 2709 | 	 */ | 
 | 2710 | 	PyObject *time; | 
 | 2711 | 	double dtime; | 
 | 2712 |  | 
 | 2713 | 	time = time_time(); | 
 | 2714 |     	if (time == NULL) | 
 | 2715 |     		return NULL; | 
 | 2716 | 	dtime = PyFloat_AsDouble(time); | 
 | 2717 | 	Py_DECREF(time); | 
 | 2718 | 	if (dtime == -1.0 && PyErr_Occurred()) | 
 | 2719 | 		return NULL; | 
 | 2720 | 	return datetime_from_timestamp(cls, f, dtime); | 
 | 2721 | #endif	/* ! HAVE_GETTIMEOFDAY */ | 
 | 2722 | } | 
 | 2723 |  | 
 | 2724 | /* Return new local datetime from timestamp (Python timestamp -- a double). */ | 
 | 2725 | static PyObject * | 
 | 2726 | datetime_fromtimestamp(PyObject *cls, PyObject *args) | 
 | 2727 | { | 
 | 2728 | 	double timestamp; | 
 | 2729 | 	PyObject *result = NULL; | 
 | 2730 |  | 
 | 2731 | 	if (PyArg_ParseTuple(args, "d:fromtimestamp", ×tamp)) | 
 | 2732 | 		result = datetime_from_timestamp(cls, localtime, timestamp); | 
 | 2733 | 	return result; | 
 | 2734 | } | 
 | 2735 |  | 
 | 2736 | /* Return new UTC datetime from timestamp (Python timestamp -- a double). */ | 
 | 2737 | static PyObject * | 
 | 2738 | datetime_utcfromtimestamp(PyObject *cls, PyObject *args) | 
 | 2739 | { | 
 | 2740 | 	double timestamp; | 
 | 2741 | 	PyObject *result = NULL; | 
 | 2742 |  | 
 | 2743 | 	if (PyArg_ParseTuple(args, "d:utcfromtimestamp", ×tamp)) | 
 | 2744 | 		result = datetime_from_timestamp(cls, gmtime, timestamp); | 
 | 2745 | 	return result; | 
 | 2746 | } | 
 | 2747 |  | 
 | 2748 | /* Return best possible local time -- this isn't constrained by the | 
 | 2749 |  * precision of a timestamp. | 
 | 2750 |  */ | 
 | 2751 | static PyObject * | 
 | 2752 | datetime_now(PyObject *cls, PyObject *dummy) | 
 | 2753 | { | 
 | 2754 | 	return datetime_best_possible(cls, localtime); | 
 | 2755 | } | 
 | 2756 |  | 
 | 2757 | /* Return best possible UTC time -- this isn't constrained by the | 
 | 2758 |  * precision of a timestamp. | 
 | 2759 |  */ | 
 | 2760 | static PyObject * | 
 | 2761 | datetime_utcnow(PyObject *cls, PyObject *dummy) | 
 | 2762 | { | 
 | 2763 | 	return datetime_best_possible(cls, gmtime); | 
 | 2764 | } | 
 | 2765 |  | 
 | 2766 | /* Return new datetime or datetimetz from date/datetime/datetimetz and | 
 | 2767 |  * time/timetz arguments. | 
 | 2768 |  */ | 
 | 2769 | static PyObject * | 
 | 2770 | datetime_combine(PyObject *cls, PyObject *args, PyObject *kw) | 
 | 2771 | { | 
 | 2772 |  	static char *keywords[] = {"date", "time", NULL}; | 
 | 2773 | 	PyObject *date; | 
 | 2774 | 	PyObject *time; | 
 | 2775 | 	PyObject *result = NULL; | 
 | 2776 |  | 
 | 2777 | 	if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords, | 
 | 2778 | 					&PyDateTime_DateType, &date, | 
 | 2779 | 					&PyDateTime_TimeType, &time)) | 
 | 2780 | 		result = PyObject_CallFunction(cls, "iiiiiii", | 
 | 2781 | 						GET_YEAR(date), | 
 | 2782 | 				    		GET_MONTH(date), | 
 | 2783 | 						GET_DAY(date), | 
 | 2784 | 				    		TIME_GET_HOUR(time), | 
 | 2785 | 				    		TIME_GET_MINUTE(time), | 
 | 2786 | 				    		TIME_GET_SECOND(time), | 
 | 2787 | 				    		TIME_GET_MICROSECOND(time)); | 
 | 2788 | 	if (result && PyTimeTZ_Check(time) && PyDateTimeTZ_Check(result)) { | 
 | 2789 | 		/* Copy the tzinfo field. */ | 
 | 2790 | 		PyObject *tzinfo = ((PyDateTime_TimeTZ *)time)->tzinfo; | 
 | 2791 | 		Py_INCREF(tzinfo); | 
 | 2792 | 		Py_DECREF(((PyDateTime_DateTimeTZ *)result)->tzinfo); | 
 | 2793 | 		((PyDateTime_DateTimeTZ *)result)->tzinfo = tzinfo; | 
 | 2794 | 	} | 
 | 2795 | 	return result; | 
 | 2796 | } | 
 | 2797 |  | 
 | 2798 | /* datetime arithmetic. */ | 
 | 2799 |  | 
 | 2800 | static PyObject * | 
 | 2801 | add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta) | 
 | 2802 | { | 
 | 2803 | 	/* Note that the C-level additions can't overflow, because of | 
 | 2804 | 	 * invariant bounds on the member values. | 
 | 2805 | 	 */ | 
 | 2806 | 	int year = GET_YEAR(date); | 
 | 2807 | 	int month = GET_MONTH(date); | 
 | 2808 | 	int day = GET_DAY(date) + GET_TD_DAYS(delta); | 
 | 2809 | 	int hour = DATE_GET_HOUR(date); | 
 | 2810 | 	int minute = DATE_GET_MINUTE(date); | 
 | 2811 | 	int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta); | 
 | 2812 | 	int microsecond = DATE_GET_MICROSECOND(date) + | 
 | 2813 | 			  GET_TD_MICROSECONDS(delta); | 
 | 2814 |  | 
 | 2815 | 	if (normalize_datetime(&year, &month, &day, | 
 | 2816 | 			       &hour, &minute, &second, µsecond) < 0) | 
 | 2817 | 		return NULL; | 
 | 2818 | 	else | 
 | 2819 | 		return new_datetime(year, month, day, | 
 | 2820 | 				    hour, minute, second, microsecond); | 
 | 2821 | } | 
 | 2822 |  | 
 | 2823 | static PyObject * | 
 | 2824 | sub_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta) | 
 | 2825 | { | 
 | 2826 | 	/* Note that the C-level subtractions can't overflow, because of | 
 | 2827 | 	 * invariant bounds on the member values. | 
 | 2828 | 	 */ | 
 | 2829 | 	int year = GET_YEAR(date); | 
 | 2830 | 	int month = GET_MONTH(date); | 
 | 2831 | 	int day = GET_DAY(date) - GET_TD_DAYS(delta); | 
 | 2832 | 	int hour = DATE_GET_HOUR(date); | 
 | 2833 | 	int minute = DATE_GET_MINUTE(date); | 
 | 2834 | 	int second = DATE_GET_SECOND(date) - GET_TD_SECONDS(delta); | 
 | 2835 | 	int microsecond = DATE_GET_MICROSECOND(date) - | 
 | 2836 | 			  GET_TD_MICROSECONDS(delta); | 
 | 2837 |  | 
 | 2838 | 	if (normalize_datetime(&year, &month, &day, | 
 | 2839 | 			       &hour, &minute, &second, µsecond) < 0) | 
 | 2840 | 		return NULL; | 
 | 2841 | 	else | 
 | 2842 | 		return new_datetime(year, month, day, | 
 | 2843 | 				    hour, minute, second, microsecond); | 
 | 2844 | } | 
 | 2845 |  | 
 | 2846 | static PyObject * | 
 | 2847 | sub_datetime_datetime(PyDateTime_DateTime *left, PyDateTime_DateTime *right) | 
 | 2848 | { | 
 | 2849 | 	int days1 = ymd_to_ord(GET_YEAR(left), GET_MONTH(left), GET_DAY(left)); | 
 | 2850 | 	int days2 = ymd_to_ord(GET_YEAR(right), | 
 | 2851 | 			       GET_MONTH(right), | 
 | 2852 | 			       GET_DAY(right)); | 
 | 2853 | 	/* These can't overflow, since the values are normalized.  At most | 
 | 2854 | 	 * this gives the number of seconds in one day. | 
 | 2855 | 	 */ | 
 | 2856 | 	int delta_s = (DATE_GET_HOUR(left) - DATE_GET_HOUR(right)) * 3600 + | 
 | 2857 | 	              (DATE_GET_MINUTE(left) - DATE_GET_MINUTE(right)) * 60 + | 
 | 2858 | 		      DATE_GET_SECOND(left) - DATE_GET_SECOND(right); | 
 | 2859 | 	int delta_us = DATE_GET_MICROSECOND(left) - | 
 | 2860 | 		       DATE_GET_MICROSECOND(right); | 
 | 2861 |  | 
 | 2862 | 	return new_delta(days1 - days2, delta_s, delta_us, 1); | 
 | 2863 | } | 
 | 2864 |  | 
 | 2865 | static PyObject * | 
 | 2866 | datetime_add(PyObject *left, PyObject *right) | 
 | 2867 | { | 
 | 2868 | 	if (PyDateTime_Check(left)) { | 
 | 2869 | 		/* datetime + ??? */ | 
 | 2870 | 		if (PyDelta_Check(right)) | 
 | 2871 | 			/* datetime + delta */ | 
 | 2872 | 			return add_datetime_timedelta( | 
 | 2873 | 					(PyDateTime_DateTime *)left, | 
 | 2874 | 					(PyDateTime_Delta *)right); | 
 | 2875 | 	} | 
 | 2876 | 	else if (PyDelta_Check(left)) { | 
 | 2877 | 		/* delta + datetime */ | 
 | 2878 | 		return add_datetime_timedelta((PyDateTime_DateTime *) right, | 
 | 2879 | 					      (PyDateTime_Delta *) left); | 
 | 2880 | 	} | 
 | 2881 | 	Py_INCREF(Py_NotImplemented); | 
 | 2882 | 	return Py_NotImplemented; | 
 | 2883 | } | 
 | 2884 |  | 
 | 2885 | static PyObject * | 
 | 2886 | datetime_subtract(PyObject *left, PyObject *right) | 
 | 2887 | { | 
 | 2888 | 	PyObject *result = Py_NotImplemented; | 
 | 2889 |  | 
 | 2890 | 	if (PyDateTime_Check(left)) { | 
 | 2891 | 		/* datetime - ??? */ | 
 | 2892 | 		if (PyDateTime_Check(right)) { | 
 | 2893 | 			/* datetime - datetime */ | 
 | 2894 | 			result = sub_datetime_datetime( | 
 | 2895 | 					(PyDateTime_DateTime *)left, | 
 | 2896 | 					(PyDateTime_DateTime *)right); | 
 | 2897 | 		} | 
 | 2898 | 		else if (PyDelta_Check(right)) { | 
 | 2899 | 			/* datetime - delta */ | 
 | 2900 | 			result = sub_datetime_timedelta( | 
 | 2901 | 					(PyDateTime_DateTime *)left, | 
 | 2902 | 					(PyDateTime_Delta *)right); | 
 | 2903 | 		} | 
 | 2904 | 	} | 
 | 2905 |  | 
 | 2906 | 	if (result == Py_NotImplemented) | 
 | 2907 | 		Py_INCREF(result); | 
 | 2908 | 	return result; | 
 | 2909 | } | 
 | 2910 |  | 
 | 2911 | /* Various ways to turn a datetime into a string. */ | 
 | 2912 |  | 
 | 2913 | static PyObject * | 
 | 2914 | datetime_repr(PyDateTime_DateTime *self) | 
 | 2915 | { | 
 | 2916 | 	char buffer[1000]; | 
 | 2917 | 	char *typename = self->ob_type->tp_name; | 
 | 2918 |  | 
 | 2919 | 	if (DATE_GET_MICROSECOND(self)) { | 
 | 2920 | 		PyOS_snprintf(buffer, sizeof(buffer), | 
 | 2921 | 			      "%s(%d, %d, %d, %d, %d, %d, %d)", | 
 | 2922 | 			      typename, | 
 | 2923 | 			      GET_YEAR(self), GET_MONTH(self), GET_DAY(self), | 
 | 2924 | 			      DATE_GET_HOUR(self), DATE_GET_MINUTE(self), | 
 | 2925 | 			      DATE_GET_SECOND(self), | 
 | 2926 | 			      DATE_GET_MICROSECOND(self)); | 
 | 2927 | 	} | 
 | 2928 | 	else if (DATE_GET_SECOND(self)) { | 
 | 2929 | 		PyOS_snprintf(buffer, sizeof(buffer), | 
 | 2930 | 			      "%s(%d, %d, %d, %d, %d, %d)", | 
 | 2931 | 			      typename, | 
 | 2932 | 			      GET_YEAR(self), GET_MONTH(self), GET_DAY(self), | 
 | 2933 | 			      DATE_GET_HOUR(self), DATE_GET_MINUTE(self), | 
 | 2934 | 			      DATE_GET_SECOND(self)); | 
 | 2935 | 	} | 
 | 2936 | 	else { | 
 | 2937 | 		PyOS_snprintf(buffer, sizeof(buffer), | 
 | 2938 | 			      "%s(%d, %d, %d, %d, %d)", | 
 | 2939 | 			      typename, | 
 | 2940 | 			      GET_YEAR(self), GET_MONTH(self), GET_DAY(self), | 
 | 2941 | 			      DATE_GET_HOUR(self), DATE_GET_MINUTE(self)); | 
 | 2942 | 	} | 
 | 2943 | 	return PyString_FromString(buffer); | 
 | 2944 | } | 
 | 2945 |  | 
 | 2946 | static PyObject * | 
 | 2947 | datetime_str(PyDateTime_DateTime *self) | 
 | 2948 | { | 
 | 2949 | 	return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " "); | 
 | 2950 | } | 
 | 2951 |  | 
 | 2952 | static PyObject * | 
 | 2953 | datetime_isoformat(PyDateTime_DateTime *self, | 
 | 2954 |                    PyObject *args, PyObject *kw) | 
 | 2955 | { | 
 | 2956 | 	char sep = 'T'; | 
 | 2957 | 	static char *keywords[] = {"sep", NULL}; | 
 | 2958 | 	char buffer[100]; | 
 | 2959 | 	char *cp; | 
 | 2960 |  | 
 | 2961 | 	if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords, | 
 | 2962 | 					 &sep)) | 
 | 2963 | 		return NULL; | 
 | 2964 | 	cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer)); | 
 | 2965 | 	assert(cp != NULL); | 
 | 2966 | 	*cp++ = sep; | 
 | 2967 | 	isoformat_time(self, cp, sizeof(buffer) - (cp - buffer)); | 
 | 2968 | 	return PyString_FromString(buffer); | 
 | 2969 | } | 
 | 2970 |  | 
 | 2971 | static PyObject * | 
 | 2972 | datetime_ctime(PyDateTime_DateTime *self) | 
 | 2973 | { | 
 | 2974 | 	return format_ctime((PyDateTime_Date *)self, | 
 | 2975 | 			    DATE_GET_HOUR(self), | 
 | 2976 | 			    DATE_GET_MINUTE(self), | 
 | 2977 | 			    DATE_GET_SECOND(self)); | 
 | 2978 | } | 
 | 2979 |  | 
 | 2980 | /* Miscellaneous methods. */ | 
 | 2981 |  | 
 | 2982 | /* This is more natural as a tp_compare, but doesn't work then:  for whatever | 
 | 2983 |  * reason, Python's try_3way_compare ignores tp_compare unless | 
 | 2984 |  * PyInstance_Check returns true, but these aren't old-style classes. | 
 | 2985 |  * Note that this routine handles all comparisons for datetime and datetimetz. | 
 | 2986 |  */ | 
 | 2987 | static PyObject * | 
 | 2988 | datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op) | 
 | 2989 | { | 
 | 2990 | 	int diff; | 
 | 2991 | 	naivety n1, n2; | 
 | 2992 | 	int offset1, offset2; | 
 | 2993 |  | 
 | 2994 | 	if (! PyDateTime_Check(other)) { | 
 | 2995 | 		/* Stop this from falling back to address comparison. */ | 
 | 2996 | 		PyErr_Format(PyExc_TypeError, | 
 | 2997 | 			     "can't compare '%s' to '%s'", | 
 | 2998 | 			     self->ob_type->tp_name, | 
 | 2999 | 			     other->ob_type->tp_name); | 
 | 3000 | 		return NULL; | 
 | 3001 | 	} | 
 | 3002 | 	n1 = classify_object((PyObject *)self, &offset1); | 
 | 3003 | 	assert(n1 != OFFSET_UNKNOWN); | 
 | 3004 | 	if (n1 == OFFSET_ERROR) | 
 | 3005 | 		return NULL; | 
 | 3006 |  | 
 | 3007 | 	n2 = classify_object(other, &offset2); | 
 | 3008 | 	assert(n2 != OFFSET_UNKNOWN); | 
 | 3009 | 	if (n2 == OFFSET_ERROR) | 
 | 3010 | 		return NULL; | 
 | 3011 |  | 
 | 3012 | 	/* If they're both naive, or both aware and have the same offsets, | 
 | 3013 | 	 * we get off cheap.  Note that if they're both naive, offset1 == | 
 | 3014 | 	 * offset2 == 0 at this point. | 
 | 3015 | 	 */ | 
 | 3016 | 	if (n1 == n2 && offset1 == offset2) { | 
 | 3017 | 		diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data, | 
 | 3018 | 			      _PyDateTime_DATETIME_DATASIZE); | 
 | 3019 | 		return diff_to_bool(diff, op); | 
 | 3020 | 	} | 
 | 3021 |  | 
 | 3022 | 	if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) { | 
 | 3023 | 		/* We want the sign of | 
 | 3024 | 		 *     (self - offset1 minutes) - (other - offset2 minutes) = | 
 | 3025 | 		 *     (self - other) + (offset2 - offset1) minutes. | 
 | 3026 | 		 */ | 
 | 3027 | 		PyDateTime_Delta *delta; | 
 | 3028 | 		int days, seconds, us; | 
 | 3029 |  | 
 | 3030 | 		assert(offset1 != offset2);	/* else last "if" handled it */ | 
 | 3031 | 		delta = (PyDateTime_Delta *)sub_datetime_datetime(self, | 
 | 3032 | 						(PyDateTime_DateTime *)other); | 
 | 3033 | 		if (delta == NULL) | 
 | 3034 | 			return NULL; | 
 | 3035 | 		days = delta->days; | 
 | 3036 | 		seconds = delta->seconds + (offset2 - offset1) * 60; | 
 | 3037 | 		us = delta->microseconds; | 
 | 3038 | 		Py_DECREF(delta); | 
 | 3039 | 		normalize_d_s_us(&days, &seconds, &us); | 
 | 3040 | 		diff = days; | 
 | 3041 | 		if (diff == 0) | 
 | 3042 | 			diff = seconds | us; | 
 | 3043 | 		return diff_to_bool(diff, op); | 
 | 3044 | 	} | 
 | 3045 |  | 
 | 3046 | 	assert(n1 != n2); | 
 | 3047 | 	PyErr_SetString(PyExc_TypeError, | 
 | 3048 | 			"can't compare offset-naive and " | 
 | 3049 | 			"offset-aware datetimes"); | 
 | 3050 | 	return NULL; | 
 | 3051 | } | 
 | 3052 |  | 
 | 3053 | static PyObject *datetime_getstate(PyDateTime_DateTime *self); | 
 | 3054 |  | 
 | 3055 | static long | 
 | 3056 | datetime_hash(PyDateTime_DateTime *self) | 
 | 3057 | { | 
 | 3058 | 	if (self->hashcode == -1) { | 
 | 3059 | 		naivety n; | 
 | 3060 | 		int offset; | 
 | 3061 | 		PyObject *temp; | 
 | 3062 |  | 
 | 3063 | 		n = classify_object((PyObject *)self, &offset); | 
 | 3064 | 		assert(n != OFFSET_UNKNOWN); | 
 | 3065 | 		if (n == OFFSET_ERROR) | 
 | 3066 | 			return -1; | 
 | 3067 |  | 
 | 3068 | 		/* Reduce this to a hash of another object. */ | 
 | 3069 | 		if (n == OFFSET_NAIVE) | 
 | 3070 | 			temp = datetime_getstate(self); | 
 | 3071 | 		else { | 
 | 3072 | 			int days; | 
 | 3073 | 			int seconds; | 
 | 3074 |  | 
 | 3075 | 			assert(n == OFFSET_AWARE); | 
 | 3076 | 			assert(PyDateTimeTZ_Check(self)); | 
 | 3077 | 			days = ymd_to_ord(GET_YEAR(self), | 
 | 3078 | 					  GET_MONTH(self), | 
 | 3079 | 					  GET_DAY(self)); | 
 | 3080 | 			seconds = DATE_GET_HOUR(self) * 3600 + | 
 | 3081 | 				  (DATE_GET_MINUTE(self) - offset) * 60 + | 
 | 3082 | 				  DATE_GET_SECOND(self); | 
 | 3083 | 			temp = new_delta(days, | 
 | 3084 | 					 seconds, | 
 | 3085 | 					 DATE_GET_MICROSECOND(self), | 
 | 3086 | 					 1); | 
 | 3087 | 		} | 
 | 3088 | 		if (temp != NULL) { | 
 | 3089 | 			self->hashcode = PyObject_Hash(temp); | 
 | 3090 | 			Py_DECREF(temp); | 
 | 3091 | 		} | 
 | 3092 | 	} | 
 | 3093 | 	return self->hashcode; | 
 | 3094 | } | 
 | 3095 |  | 
 | 3096 | static PyObject * | 
 | 3097 | datetime_timetuple(PyDateTime_DateTime *self) | 
 | 3098 | { | 
 | 3099 | 	return build_struct_time(GET_YEAR(self), | 
 | 3100 | 				 GET_MONTH(self), | 
 | 3101 | 				 GET_DAY(self), | 
 | 3102 | 				 DATE_GET_HOUR(self), | 
 | 3103 | 				 DATE_GET_MINUTE(self), | 
 | 3104 | 				 DATE_GET_SECOND(self), | 
 | 3105 | 				 -1); | 
 | 3106 | } | 
 | 3107 |  | 
 | 3108 | static PyObject * | 
 | 3109 | datetime_getdate(PyDateTime_DateTime *self) | 
 | 3110 | { | 
 | 3111 | 	return new_date(GET_YEAR(self), | 
 | 3112 | 			GET_MONTH(self), | 
 | 3113 | 			GET_DAY(self)); | 
 | 3114 | } | 
 | 3115 |  | 
 | 3116 | static PyObject * | 
 | 3117 | datetime_gettime(PyDateTime_DateTime *self) | 
 | 3118 | { | 
 | 3119 | 	return new_time(DATE_GET_HOUR(self), | 
 | 3120 | 			DATE_GET_MINUTE(self), | 
 | 3121 | 			DATE_GET_SECOND(self), | 
 | 3122 | 			DATE_GET_MICROSECOND(self)); | 
 | 3123 | } | 
 | 3124 |  | 
 | 3125 | /* Pickle support.  Quite a maze! */ | 
 | 3126 |  | 
 | 3127 | static PyObject * | 
 | 3128 | datetime_getstate(PyDateTime_DateTime *self) | 
 | 3129 | { | 
 | 3130 | 	return PyString_FromStringAndSize(self->data, | 
 | 3131 | 					  _PyDateTime_DATETIME_DATASIZE); | 
 | 3132 | } | 
 | 3133 |  | 
 | 3134 | static PyObject * | 
 | 3135 | datetime_setstate(PyDateTime_DateTime *self, PyObject *state) | 
 | 3136 | { | 
 | 3137 | 	const int len = PyString_Size(state); | 
 | 3138 | 	unsigned char *pdata = (unsigned char*)PyString_AsString(state); | 
 | 3139 |  | 
 | 3140 | 	if (! PyString_Check(state) || | 
 | 3141 | 	    len != _PyDateTime_DATETIME_DATASIZE) { | 
 | 3142 | 		PyErr_SetString(PyExc_TypeError, | 
 | 3143 | 				"bad argument to datetime.__setstate__"); | 
 | 3144 | 		return NULL; | 
 | 3145 | 	} | 
 | 3146 | 	memcpy(self->data, pdata, _PyDateTime_DATETIME_DATASIZE); | 
 | 3147 | 	self->hashcode = -1; | 
 | 3148 |  | 
 | 3149 | 	Py_INCREF(Py_None); | 
 | 3150 | 	return Py_None; | 
 | 3151 | } | 
 | 3152 |  | 
 | 3153 | /* XXX This seems a ridiculously inefficient way to pickle a short string. */ | 
 | 3154 | static PyObject * | 
 | 3155 | datetime_pickler(PyObject *module, PyDateTime_DateTime *datetime) | 
 | 3156 | { | 
 | 3157 | 	PyObject *state; | 
 | 3158 | 	PyObject *result = NULL; | 
 | 3159 |  | 
 | 3160 | 	if (! PyDateTime_CheckExact(datetime)) { | 
 | 3161 | 		PyErr_Format(PyExc_TypeError, | 
 | 3162 | 			     "bad type passed to datetime pickler: %s", | 
 | 3163 | 			     datetime->ob_type->tp_name); | 
 | 3164 | 		return NULL; | 
 | 3165 | 	} | 
 | 3166 | 	state = datetime_getstate(datetime); | 
 | 3167 | 	if (state) { | 
 | 3168 | 		result = Py_BuildValue("O(O)", | 
 | 3169 | 				       datetime_unpickler_object, | 
 | 3170 | 				       state); | 
 | 3171 | 		Py_DECREF(state); | 
 | 3172 | 	} | 
 | 3173 | 	return result; | 
 | 3174 | } | 
 | 3175 |  | 
 | 3176 | static PyObject * | 
 | 3177 | datetime_unpickler(PyObject *module, PyObject *arg) | 
 | 3178 | { | 
 | 3179 | 	PyDateTime_DateTime *self; | 
 | 3180 |  | 
 | 3181 | 	if (! PyString_CheckExact(arg)) { | 
 | 3182 | 		PyErr_Format(PyExc_TypeError, | 
 | 3183 | 			     "bad type passed to datetime unpickler: %s", | 
 | 3184 | 			     arg->ob_type->tp_name); | 
 | 3185 | 		return NULL; | 
 | 3186 | 	} | 
 | 3187 | 	self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType); | 
 | 3188 | 	if (self != NULL) { | 
 | 3189 | 		PyObject *res = datetime_setstate(self, arg); | 
 | 3190 | 		if (res == NULL) { | 
 | 3191 | 			Py_DECREF(self); | 
 | 3192 | 			return NULL; | 
 | 3193 | 		} | 
 | 3194 | 		Py_DECREF(res); | 
 | 3195 | 	} | 
 | 3196 | 	return (PyObject *)self; | 
 | 3197 | } | 
 | 3198 |  | 
 | 3199 | static PyMethodDef datetime_methods[] = { | 
 | 3200 | 	/* Class methods: */ | 
 | 3201 | 	{"now",         (PyCFunction)datetime_now, | 
 | 3202 | 	 METH_NOARGS | METH_CLASS, | 
 | 3203 | 	 PyDoc_STR("Return a new datetime representing local day and time.")}, | 
 | 3204 |  | 
 | 3205 | 	{"utcnow",         (PyCFunction)datetime_utcnow, | 
 | 3206 | 	 METH_NOARGS | METH_CLASS, | 
 | 3207 | 	 PyDoc_STR("Return a new datetime representing UTC day and time.")}, | 
 | 3208 |  | 
 | 3209 | 	{"fromtimestamp", (PyCFunction)datetime_fromtimestamp, | 
 | 3210 | 	 METH_VARARGS | METH_CLASS, | 
 | 3211 | 	 PyDoc_STR("timestamp -> local datetime from a POSIX timestamp " | 
 | 3212 | 	 	   "(like time.time()).")}, | 
 | 3213 |  | 
 | 3214 | 	{"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp, | 
 | 3215 | 	 METH_VARARGS | METH_CLASS, | 
 | 3216 | 	 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp " | 
 | 3217 | 	 	   "(like time.time()).")}, | 
 | 3218 |  | 
 | 3219 | 	{"combine", (PyCFunction)datetime_combine, | 
 | 3220 | 	 METH_VARARGS | METH_KEYWORDS | METH_CLASS, | 
 | 3221 | 	 PyDoc_STR("date, time -> datetime with same date and time fields")}, | 
 | 3222 |  | 
 | 3223 | 	/* Instance methods: */ | 
 | 3224 | 	{"timetuple",   (PyCFunction)datetime_timetuple, METH_NOARGS, | 
 | 3225 |          PyDoc_STR("Return time tuple, compatible with time.localtime().")}, | 
 | 3226 |  | 
 | 3227 | 	{"date",   (PyCFunction)datetime_getdate, METH_NOARGS, | 
 | 3228 |          PyDoc_STR("Return date object with same year, month and day.")}, | 
 | 3229 |  | 
 | 3230 | 	{"time",   (PyCFunction)datetime_gettime, METH_NOARGS, | 
 | 3231 |          PyDoc_STR("Return time object with same hour, minute, second and " | 
 | 3232 |          	   "microsecond.")}, | 
 | 3233 |  | 
 | 3234 | 	{"ctime",       (PyCFunction)datetime_ctime,	METH_NOARGS, | 
 | 3235 | 	 PyDoc_STR("Return ctime() style string.")}, | 
 | 3236 |  | 
 | 3237 | 	{"isoformat",   (PyCFunction)datetime_isoformat, METH_KEYWORDS, | 
 | 3238 | 	 PyDoc_STR("[sep] -> string in ISO 8601 format, " | 
 | 3239 | 	 	   "YYYY-MM-DDTHH:MM:SS[.mmmmmm].\n\n" | 
 | 3240 | 	 	   "sep is used to separate the year from the time, and " | 
 | 3241 | 	 	   "defaults\n" | 
 | 3242 | 	 	   "to 'T'.")}, | 
 | 3243 |  | 
 | 3244 | 	{"__setstate__", (PyCFunction)datetime_setstate, METH_O, | 
 | 3245 | 	 PyDoc_STR("__setstate__(state)")}, | 
 | 3246 |  | 
 | 3247 | 	{"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS, | 
 | 3248 | 	 PyDoc_STR("__getstate__() -> state")}, | 
 | 3249 | 	{NULL,	NULL} | 
 | 3250 | }; | 
 | 3251 |  | 
 | 3252 | static char datetime_doc[] = | 
 | 3253 | PyDoc_STR("Basic date/time type."); | 
 | 3254 |  | 
 | 3255 | static PyNumberMethods datetime_as_number = { | 
 | 3256 | 	datetime_add,				/* nb_add */ | 
 | 3257 | 	datetime_subtract,			/* nb_subtract */ | 
 | 3258 | 	0,					/* nb_multiply */ | 
 | 3259 | 	0,					/* nb_divide */ | 
 | 3260 | 	0,					/* nb_remainder */ | 
 | 3261 | 	0,					/* nb_divmod */ | 
 | 3262 | 	0,					/* nb_power */ | 
 | 3263 | 	0,					/* nb_negative */ | 
 | 3264 | 	0,					/* nb_positive */ | 
 | 3265 | 	0,					/* nb_absolute */ | 
 | 3266 | 	0,					/* nb_nonzero */ | 
 | 3267 | }; | 
 | 3268 |  | 
 | 3269 | statichere PyTypeObject PyDateTime_DateTimeType = { | 
 | 3270 | 	PyObject_HEAD_INIT(NULL) | 
 | 3271 | 	0,					/* ob_size */ | 
 | 3272 | 	"datetime.datetime",			/* tp_name */ | 
 | 3273 | 	sizeof(PyDateTime_DateTime),		/* tp_basicsize */ | 
 | 3274 | 	0,					/* tp_itemsize */ | 
 | 3275 | 	(destructor)PyObject_Del,		/* tp_dealloc */ | 
 | 3276 | 	0,					/* tp_print */ | 
 | 3277 | 	0,					/* tp_getattr */ | 
 | 3278 | 	0,					/* tp_setattr */ | 
 | 3279 | 	0,					/* tp_compare */ | 
 | 3280 | 	(reprfunc)datetime_repr,		/* tp_repr */ | 
 | 3281 | 	&datetime_as_number,			/* tp_as_number */ | 
 | 3282 | 	0,					/* tp_as_sequence */ | 
 | 3283 | 	0,					/* tp_as_mapping */ | 
 | 3284 | 	(hashfunc)datetime_hash,		/* tp_hash */ | 
 | 3285 | 	0,              			/* tp_call */ | 
 | 3286 | 	(reprfunc)datetime_str,			/* tp_str */ | 
 | 3287 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 3288 | 	0,					/* tp_setattro */ | 
 | 3289 | 	0,					/* tp_as_buffer */ | 
 | 3290 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | | 
 | 3291 |         Py_TPFLAGS_BASETYPE,			/* tp_flags */ | 
 | 3292 | 	datetime_doc,				/* tp_doc */ | 
 | 3293 | 	0,					/* tp_traverse */ | 
 | 3294 | 	0,					/* tp_clear */ | 
 | 3295 | 	(richcmpfunc)datetime_richcompare,	/* tp_richcompare */ | 
 | 3296 | 	0,					/* tp_weaklistoffset */ | 
 | 3297 | 	0,					/* tp_iter */ | 
 | 3298 | 	0,					/* tp_iternext */ | 
 | 3299 | 	datetime_methods,			/* tp_methods */ | 
 | 3300 | 	0,					/* tp_members */ | 
 | 3301 | 	datetime_getset,			/* tp_getset */ | 
 | 3302 | 	&PyDateTime_DateType,			/* tp_base */ | 
 | 3303 | 	0,					/* tp_dict */ | 
 | 3304 | 	0,					/* tp_descr_get */ | 
 | 3305 | 	0,					/* tp_descr_set */ | 
 | 3306 | 	0,					/* tp_dictoffset */ | 
 | 3307 | 	0,					/* tp_init */ | 
 | 3308 | 	0,					/* tp_alloc */ | 
 | 3309 | 	datetime_new,				/* tp_new */ | 
 | 3310 | 	_PyObject_Del,				/* tp_free */ | 
 | 3311 | }; | 
 | 3312 |  | 
 | 3313 | /* | 
 | 3314 |  * PyDateTime_Time implementation. | 
 | 3315 |  */ | 
 | 3316 |  | 
 | 3317 | /* Accessor properties. */ | 
 | 3318 |  | 
 | 3319 | static PyObject * | 
 | 3320 | time_hour(PyDateTime_Time *self, void *unused) | 
 | 3321 | { | 
 | 3322 | 	return PyInt_FromLong(TIME_GET_HOUR(self)); | 
 | 3323 | } | 
 | 3324 |  | 
 | 3325 | static PyObject * | 
 | 3326 | time_minute(PyDateTime_Time *self, void *unused) | 
 | 3327 | { | 
 | 3328 | 	return PyInt_FromLong(TIME_GET_MINUTE(self)); | 
 | 3329 | } | 
 | 3330 |  | 
 | 3331 | static PyObject * | 
| Jack Jansen | 51cd8a2 | 2002-12-17 20:57:24 +0000 | [diff] [blame] | 3332 | py_time_second(PyDateTime_Time *self, void *unused) | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 3333 | { | 
 | 3334 | 	return PyInt_FromLong(TIME_GET_SECOND(self)); | 
 | 3335 | } | 
 | 3336 |  | 
 | 3337 | static PyObject * | 
 | 3338 | time_microsecond(PyDateTime_Time *self, void *unused) | 
 | 3339 | { | 
 | 3340 | 	return PyInt_FromLong(TIME_GET_MICROSECOND(self)); | 
 | 3341 | } | 
 | 3342 |  | 
 | 3343 | static PyGetSetDef time_getset[] = { | 
 | 3344 | 	{"hour",        (getter)time_hour}, | 
 | 3345 | 	{"minute",      (getter)time_minute}, | 
| Jack Jansen | 51cd8a2 | 2002-12-17 20:57:24 +0000 | [diff] [blame] | 3346 | 	{"second",      (getter)py_time_second}, | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 3347 | 	{"microsecond", (getter)time_microsecond}, | 
 | 3348 | 	{NULL} | 
 | 3349 | }; | 
 | 3350 |  | 
 | 3351 | /* Constructors. */ | 
 | 3352 |  | 
 | 3353 | static PyObject * | 
 | 3354 | time_new(PyTypeObject *type, PyObject *args, PyObject *kw) | 
 | 3355 | { | 
 | 3356 | 	PyObject *self = NULL; | 
 | 3357 | 	int hour = 0; | 
 | 3358 | 	int minute = 0; | 
 | 3359 | 	int second = 0; | 
 | 3360 | 	int usecond = 0; | 
 | 3361 |  | 
 | 3362 | 	static char *keywords[] = { | 
 | 3363 | 		"hour", "minute", "second", "microsecond", NULL | 
 | 3364 | 	}; | 
 | 3365 |  | 
 | 3366 | 	if (PyArg_ParseTupleAndKeywords(args, kw, "|iiii", keywords, | 
 | 3367 | 					&hour, &minute, &second, &usecond)) { | 
 | 3368 | 		if (check_time_args(hour, minute, second, usecond) < 0) | 
 | 3369 | 			return NULL; | 
 | 3370 | 		self = new_time(hour, minute, second, usecond); | 
 | 3371 | 	} | 
 | 3372 | 	return self; | 
 | 3373 | } | 
 | 3374 |  | 
 | 3375 | /* Various ways to turn a time into a string. */ | 
 | 3376 |  | 
 | 3377 | static PyObject * | 
 | 3378 | time_repr(PyDateTime_Time *self) | 
 | 3379 | { | 
 | 3380 | 	char buffer[100]; | 
 | 3381 | 	char *typename = self->ob_type->tp_name; | 
 | 3382 | 	int h = TIME_GET_HOUR(self); | 
 | 3383 | 	int m = TIME_GET_MINUTE(self); | 
 | 3384 | 	int s = TIME_GET_SECOND(self); | 
 | 3385 | 	int us = TIME_GET_MICROSECOND(self); | 
 | 3386 |  | 
 | 3387 | 	if (us) | 
 | 3388 | 		PyOS_snprintf(buffer, sizeof(buffer), | 
 | 3389 | 			      "%s(%d, %d, %d, %d)", typename, h, m, s, us); | 
 | 3390 | 	else if (s) | 
 | 3391 | 		PyOS_snprintf(buffer, sizeof(buffer), | 
 | 3392 | 			      "%s(%d, %d, %d)", typename, h, m, s); | 
 | 3393 | 	else | 
 | 3394 | 		PyOS_snprintf(buffer, sizeof(buffer), | 
 | 3395 | 			      "%s(%d, %d)", typename, h, m); | 
 | 3396 | 	return PyString_FromString(buffer); | 
 | 3397 | } | 
 | 3398 |  | 
 | 3399 | static PyObject * | 
 | 3400 | time_str(PyDateTime_Time *self) | 
 | 3401 | { | 
 | 3402 | 	return PyObject_CallMethod((PyObject *)self, "isoformat", "()"); | 
 | 3403 | } | 
 | 3404 |  | 
 | 3405 | static PyObject * | 
 | 3406 | time_isoformat(PyDateTime_Time *self) | 
 | 3407 | { | 
 | 3408 | 	char buffer[100]; | 
 | 3409 | 	/* Reuse the time format code from the datetime type. */ | 
 | 3410 | 	PyDateTime_DateTime datetime; | 
 | 3411 | 	PyDateTime_DateTime *pdatetime = &datetime; | 
 | 3412 |  | 
 | 3413 | 	/* Copy over just the time bytes. */ | 
 | 3414 | 	memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE, | 
 | 3415 | 	       self->data, | 
 | 3416 | 	       _PyDateTime_TIME_DATASIZE); | 
 | 3417 |  | 
 | 3418 | 	isoformat_time(pdatetime, buffer, sizeof(buffer)); | 
 | 3419 | 	return PyString_FromString(buffer); | 
 | 3420 | } | 
 | 3421 |  | 
 | 3422 | static PyObject * | 
 | 3423 | time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw) | 
 | 3424 | { | 
 | 3425 | 	PyObject *result; | 
 | 3426 | 	PyObject *format; | 
 | 3427 | 	PyObject *tuple; | 
 | 3428 | 	static char *keywords[] = {"format", NULL}; | 
 | 3429 |  | 
 | 3430 | 	if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords, | 
 | 3431 | 					  &PyString_Type, &format)) | 
 | 3432 | 		return NULL; | 
 | 3433 |  | 
 | 3434 | 	tuple = Py_BuildValue("iiiiiiiii", | 
 | 3435 | 		              0, 0, 0, /* year, month, day */ | 
 | 3436 | 			      TIME_GET_HOUR(self), | 
 | 3437 | 			      TIME_GET_MINUTE(self), | 
 | 3438 | 			      TIME_GET_SECOND(self), | 
 | 3439 | 			      0, 0, -1); /* weekday, daynum, dst */ | 
 | 3440 | 	if (tuple == NULL) | 
 | 3441 | 		return NULL; | 
 | 3442 | 	assert(PyTuple_Size(tuple) == 9); | 
 | 3443 | 	result = wrap_strftime((PyObject *)self, format, tuple); | 
 | 3444 | 	Py_DECREF(tuple); | 
 | 3445 | 	return result; | 
 | 3446 | } | 
 | 3447 |  | 
 | 3448 | /* Miscellaneous methods. */ | 
 | 3449 |  | 
 | 3450 | /* This is more natural as a tp_compare, but doesn't work then:  for whatever | 
 | 3451 |  * reason, Python's try_3way_compare ignores tp_compare unless | 
 | 3452 |  * PyInstance_Check returns true, but these aren't old-style classes. | 
 | 3453 |  * Note that this routine handles all comparisons for time and timetz. | 
 | 3454 |  */ | 
 | 3455 | static PyObject * | 
 | 3456 | time_richcompare(PyDateTime_Time *self, PyObject *other, int op) | 
 | 3457 | { | 
 | 3458 | 	int diff; | 
 | 3459 | 	naivety n1, n2; | 
 | 3460 | 	int offset1, offset2; | 
 | 3461 |  | 
 | 3462 | 	if (! PyTime_Check(other)) { | 
 | 3463 | 		/* Stop this from falling back to address comparison. */ | 
 | 3464 | 		PyErr_Format(PyExc_TypeError, | 
 | 3465 | 			     "can't compare '%s' to '%s'", | 
 | 3466 | 			     self->ob_type->tp_name, | 
 | 3467 | 			     other->ob_type->tp_name); | 
 | 3468 | 		return NULL; | 
 | 3469 | 	} | 
 | 3470 | 	n1 = classify_object((PyObject *)self, &offset1); | 
 | 3471 | 	assert(n1 != OFFSET_UNKNOWN); | 
 | 3472 | 	if (n1 == OFFSET_ERROR) | 
 | 3473 | 		return NULL; | 
 | 3474 |  | 
 | 3475 | 	n2 = classify_object(other, &offset2); | 
 | 3476 | 	assert(n2 != OFFSET_UNKNOWN); | 
 | 3477 | 	if (n2 == OFFSET_ERROR) | 
 | 3478 | 		return NULL; | 
 | 3479 |  | 
 | 3480 | 	/* If they're both naive, or both aware and have the same offsets, | 
 | 3481 | 	 * we get off cheap.  Note that if they're both naive, offset1 == | 
 | 3482 | 	 * offset2 == 0 at this point. | 
 | 3483 | 	 */ | 
 | 3484 | 	if (n1 == n2 && offset1 == offset2) { | 
 | 3485 | 		diff = memcmp(self->data, ((PyDateTime_Time *)other)->data, | 
 | 3486 | 			      _PyDateTime_TIME_DATASIZE); | 
 | 3487 | 		return diff_to_bool(diff, op); | 
 | 3488 | 	} | 
 | 3489 |  | 
 | 3490 | 	if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) { | 
 | 3491 | 		assert(offset1 != offset2);	/* else last "if" handled it */ | 
 | 3492 | 		/* Convert everything except microseconds to seconds.  These | 
 | 3493 | 		 * can't overflow (no more than the # of seconds in 2 days). | 
 | 3494 | 		 */ | 
 | 3495 | 		offset1 = TIME_GET_HOUR(self) * 3600 + | 
 | 3496 | 			  (TIME_GET_MINUTE(self) - offset1) * 60 + | 
 | 3497 | 			  TIME_GET_SECOND(self); | 
 | 3498 | 		offset2 = TIME_GET_HOUR(other) * 3600 + | 
 | 3499 | 			  (TIME_GET_MINUTE(other) - offset2) * 60 + | 
 | 3500 | 			  TIME_GET_SECOND(other); | 
 | 3501 | 		diff = offset1 - offset2; | 
 | 3502 | 		if (diff == 0) | 
 | 3503 | 			diff = TIME_GET_MICROSECOND(self) - | 
 | 3504 | 			       TIME_GET_MICROSECOND(other); | 
 | 3505 | 		return diff_to_bool(diff, op); | 
 | 3506 | 	} | 
 | 3507 |  | 
 | 3508 | 	assert(n1 != n2); | 
 | 3509 | 	PyErr_SetString(PyExc_TypeError, | 
 | 3510 | 			"can't compare offset-naive and " | 
 | 3511 | 			"offset-aware times"); | 
 | 3512 | 	return NULL; | 
 | 3513 | } | 
 | 3514 |  | 
 | 3515 | static PyObject *time_getstate(PyDateTime_Time *self); | 
 | 3516 |  | 
 | 3517 | static long | 
 | 3518 | time_hash(PyDateTime_Time *self) | 
 | 3519 | { | 
 | 3520 | 	if (self->hashcode == -1) { | 
 | 3521 | 		naivety n; | 
 | 3522 | 		int offset; | 
 | 3523 | 		PyObject *temp; | 
 | 3524 |  | 
 | 3525 | 		n = classify_object((PyObject *)self, &offset); | 
 | 3526 | 		assert(n != OFFSET_UNKNOWN); | 
 | 3527 | 		if (n == OFFSET_ERROR) | 
 | 3528 | 			return -1; | 
 | 3529 |  | 
 | 3530 | 		/* Reduce this to a hash of another object. */ | 
 | 3531 | 		if (offset == 0) | 
 | 3532 | 			temp = time_getstate(self); | 
 | 3533 | 		else { | 
 | 3534 | 			int hour; | 
 | 3535 | 			int minute; | 
 | 3536 |  | 
 | 3537 | 			assert(n == OFFSET_AWARE); | 
 | 3538 | 			assert(PyTimeTZ_Check(self)); | 
 | 3539 | 			hour = divmod(TIME_GET_HOUR(self) * 60 + | 
 | 3540 | 					TIME_GET_MINUTE(self) - offset, | 
 | 3541 | 				      60, | 
 | 3542 | 				      &minute); | 
 | 3543 | 			if (0 <= hour && hour < 24) | 
 | 3544 | 				temp = new_time(hour, minute, | 
 | 3545 | 						TIME_GET_SECOND(self), | 
 | 3546 | 						TIME_GET_MICROSECOND(self)); | 
 | 3547 | 			else | 
 | 3548 | 				temp = Py_BuildValue("iiii", | 
 | 3549 | 					   hour, minute, | 
 | 3550 | 					   TIME_GET_SECOND(self), | 
 | 3551 | 					   TIME_GET_MICROSECOND(self)); | 
 | 3552 | 		} | 
 | 3553 | 		if (temp != NULL) { | 
 | 3554 | 			self->hashcode = PyObject_Hash(temp); | 
 | 3555 | 			Py_DECREF(temp); | 
 | 3556 | 		} | 
 | 3557 | 	} | 
 | 3558 | 	return self->hashcode; | 
 | 3559 | } | 
 | 3560 |  | 
 | 3561 | static int | 
 | 3562 | time_nonzero(PyDateTime_Time *self) | 
 | 3563 | { | 
 | 3564 | 	return TIME_GET_HOUR(self) || | 
 | 3565 | 	       TIME_GET_MINUTE(self) || | 
 | 3566 | 	       TIME_GET_SECOND(self) || | 
 | 3567 | 	       TIME_GET_MICROSECOND(self); | 
 | 3568 | } | 
 | 3569 |  | 
 | 3570 | /* Pickle support.  Quite a maze! */ | 
 | 3571 |  | 
 | 3572 | static PyObject * | 
 | 3573 | time_getstate(PyDateTime_Time *self) | 
 | 3574 | { | 
 | 3575 | 	return PyString_FromStringAndSize(self->data, | 
 | 3576 | 					  _PyDateTime_TIME_DATASIZE); | 
 | 3577 | } | 
 | 3578 |  | 
 | 3579 | static PyObject * | 
 | 3580 | time_setstate(PyDateTime_Time *self, PyObject *state) | 
 | 3581 | { | 
 | 3582 | 	const int len = PyString_Size(state); | 
 | 3583 | 	unsigned char *pdata = (unsigned char*)PyString_AsString(state); | 
 | 3584 |  | 
 | 3585 | 	if (! PyString_Check(state) || | 
 | 3586 | 	    len != _PyDateTime_TIME_DATASIZE) { | 
 | 3587 | 		PyErr_SetString(PyExc_TypeError, | 
 | 3588 | 				"bad argument to time.__setstate__"); | 
 | 3589 | 		return NULL; | 
 | 3590 | 	} | 
 | 3591 | 	memcpy(self->data, pdata, _PyDateTime_TIME_DATASIZE); | 
 | 3592 | 	self->hashcode = -1; | 
 | 3593 |  | 
 | 3594 | 	Py_INCREF(Py_None); | 
 | 3595 | 	return Py_None; | 
 | 3596 | } | 
 | 3597 |  | 
 | 3598 | /* XXX This seems a ridiculously inefficient way to pickle a short string. */ | 
 | 3599 | static PyObject * | 
 | 3600 | time_pickler(PyObject *module, PyDateTime_Time *time) | 
 | 3601 | { | 
 | 3602 | 	PyObject *state; | 
 | 3603 | 	PyObject *result = NULL; | 
 | 3604 |  | 
 | 3605 | 	if (! PyTime_CheckExact(time)) { | 
 | 3606 | 		PyErr_Format(PyExc_TypeError, | 
 | 3607 | 			     "bad type passed to time pickler: %s", | 
 | 3608 | 			     time->ob_type->tp_name); | 
 | 3609 | 		return NULL; | 
 | 3610 | 	} | 
 | 3611 | 	state = time_getstate(time); | 
 | 3612 | 	if (state) { | 
 | 3613 | 		result = Py_BuildValue("O(O)", | 
 | 3614 | 				       time_unpickler_object, | 
 | 3615 | 				       state); | 
 | 3616 | 		Py_DECREF(state); | 
 | 3617 | 	} | 
 | 3618 | 	return result; | 
 | 3619 | } | 
 | 3620 |  | 
 | 3621 | static PyObject * | 
 | 3622 | time_unpickler(PyObject *module, PyObject *arg) | 
 | 3623 | { | 
 | 3624 | 	PyDateTime_Time *self; | 
 | 3625 |  | 
 | 3626 | 	if (! PyString_CheckExact(arg)) { | 
 | 3627 | 		PyErr_Format(PyExc_TypeError, | 
 | 3628 | 			     "bad type passed to time unpickler: %s", | 
 | 3629 | 			     arg->ob_type->tp_name); | 
 | 3630 | 		return NULL; | 
 | 3631 | 	} | 
 | 3632 | 	self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType); | 
 | 3633 | 	if (self != NULL) { | 
 | 3634 | 		PyObject *res = time_setstate(self, arg); | 
 | 3635 | 		if (res == NULL) { | 
 | 3636 | 			Py_DECREF(self); | 
 | 3637 | 			return NULL; | 
 | 3638 | 		} | 
 | 3639 | 		Py_DECREF(res); | 
 | 3640 | 	} | 
 | 3641 | 	return (PyObject *)self; | 
 | 3642 | } | 
 | 3643 |  | 
 | 3644 | static PyMethodDef time_methods[] = { | 
 | 3645 | 	{"isoformat",   (PyCFunction)time_isoformat,	METH_KEYWORDS, | 
 | 3646 | 	 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm].")}, | 
 | 3647 |  | 
 | 3648 | 	{"strftime",   	(PyCFunction)time_strftime,	METH_KEYWORDS, | 
 | 3649 | 	 PyDoc_STR("format -> strftime() style string.")}, | 
 | 3650 |  | 
 | 3651 | 	{"__setstate__", (PyCFunction)time_setstate,	METH_O, | 
 | 3652 | 	 PyDoc_STR("__setstate__(state)")}, | 
 | 3653 |  | 
 | 3654 | 	{"__getstate__", (PyCFunction)time_getstate,	METH_NOARGS, | 
 | 3655 | 	 PyDoc_STR("__getstate__() -> state")}, | 
 | 3656 | 	{NULL,	NULL} | 
 | 3657 | }; | 
 | 3658 |  | 
 | 3659 | static char time_doc[] = | 
 | 3660 | PyDoc_STR("Basic time type."); | 
 | 3661 |  | 
 | 3662 | static PyNumberMethods time_as_number = { | 
 | 3663 | 	0,					/* nb_add */ | 
 | 3664 | 	0,					/* nb_subtract */ | 
 | 3665 | 	0,					/* nb_multiply */ | 
 | 3666 | 	0,					/* nb_divide */ | 
 | 3667 | 	0,					/* nb_remainder */ | 
 | 3668 | 	0,					/* nb_divmod */ | 
 | 3669 | 	0,					/* nb_power */ | 
 | 3670 | 	0,					/* nb_negative */ | 
 | 3671 | 	0,					/* nb_positive */ | 
 | 3672 | 	0,					/* nb_absolute */ | 
 | 3673 | 	(inquiry)time_nonzero,			/* nb_nonzero */ | 
 | 3674 | }; | 
 | 3675 |  | 
 | 3676 | statichere PyTypeObject PyDateTime_TimeType = { | 
 | 3677 | 	PyObject_HEAD_INIT(NULL) | 
 | 3678 | 	0,					/* ob_size */ | 
 | 3679 | 	"datetime.time",			/* tp_name */ | 
 | 3680 | 	sizeof(PyDateTime_Time),		/* tp_basicsize */ | 
 | 3681 | 	0,					/* tp_itemsize */ | 
 | 3682 | 	(destructor)PyObject_Del,		/* tp_dealloc */ | 
 | 3683 | 	0,					/* tp_print */ | 
 | 3684 | 	0,					/* tp_getattr */ | 
 | 3685 | 	0,					/* tp_setattr */ | 
 | 3686 | 	0,					/* tp_compare */ | 
 | 3687 | 	(reprfunc)time_repr,			/* tp_repr */ | 
 | 3688 | 	&time_as_number,			/* tp_as_number */ | 
 | 3689 | 	0,					/* tp_as_sequence */ | 
 | 3690 | 	0,					/* tp_as_mapping */ | 
 | 3691 | 	(hashfunc)time_hash,			/* tp_hash */ | 
 | 3692 | 	0,              			/* tp_call */ | 
 | 3693 | 	(reprfunc)time_str,			/* tp_str */ | 
 | 3694 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 3695 | 	0,					/* tp_setattro */ | 
 | 3696 | 	0,					/* tp_as_buffer */ | 
 | 3697 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | | 
 | 3698 |         Py_TPFLAGS_BASETYPE,			/* tp_flags */ | 
 | 3699 | 	time_doc,				/* tp_doc */ | 
 | 3700 | 	0,					/* tp_traverse */ | 
 | 3701 | 	0,					/* tp_clear */ | 
 | 3702 | 	(richcmpfunc)time_richcompare,		/* tp_richcompare */ | 
 | 3703 | 	0,					/* tp_weaklistoffset */ | 
 | 3704 | 	0,					/* tp_iter */ | 
 | 3705 | 	0,					/* tp_iternext */ | 
 | 3706 | 	time_methods,				/* tp_methods */ | 
 | 3707 | 	0,					/* tp_members */ | 
 | 3708 | 	time_getset,				/* tp_getset */ | 
 | 3709 | 	0,					/* tp_base */ | 
 | 3710 | 	0,					/* tp_dict */ | 
 | 3711 | 	0,					/* tp_descr_get */ | 
 | 3712 | 	0,					/* tp_descr_set */ | 
 | 3713 | 	0,					/* tp_dictoffset */ | 
 | 3714 | 	0,					/* tp_init */ | 
 | 3715 | 	0,					/* tp_alloc */ | 
 | 3716 | 	time_new,				/* tp_new */ | 
 | 3717 | 	_PyObject_Del,				/* tp_free */ | 
 | 3718 | }; | 
 | 3719 |  | 
 | 3720 | /* | 
 | 3721 |  * PyDateTime_TZInfo implementation. | 
 | 3722 |  */ | 
 | 3723 |  | 
 | 3724 | /* This is a pure abstract base class, so doesn't do anything beyond | 
 | 3725 |  * raising NotImplemented exceptions.  Real tzinfo classes need | 
 | 3726 |  * to derive from this.  This is mostly for clarity, and for efficiency in | 
 | 3727 |  * datetimetz and timetz constructors (their tzinfo arguments need to | 
 | 3728 |  * be subclasses of this tzinfo class, which is easy and quick to check). | 
 | 3729 |  * | 
 | 3730 |  * Note:  For reasons having to do with pickling of subclasses, we have | 
 | 3731 |  * to allow tzinfo objects to be instantiated.  This wasn't an issue | 
 | 3732 |  * in the Python implementation (__init__() could raise NotImplementedError | 
 | 3733 |  * there without ill effect), but doing so in the C implementation hit a | 
 | 3734 |  * brick wall. | 
 | 3735 |  */ | 
 | 3736 |  | 
 | 3737 | static PyObject * | 
 | 3738 | tzinfo_nogo(const char* methodname) | 
 | 3739 | { | 
 | 3740 | 	PyErr_Format(PyExc_NotImplementedError, | 
 | 3741 | 		     "a tzinfo subclass must implement %s()", | 
 | 3742 | 		     methodname); | 
 | 3743 | 	return NULL; | 
 | 3744 | } | 
 | 3745 |  | 
 | 3746 | /* Methods.  A subclass must implement these. */ | 
 | 3747 |  | 
 | 3748 | static PyObject* | 
 | 3749 | tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt) | 
 | 3750 | { | 
 | 3751 | 	return tzinfo_nogo("tzname"); | 
 | 3752 | } | 
 | 3753 |  | 
 | 3754 | static PyObject* | 
 | 3755 | tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt) | 
 | 3756 | { | 
 | 3757 | 	return tzinfo_nogo("utcoffset"); | 
 | 3758 | } | 
 | 3759 |  | 
 | 3760 | static PyObject* | 
 | 3761 | tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt) | 
 | 3762 | { | 
 | 3763 | 	return tzinfo_nogo("dst"); | 
 | 3764 | } | 
 | 3765 |  | 
 | 3766 | /* | 
 | 3767 |  * Pickle support.  This is solely so that tzinfo subclasses can use | 
 | 3768 |  * pickling -- tzinfo itself is supposed to be uninstantiable.  The | 
 | 3769 |  * pickler and unpickler functions are given module-level private | 
 | 3770 |  * names, and registered with copy_reg, by the module init function. | 
 | 3771 |  */ | 
 | 3772 |  | 
 | 3773 | static PyObject* | 
 | 3774 | tzinfo_pickler(PyDateTime_TZInfo *self) { | 
 | 3775 | 	return Py_BuildValue("O()", tzinfo_unpickler_object); | 
 | 3776 | } | 
 | 3777 |  | 
 | 3778 | static PyObject* | 
 | 3779 | tzinfo_unpickler(PyObject * unused) { | 
 | 3780 |  	return PyType_GenericNew(&PyDateTime_TZInfoType, NULL, NULL); | 
 | 3781 | } | 
 | 3782 |  | 
 | 3783 |  | 
 | 3784 | static PyMethodDef tzinfo_methods[] = { | 
 | 3785 | 	{"tzname",	(PyCFunction)tzinfo_tzname,		METH_O, | 
 | 3786 | 	 PyDoc_STR("datetime -> string name of time zone.")}, | 
 | 3787 |  | 
 | 3788 | 	{"utcoffset",	(PyCFunction)tzinfo_utcoffset,		METH_O, | 
 | 3789 | 	 PyDoc_STR("datetime -> minutes east of UTC (negative for " | 
 | 3790 | 	 	   "west of UTC).")}, | 
 | 3791 |  | 
 | 3792 | 	{"dst",		(PyCFunction)tzinfo_dst,		METH_O, | 
 | 3793 | 	 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")}, | 
 | 3794 |  | 
 | 3795 | 	{NULL, NULL} | 
 | 3796 | }; | 
 | 3797 |  | 
 | 3798 | static char tzinfo_doc[] = | 
 | 3799 | PyDoc_STR("Abstract base class for time zone info objects."); | 
 | 3800 |  | 
 | 3801 |  statichere PyTypeObject PyDateTime_TZInfoType = { | 
 | 3802 | 	PyObject_HEAD_INIT(NULL) | 
 | 3803 | 	0,					/* ob_size */ | 
 | 3804 | 	"datetime.tzinfo",			/* tp_name */ | 
 | 3805 | 	sizeof(PyDateTime_TZInfo),		/* tp_basicsize */ | 
 | 3806 | 	0,					/* tp_itemsize */ | 
 | 3807 | 	0,					/* tp_dealloc */ | 
 | 3808 | 	0,					/* tp_print */ | 
 | 3809 | 	0,					/* tp_getattr */ | 
 | 3810 | 	0,					/* tp_setattr */ | 
 | 3811 | 	0,					/* tp_compare */ | 
 | 3812 | 	0,					/* tp_repr */ | 
 | 3813 | 	0,					/* tp_as_number */ | 
 | 3814 | 	0,					/* tp_as_sequence */ | 
 | 3815 | 	0,					/* tp_as_mapping */ | 
 | 3816 | 	0,					/* tp_hash */ | 
 | 3817 | 	0,              			/* tp_call */ | 
 | 3818 | 	0,					/* tp_str */ | 
 | 3819 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 3820 | 	0,					/* tp_setattro */ | 
 | 3821 | 	0,					/* tp_as_buffer */ | 
 | 3822 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | | 
 | 3823 |         Py_TPFLAGS_BASETYPE,			/* tp_flags */ | 
 | 3824 | 	tzinfo_doc,				/* tp_doc */ | 
 | 3825 | 	0,					/* tp_traverse */ | 
 | 3826 | 	0,					/* tp_clear */ | 
 | 3827 | 	0,					/* tp_richcompare */ | 
 | 3828 | 	0,					/* tp_weaklistoffset */ | 
 | 3829 | 	0,					/* tp_iter */ | 
 | 3830 | 	0,					/* tp_iternext */ | 
 | 3831 | 	tzinfo_methods,				/* tp_methods */ | 
 | 3832 | 	0,					/* tp_members */ | 
 | 3833 | 	0,					/* tp_getset */ | 
 | 3834 | 	0,					/* tp_base */ | 
 | 3835 | 	0,					/* tp_dict */ | 
 | 3836 | 	0,					/* tp_descr_get */ | 
 | 3837 | 	0,					/* tp_descr_set */ | 
 | 3838 | 	0,					/* tp_dictoffset */ | 
 | 3839 | 	0,					/* tp_init */ | 
 | 3840 | 	0,					/* tp_alloc */ | 
 | 3841 | 	PyType_GenericNew,			/* tp_new */ | 
 | 3842 | 	0,					/* tp_free */ | 
 | 3843 | }; | 
 | 3844 |  | 
 | 3845 | /* | 
 | 3846 |  * PyDateTime_TimeTZ implementation. | 
 | 3847 |  */ | 
 | 3848 |  | 
 | 3849 | /* Accessor properties.  Properties for hour, minute, second and microsecond | 
 | 3850 |  * are inherited from time. | 
 | 3851 |  */ | 
 | 3852 |  | 
 | 3853 | static PyObject * | 
 | 3854 | timetz_tzinfo(PyDateTime_TimeTZ *self, void *unused) | 
 | 3855 | { | 
 | 3856 | 	Py_INCREF(self->tzinfo); | 
 | 3857 | 	return self->tzinfo; | 
 | 3858 | } | 
 | 3859 |  | 
 | 3860 | static PyGetSetDef timetz_getset[] = { | 
 | 3861 | 	{"tzinfo", (getter)timetz_tzinfo}, | 
 | 3862 | 	{NULL} | 
 | 3863 | }; | 
 | 3864 |  | 
 | 3865 | /* | 
 | 3866 |  * Constructors. | 
 | 3867 |  */ | 
 | 3868 |  | 
 | 3869 | static PyObject * | 
 | 3870 | timetz_new(PyTypeObject *type, PyObject *args, PyObject *kw) | 
 | 3871 | { | 
 | 3872 | 	PyObject *self = NULL; | 
 | 3873 | 	int hour = 0; | 
 | 3874 | 	int minute = 0; | 
 | 3875 | 	int second = 0; | 
 | 3876 | 	int usecond = 0; | 
 | 3877 | 	PyObject *tzinfo = Py_None; | 
 | 3878 |  | 
 | 3879 | 	static char *keywords[] = { | 
 | 3880 | 		"hour", "minute", "second", "microsecond", "tzinfo", NULL | 
 | 3881 | 	}; | 
 | 3882 |  | 
 | 3883 | 	if (PyArg_ParseTupleAndKeywords(args, kw, "|llllO", keywords, | 
 | 3884 | 					&hour, &minute, &second, &usecond, | 
 | 3885 | 					&tzinfo)) { | 
 | 3886 | 		if (check_time_args(hour, minute, second, usecond) < 0) | 
 | 3887 | 			return NULL; | 
 | 3888 | 		if (check_tzinfo_subclass(tzinfo) < 0) | 
 | 3889 | 			return NULL; | 
 | 3890 | 		self = new_timetz(hour, minute, second, usecond, tzinfo); | 
 | 3891 | 	} | 
 | 3892 | 	return self; | 
 | 3893 | } | 
 | 3894 |  | 
 | 3895 | /* | 
 | 3896 |  * Destructor. | 
 | 3897 |  */ | 
 | 3898 |  | 
 | 3899 | static void | 
 | 3900 | timetz_dealloc(PyDateTime_TimeTZ *self) | 
 | 3901 | { | 
 | 3902 | 	Py_XDECREF(self->tzinfo); | 
 | 3903 | 	self->ob_type->tp_free((PyObject *)self); | 
 | 3904 | } | 
 | 3905 |  | 
 | 3906 | /* | 
 | 3907 |  * Indirect access to tzinfo methods.  One more "convenience function" and | 
 | 3908 |  * it won't be possible to find the useful methods anymore <0.5 wink>. | 
 | 3909 |  */ | 
 | 3910 |  | 
 | 3911 | static PyObject * | 
 | 3912 | timetz_convienience(PyDateTime_TimeTZ *self, char *name) | 
 | 3913 | { | 
 | 3914 | 	PyObject *result; | 
 | 3915 |  | 
 | 3916 | 	if (self->tzinfo == Py_None) { | 
 | 3917 | 		result = Py_None; | 
 | 3918 | 		Py_INCREF(result); | 
 | 3919 | 	} | 
 | 3920 | 	else | 
 | 3921 | 		result = PyObject_CallMethod(self->tzinfo, name, "O", self); | 
 | 3922 | 	return result; | 
 | 3923 | } | 
 | 3924 |  | 
 | 3925 | /* These are all METH_NOARGS, so don't need to check the arglist. */ | 
 | 3926 | static PyObject * | 
 | 3927 | timetz_utcoffset(PyDateTime_TimeTZ *self, PyObject *unused) { | 
 | 3928 | 	return timetz_convienience(self, "utcoffset"); | 
 | 3929 | } | 
 | 3930 |  | 
 | 3931 | static PyObject * | 
 | 3932 | timetz_tzname(PyDateTime_TimeTZ *self, PyObject *unused) { | 
 | 3933 | 	return timetz_convienience(self, "tzname"); | 
 | 3934 | } | 
 | 3935 |  | 
 | 3936 | static PyObject * | 
 | 3937 | timetz_dst(PyDateTime_TimeTZ *self, PyObject *unused) { | 
 | 3938 | 	return timetz_convienience(self, "dst"); | 
 | 3939 | } | 
 | 3940 |  | 
 | 3941 | /* | 
 | 3942 |  * Various ways to turn a timetz into a string. | 
 | 3943 |  */ | 
 | 3944 |  | 
 | 3945 | static PyObject * | 
 | 3946 | timetz_repr(PyDateTime_TimeTZ *self) | 
 | 3947 | { | 
 | 3948 | 	PyObject *baserepr = time_repr((PyDateTime_Time *)self); | 
 | 3949 |  | 
 | 3950 | 	if (baserepr == NULL) | 
 | 3951 | 		return NULL; | 
 | 3952 | 	return append_keyword_tzinfo(baserepr, self->tzinfo); | 
 | 3953 | } | 
 | 3954 |  | 
 | 3955 | /* Note:  tp_str is inherited from time. */ | 
 | 3956 |  | 
 | 3957 | static PyObject * | 
 | 3958 | timetz_isoformat(PyDateTime_TimeTZ *self) | 
 | 3959 | { | 
 | 3960 | 	char buf[100]; | 
 | 3961 | 	PyObject *result = time_isoformat((PyDateTime_Time *)self); | 
 | 3962 |  | 
 | 3963 | 	if (result == NULL || self->tzinfo == Py_None) | 
 | 3964 | 		return result; | 
 | 3965 |  | 
 | 3966 | 	/* We need to append the UTC offset. */ | 
 | 3967 | 	if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo, | 
 | 3968 | 			     (PyObject *)self) < 0) { | 
 | 3969 | 		Py_DECREF(result); | 
 | 3970 | 		return NULL; | 
 | 3971 | 	} | 
 | 3972 | 	PyString_ConcatAndDel(&result, PyString_FromString(buf)); | 
 | 3973 | 	return result; | 
 | 3974 | } | 
 | 3975 |  | 
 | 3976 | /* Note:  strftime() is inherited from time. */ | 
 | 3977 |  | 
 | 3978 | /* | 
 | 3979 |  * Miscellaneous methods. | 
 | 3980 |  */ | 
 | 3981 |  | 
 | 3982 | /* Note:  tp_richcompare and tp_hash are inherited from time. */ | 
 | 3983 |  | 
 | 3984 | static int | 
 | 3985 | timetz_nonzero(PyDateTime_TimeTZ *self) | 
 | 3986 | { | 
 | 3987 | 	int offset; | 
 | 3988 | 	int none; | 
 | 3989 |  | 
 | 3990 | 	if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) { | 
 | 3991 | 		/* Since utcoffset is in whole minutes, nothing can | 
 | 3992 | 		 * alter the conclusion that this is nonzero. | 
 | 3993 | 		 */ | 
 | 3994 | 		return 1; | 
 | 3995 | 	} | 
 | 3996 | 	offset = 0; | 
 | 3997 | 	if (self->tzinfo != Py_None) { | 
 | 3998 | 		offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none); | 
 | 3999 | 		if (offset == -1 && PyErr_Occurred()) | 
 | 4000 | 			return -1; | 
 | 4001 | 	} | 
 | 4002 | 	return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0; | 
 | 4003 | } | 
 | 4004 |  | 
 | 4005 | /* | 
 | 4006 |  * Pickle support.  Quite a maze! | 
 | 4007 |  */ | 
 | 4008 |  | 
 | 4009 | /* Let basestate be the state string returned by time_getstate. | 
 | 4010 |  * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). | 
 | 4011 |  * So it's a tuple in any (non-error) case. | 
 | 4012 |  */ | 
 | 4013 | static PyObject * | 
 | 4014 | timetz_getstate(PyDateTime_TimeTZ *self) | 
 | 4015 | { | 
 | 4016 | 	PyObject *basestate; | 
 | 4017 | 	PyObject *result = NULL; | 
 | 4018 |  | 
 | 4019 | 	basestate = time_getstate((PyDateTime_Time *)self); | 
 | 4020 | 	if (basestate != NULL) { | 
 | 4021 | 		if (self->tzinfo == Py_None) | 
 | 4022 | 			result = Py_BuildValue("(O)", basestate); | 
 | 4023 | 		else | 
 | 4024 | 			result = Py_BuildValue("OO", basestate, self->tzinfo); | 
 | 4025 | 		Py_DECREF(basestate); | 
 | 4026 | 	} | 
 | 4027 | 	return result; | 
 | 4028 | } | 
 | 4029 |  | 
 | 4030 | static PyObject * | 
 | 4031 | timetz_setstate(PyDateTime_TimeTZ *self, PyObject *state) | 
 | 4032 | { | 
 | 4033 | 	PyObject *temp; | 
 | 4034 | 	PyObject *basestate; | 
 | 4035 | 	PyObject *tzinfo = Py_None; | 
 | 4036 |  | 
 | 4037 | 	if (! PyArg_ParseTuple(state, "O!|O:__setstate__", | 
 | 4038 | 			       &PyString_Type, &basestate, | 
 | 4039 | 			       &tzinfo)) | 
 | 4040 | 		return NULL; | 
 | 4041 | 	temp = time_setstate((PyDateTime_Time *)self, basestate); | 
 | 4042 | 	if (temp == NULL) | 
 | 4043 | 		return NULL; | 
 | 4044 | 	Py_DECREF(temp); | 
 | 4045 |  | 
 | 4046 | 	Py_INCREF(tzinfo); | 
 | 4047 | 	Py_XDECREF(self->tzinfo); | 
 | 4048 | 	self->tzinfo = tzinfo; | 
 | 4049 |  | 
 | 4050 | 	Py_INCREF(Py_None); | 
 | 4051 | 	return Py_None; | 
 | 4052 | } | 
 | 4053 |  | 
 | 4054 | static PyObject * | 
 | 4055 | timetz_pickler(PyObject *module, PyDateTime_TimeTZ *timetz) | 
 | 4056 | { | 
 | 4057 | 	PyObject *state; | 
 | 4058 | 	PyObject *result = NULL; | 
 | 4059 |  | 
 | 4060 | 	if (! PyTimeTZ_CheckExact(timetz)) { | 
 | 4061 | 		PyErr_Format(PyExc_TypeError, | 
 | 4062 | 			     "bad type passed to timetz pickler: %s", | 
 | 4063 | 			     timetz->ob_type->tp_name); | 
 | 4064 | 		return NULL; | 
 | 4065 | 	} | 
 | 4066 | 	state = timetz_getstate(timetz); | 
 | 4067 | 	if (state) { | 
 | 4068 | 		result = Py_BuildValue("O(O)", | 
 | 4069 | 				       timetz_unpickler_object, | 
 | 4070 | 				       state); | 
 | 4071 | 		Py_DECREF(state); | 
 | 4072 | 	} | 
 | 4073 | 	return result; | 
 | 4074 | } | 
 | 4075 |  | 
 | 4076 | static PyObject * | 
 | 4077 | timetz_unpickler(PyObject *module, PyObject *arg) | 
 | 4078 | { | 
 | 4079 | 	PyDateTime_TimeTZ *self; | 
 | 4080 |  | 
 | 4081 | 	self = PyObject_New(PyDateTime_TimeTZ, &PyDateTime_TimeTZType); | 
 | 4082 | 	if (self != NULL) { | 
 | 4083 | 		PyObject *res; | 
 | 4084 |  | 
 | 4085 | 		self->tzinfo = NULL; | 
 | 4086 | 		res = timetz_setstate(self, arg); | 
 | 4087 | 		if (res == NULL) { | 
 | 4088 | 			Py_DECREF(self); | 
 | 4089 | 			return NULL; | 
 | 4090 | 		} | 
 | 4091 | 		Py_DECREF(res); | 
 | 4092 | 	} | 
 | 4093 | 	return (PyObject *)self; | 
 | 4094 | } | 
 | 4095 |  | 
 | 4096 | static PyMethodDef timetz_methods[] = { | 
 | 4097 | 	{"isoformat",   (PyCFunction)timetz_isoformat,	METH_KEYWORDS, | 
 | 4098 | 	 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]" | 
 | 4099 | 	 	   "[+HH:MM].")}, | 
 | 4100 |  | 
 | 4101 | 	{"utcoffset",	(PyCFunction)timetz_utcoffset,	METH_NOARGS, | 
 | 4102 | 	 PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, | 
 | 4103 |  | 
 | 4104 | 	{"tzname",	(PyCFunction)timetz_tzname,	METH_NOARGS, | 
 | 4105 | 	 PyDoc_STR("Return self.tzinfo.tzname(self).")}, | 
 | 4106 |  | 
 | 4107 | 	{"dst",		(PyCFunction)timetz_dst,	METH_NOARGS, | 
 | 4108 | 	 PyDoc_STR("Return self.tzinfo.dst(self).")}, | 
 | 4109 |  | 
 | 4110 | 	{"__setstate__", (PyCFunction)timetz_setstate,	METH_O, | 
 | 4111 | 	 PyDoc_STR("__setstate__(state)")}, | 
 | 4112 |  | 
 | 4113 | 	{"__getstate__", (PyCFunction)timetz_getstate,	METH_NOARGS, | 
 | 4114 | 	 PyDoc_STR("__getstate__() -> state")}, | 
 | 4115 | 	{NULL,	NULL} | 
 | 4116 |  | 
 | 4117 | }; | 
 | 4118 |  | 
 | 4119 | static char timetz_doc[] = | 
 | 4120 | PyDoc_STR("Time type."); | 
 | 4121 |  | 
 | 4122 | static PyNumberMethods timetz_as_number = { | 
 | 4123 | 	0,					/* nb_add */ | 
 | 4124 | 	0,					/* nb_subtract */ | 
 | 4125 | 	0,					/* nb_multiply */ | 
 | 4126 | 	0,					/* nb_divide */ | 
 | 4127 | 	0,					/* nb_remainder */ | 
 | 4128 | 	0,					/* nb_divmod */ | 
 | 4129 | 	0,					/* nb_power */ | 
 | 4130 | 	0,					/* nb_negative */ | 
 | 4131 | 	0,					/* nb_positive */ | 
 | 4132 | 	0,					/* nb_absolute */ | 
 | 4133 | 	(inquiry)timetz_nonzero,		/* nb_nonzero */ | 
 | 4134 | }; | 
 | 4135 |  | 
 | 4136 | statichere PyTypeObject PyDateTime_TimeTZType = { | 
 | 4137 | 	PyObject_HEAD_INIT(NULL) | 
 | 4138 | 	0,					/* ob_size */ | 
 | 4139 | 	"datetime.timetz",			/* tp_name */ | 
 | 4140 | 	sizeof(PyDateTime_TimeTZ),		/* tp_basicsize */ | 
 | 4141 | 	0,					/* tp_itemsize */ | 
 | 4142 | 	(destructor)timetz_dealloc,		/* tp_dealloc */ | 
 | 4143 | 	0,					/* tp_print */ | 
 | 4144 | 	0,					/* tp_getattr */ | 
 | 4145 | 	0,					/* tp_setattr */ | 
 | 4146 | 	0,					/* tp_compare */ | 
 | 4147 | 	(reprfunc)timetz_repr,			/* tp_repr */ | 
 | 4148 | 	&timetz_as_number,			/* tp_as_number */ | 
 | 4149 | 	0,					/* tp_as_sequence */ | 
 | 4150 | 	0,					/* tp_as_mapping */ | 
 | 4151 | 	0,					/* tp_hash */ | 
 | 4152 | 	0,              			/* tp_call */ | 
 | 4153 | 	0,					/* tp_str */ | 
 | 4154 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 4155 | 	0,					/* tp_setattro */ | 
 | 4156 | 	0,					/* tp_as_buffer */ | 
 | 4157 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | | 
 | 4158 |         Py_TPFLAGS_BASETYPE,			/* tp_flags */ | 
| Guido van Rossum | bd43e91 | 2002-12-16 20:34:55 +0000 | [diff] [blame] | 4159 | 	timetz_doc,				/* tp_doc */ | 
| Tim Peters | 2a799bf | 2002-12-16 20:18:38 +0000 | [diff] [blame] | 4160 | 	0,					/* tp_traverse */ | 
 | 4161 | 	0,					/* tp_clear */ | 
 | 4162 | 	0,					/* tp_richcompare */ | 
 | 4163 | 	0,					/* tp_weaklistoffset */ | 
 | 4164 | 	0,					/* tp_iter */ | 
 | 4165 | 	0,					/* tp_iternext */ | 
 | 4166 | 	timetz_methods,				/* tp_methods */ | 
 | 4167 | 	0,					/* tp_members */ | 
 | 4168 | 	timetz_getset,				/* tp_getset */ | 
 | 4169 | 	&PyDateTime_TimeType,			/* tp_base */ | 
 | 4170 | 	0,					/* tp_dict */ | 
 | 4171 | 	0,					/* tp_descr_get */ | 
 | 4172 | 	0,					/* tp_descr_set */ | 
 | 4173 | 	0,					/* tp_dictoffset */ | 
 | 4174 | 	0,					/* tp_init */ | 
 | 4175 | 	0,					/* tp_alloc */ | 
 | 4176 | 	timetz_new,				/* tp_new */ | 
 | 4177 | 	_PyObject_Del,				/* tp_free */ | 
 | 4178 | }; | 
 | 4179 |  | 
 | 4180 | /* | 
 | 4181 |  * PyDateTime_DateTimeTZ implementation. | 
 | 4182 |  */ | 
 | 4183 |  | 
 | 4184 | /* Accessor properties.  Properties for day, month, year, hour, minute, | 
 | 4185 |  * second and microsecond are inherited from datetime. | 
 | 4186 |  */ | 
 | 4187 |  | 
 | 4188 | static PyObject * | 
 | 4189 | datetimetz_tzinfo(PyDateTime_DateTimeTZ *self, void *unused) | 
 | 4190 | { | 
 | 4191 | 	Py_INCREF(self->tzinfo); | 
 | 4192 | 	return self->tzinfo; | 
 | 4193 | } | 
 | 4194 |  | 
 | 4195 | static PyGetSetDef datetimetz_getset[] = { | 
 | 4196 | 	{"tzinfo", (getter)datetimetz_tzinfo}, | 
 | 4197 | 	{NULL} | 
 | 4198 | }; | 
 | 4199 |  | 
 | 4200 | /* | 
 | 4201 |  * Constructors. | 
 | 4202 |  * These are like the datetime methods of the same names, but allow an | 
 | 4203 |  * optional tzinfo argument. | 
 | 4204 |  */ | 
 | 4205 |  | 
 | 4206 | /* Internal helper. | 
 | 4207 |  * self is a datetimetz.  Replace its tzinfo member. | 
 | 4208 |  */ | 
 | 4209 | void | 
 | 4210 | replace_tzinfo(PyObject *self, PyObject *newtzinfo) | 
 | 4211 | { | 
 | 4212 | 	assert(self != NULL); | 
 | 4213 | 	assert(newtzinfo != NULL); | 
 | 4214 | 	assert(PyDateTimeTZ_Check(self)); | 
 | 4215 | 	Py_INCREF(newtzinfo); | 
 | 4216 | 	Py_DECREF(((PyDateTime_DateTimeTZ *)self)->tzinfo); | 
 | 4217 | 	((PyDateTime_DateTimeTZ *)self)->tzinfo = newtzinfo; | 
 | 4218 | } | 
 | 4219 |  | 
 | 4220 | static PyObject * | 
 | 4221 | datetimetz_new(PyTypeObject *type, PyObject *args, PyObject *kw) | 
 | 4222 | { | 
 | 4223 | 	PyObject *self = NULL; | 
 | 4224 | 	int year; | 
 | 4225 | 	int month; | 
 | 4226 | 	int day; | 
 | 4227 | 	int hour = 0; | 
 | 4228 | 	int minute = 0; | 
 | 4229 | 	int second = 0; | 
 | 4230 | 	int usecond = 0; | 
 | 4231 | 	PyObject *tzinfo = Py_None; | 
 | 4232 |  | 
 | 4233 | 	static char *keywords[] = { | 
 | 4234 | 		"year", "month", "day", "hour", "minute", "second", | 
 | 4235 | 		"microsecond", "tzinfo", NULL | 
 | 4236 | 	}; | 
 | 4237 |  | 
 | 4238 | 	if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", keywords, | 
 | 4239 | 					&year, &month, &day, &hour, &minute, | 
 | 4240 | 					&second, &usecond, &tzinfo)) { | 
 | 4241 | 		if (check_date_args(year, month, day) < 0) | 
 | 4242 | 			return NULL; | 
 | 4243 | 		if (check_time_args(hour, minute, second, usecond) < 0) | 
 | 4244 | 			return NULL; | 
 | 4245 | 		if (check_tzinfo_subclass(tzinfo) < 0) | 
 | 4246 | 			return NULL; | 
 | 4247 | 		self = new_datetimetz(year, month, day, | 
 | 4248 | 				      hour, minute, second, usecond, | 
 | 4249 | 				      tzinfo); | 
 | 4250 | 	} | 
 | 4251 | 	return self; | 
 | 4252 | } | 
 | 4253 |  | 
 | 4254 | /* Return best possible local time -- this isn't constrained by the | 
 | 4255 |  * precision of a timestamp. | 
 | 4256 |  */ | 
 | 4257 | static PyObject * | 
 | 4258 | datetimetz_now(PyObject *cls, PyObject *args, PyObject *kw) | 
 | 4259 | { | 
 | 4260 | 	PyObject *self = NULL; | 
 | 4261 | 	PyObject *tzinfo = Py_None; | 
 | 4262 | 	static char *keywords[] = {"tzinfo", NULL}; | 
 | 4263 |  | 
 | 4264 | 	if (PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords, | 
 | 4265 | 					&tzinfo)) { | 
 | 4266 | 		if (check_tzinfo_subclass(tzinfo) < 0) | 
 | 4267 | 			return NULL; | 
 | 4268 | 		self = datetime_best_possible(cls, localtime); | 
 | 4269 | 		if (self != NULL) | 
 | 4270 | 			replace_tzinfo(self, tzinfo); | 
 | 4271 | 	} | 
 | 4272 | 	return self; | 
 | 4273 | } | 
 | 4274 |  | 
 | 4275 | /* Return new local datetime from timestamp (Python timestamp -- a double). */ | 
 | 4276 | static PyObject * | 
 | 4277 | datetimetz_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) | 
 | 4278 | { | 
 | 4279 | 	PyObject *self = NULL; | 
 | 4280 | 	double timestamp; | 
 | 4281 | 	PyObject *tzinfo = Py_None; | 
 | 4282 | 	static char *keywords[] = {"timestamp", "tzinfo", NULL}; | 
 | 4283 |  | 
 | 4284 | 	if (PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp", | 
 | 4285 | 					keywords, ×tamp, &tzinfo)) { | 
 | 4286 | 		if (check_tzinfo_subclass(tzinfo) < 0) | 
 | 4287 | 			return NULL; | 
 | 4288 | 		self = datetime_from_timestamp(cls, localtime, timestamp); | 
 | 4289 | 		if (self != NULL) | 
 | 4290 | 			replace_tzinfo(self, tzinfo); | 
 | 4291 | 	} | 
 | 4292 | 	return self; | 
 | 4293 | } | 
 | 4294 |  | 
 | 4295 | /* Note:  utcnow() is inherited, and doesn't accept tzinfo. | 
 | 4296 |  * Ditto utcfromtimestamp().  Ditto combine(). | 
 | 4297 |  */ | 
 | 4298 |  | 
 | 4299 |  | 
 | 4300 | /* | 
 | 4301 |  * Destructor. | 
 | 4302 |  */ | 
 | 4303 |  | 
 | 4304 | static void | 
 | 4305 | datetimetz_dealloc(PyDateTime_DateTimeTZ *self) | 
 | 4306 | { | 
 | 4307 | 	Py_XDECREF(self->tzinfo); | 
 | 4308 | 	self->ob_type->tp_free((PyObject *)self); | 
 | 4309 | } | 
 | 4310 |  | 
 | 4311 | /* | 
 | 4312 |  * Indirect access to tzinfo methods. | 
 | 4313 |  */ | 
 | 4314 |  | 
 | 4315 | /* Internal helper. | 
 | 4316 |  * Call a tzinfo object's method, or return None if tzinfo is None. | 
 | 4317 |  */ | 
 | 4318 | static PyObject * | 
 | 4319 | datetimetz_convienience(PyDateTime_DateTimeTZ *self, char *name) | 
 | 4320 | { | 
 | 4321 | 	PyObject *result; | 
 | 4322 |  | 
 | 4323 | 	if (self->tzinfo == Py_None) { | 
 | 4324 | 		result = Py_None; | 
 | 4325 | 		Py_INCREF(result); | 
 | 4326 | 	} | 
 | 4327 | 	else | 
 | 4328 | 		result = PyObject_CallMethod(self->tzinfo, name, "O", self); | 
 | 4329 | 	return result; | 
 | 4330 | } | 
 | 4331 |  | 
 | 4332 | /* These are all METH_NOARGS, so don't need to check the arglist. */ | 
 | 4333 | static PyObject * | 
 | 4334 | datetimetz_utcoffset(PyDateTime_DateTimeTZ *self, PyObject *unused) { | 
 | 4335 | 	return datetimetz_convienience(self, "utcoffset"); | 
 | 4336 | } | 
 | 4337 |  | 
 | 4338 | static PyObject * | 
 | 4339 | datetimetz_tzname(PyDateTime_DateTimeTZ *self, PyObject *unused) { | 
 | 4340 | 	return datetimetz_convienience(self, "tzname"); | 
 | 4341 | } | 
 | 4342 |  | 
 | 4343 | static PyObject * | 
 | 4344 | datetimetz_dst(PyDateTime_DateTimeTZ *self, PyObject *unused) { | 
 | 4345 | 	return datetimetz_convienience(self, "dst"); | 
 | 4346 | } | 
 | 4347 |  | 
 | 4348 | /* | 
 | 4349 |  * datetimetz arithmetic. | 
 | 4350 |  */ | 
 | 4351 |  | 
 | 4352 | /* If base is Py_NotImplemented or NULL, just return it. | 
 | 4353 |  * Else base is a datetime, exactly one of {left, right} is a datetimetz, | 
 | 4354 |  * and we want to create a datetimetz with the same date and time fields | 
 | 4355 |  * as base, and with the tzinfo field from left or right.  Do that, | 
 | 4356 |  * return it, and decref base.  This is used to transform the result of | 
 | 4357 |  * a binary datetime operation (base) into a datetimetz result. | 
 | 4358 |  */ | 
 | 4359 | static PyObject * | 
 | 4360 | attach_tzinfo(PyObject *base, PyObject *left, PyObject *right) | 
 | 4361 | { | 
 | 4362 | 	PyDateTime_DateTimeTZ *self; | 
 | 4363 | 	PyDateTime_DateTimeTZ *result; | 
 | 4364 |  | 
 | 4365 | 	if (base == NULL || base == Py_NotImplemented) | 
 | 4366 | 		return base; | 
 | 4367 |  | 
 | 4368 | 	assert(PyDateTime_CheckExact(base)); | 
 | 4369 |  | 
 | 4370 | 	if (PyDateTimeTZ_Check(left)) { | 
 | 4371 | 		assert(! PyDateTimeTZ_Check(right)); | 
 | 4372 | 		self = (PyDateTime_DateTimeTZ *)left; | 
 | 4373 | 	} | 
 | 4374 | 	else { | 
 | 4375 | 		assert(PyDateTimeTZ_Check(right)); | 
 | 4376 | 		self = (PyDateTime_DateTimeTZ *)right; | 
 | 4377 | 	} | 
 | 4378 | 	result = PyObject_New(PyDateTime_DateTimeTZ, | 
 | 4379 | 			      &PyDateTime_DateTimeTZType); | 
 | 4380 | 	if (result != NULL) { | 
 | 4381 | 		memcpy(result->data, ((PyDateTime_DateTime *)base)->data, | 
 | 4382 | 		       _PyDateTime_DATETIME_DATASIZE); | 
 | 4383 | 		Py_INCREF(self->tzinfo); | 
 | 4384 | 		result->tzinfo = self->tzinfo; | 
 | 4385 | 	} | 
 | 4386 | 	Py_DECREF(base); | 
 | 4387 | 	return (PyObject *)result; | 
 | 4388 | } | 
 | 4389 |  | 
 | 4390 | static PyObject * | 
 | 4391 | datetimetz_add(PyObject *left, PyObject *right) | 
 | 4392 | { | 
 | 4393 | 	return attach_tzinfo(datetime_add(left, right), left, right); | 
 | 4394 | } | 
 | 4395 |  | 
 | 4396 | static PyObject * | 
 | 4397 | datetimetz_subtract(PyObject *left, PyObject *right) | 
 | 4398 | { | 
 | 4399 | 	PyObject *result = Py_NotImplemented; | 
 | 4400 |  | 
 | 4401 | 	if (PyDateTime_Check(left)) { | 
 | 4402 | 		/* datetime - ??? */ | 
 | 4403 | 		if (PyDateTime_Check(right)) { | 
 | 4404 | 			/* datetime - datetime */ | 
 | 4405 | 			naivety n1, n2; | 
 | 4406 | 			int offset1, offset2; | 
 | 4407 | 			PyDateTime_Delta *delta; | 
 | 4408 |  | 
 | 4409 | 			n1 = classify_object(left, &offset1); | 
 | 4410 | 			assert(n1 != OFFSET_UNKNOWN); | 
 | 4411 | 			if (n1 == OFFSET_ERROR) | 
 | 4412 | 				return NULL; | 
 | 4413 |  | 
 | 4414 | 			n2 = classify_object(right, &offset2); | 
 | 4415 | 			assert(n2 != OFFSET_UNKNOWN); | 
 | 4416 | 			if (n2 == OFFSET_ERROR) | 
 | 4417 | 				return NULL; | 
 | 4418 |  | 
 | 4419 | 			if (n1 != n2) { | 
 | 4420 | 				PyErr_SetString(PyExc_TypeError, | 
 | 4421 | 					"can't subtract offset-naive and " | 
 | 4422 | 					"offset-aware datetimes"); | 
 | 4423 | 				return NULL; | 
 | 4424 | 			} | 
 | 4425 | 			delta = (PyDateTime_Delta *)sub_datetime_datetime( | 
 | 4426 | 						(PyDateTime_DateTime *)left, | 
 | 4427 | 						(PyDateTime_DateTime *)right); | 
 | 4428 | 			if (delta == NULL || offset1 == offset2) | 
 | 4429 | 				return (PyObject *)delta; | 
 | 4430 | 			/* (left - offset1) - (right - offset2) = | 
 | 4431 | 			 * (left - right) + (offset2 - offset1) | 
 | 4432 | 			 */ | 
 | 4433 | 			result = new_delta(delta->days, | 
 | 4434 | 					   delta->seconds + | 
 | 4435 | 					   	(offset2 - offset1) * 60, | 
 | 4436 | 					   delta->microseconds, | 
 | 4437 | 					   1); | 
 | 4438 | 			Py_DECREF(delta); | 
 | 4439 | 		} | 
 | 4440 | 		else if (PyDelta_Check(right)) { | 
 | 4441 | 			/* datetimetz - delta */ | 
 | 4442 | 			result = sub_datetime_timedelta( | 
 | 4443 | 					(PyDateTime_DateTime *)left, | 
 | 4444 | 					(PyDateTime_Delta *)right); | 
 | 4445 | 			result = attach_tzinfo(result, left, right); | 
 | 4446 | 		} | 
 | 4447 | 	} | 
 | 4448 |  | 
 | 4449 | 	if (result == Py_NotImplemented) | 
 | 4450 | 		Py_INCREF(result); | 
 | 4451 | 	return result; | 
 | 4452 | } | 
 | 4453 |  | 
 | 4454 | /* Various ways to turn a datetime into a string. */ | 
 | 4455 |  | 
 | 4456 | static PyObject * | 
 | 4457 | datetimetz_repr(PyDateTime_DateTimeTZ *self) | 
 | 4458 | { | 
 | 4459 | 	PyObject *baserepr = datetime_repr((PyDateTime_DateTime *)self); | 
 | 4460 |  | 
 | 4461 | 	if (baserepr == NULL) | 
 | 4462 | 		return NULL; | 
 | 4463 | 	return append_keyword_tzinfo(baserepr, self->tzinfo); | 
 | 4464 | } | 
 | 4465 |  | 
 | 4466 | /* Note:  tp_str is inherited from datetime. */ | 
 | 4467 |  | 
 | 4468 | static PyObject * | 
 | 4469 | datetimetz_isoformat(PyDateTime_DateTimeTZ *self, | 
 | 4470 | 		     PyObject *args, PyObject *kw) | 
 | 4471 | { | 
 | 4472 | 	char buf[100]; | 
 | 4473 | 	PyObject *result = datetime_isoformat((PyDateTime_DateTime *)self, | 
 | 4474 | 					      args, kw); | 
 | 4475 |  | 
 | 4476 | 	if (result == NULL || self->tzinfo == Py_None) | 
 | 4477 | 		return result; | 
 | 4478 |  | 
 | 4479 | 	/* We need to append the UTC offset. */ | 
 | 4480 | 	if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo, | 
 | 4481 | 			     (PyObject *)self) < 0) { | 
 | 4482 | 		Py_DECREF(result); | 
 | 4483 | 		return NULL; | 
 | 4484 | 	} | 
 | 4485 | 	PyString_ConcatAndDel(&result, PyString_FromString(buf)); | 
 | 4486 | 	return result; | 
 | 4487 | } | 
 | 4488 |  | 
 | 4489 | /* Miscellaneous methods. */ | 
 | 4490 |  | 
 | 4491 | /* Note:  tp_richcompare and tp_hash are inherited from datetime. */ | 
 | 4492 |  | 
 | 4493 | static PyObject * | 
 | 4494 | datetimetz_timetuple(PyDateTime_DateTimeTZ *self) | 
 | 4495 | { | 
 | 4496 | 	int dstflag = -1; | 
 | 4497 |  | 
 | 4498 | 	if (self->tzinfo != Py_None) { | 
 | 4499 | 		int none; | 
 | 4500 |  | 
 | 4501 | 		dstflag = call_dst(self->tzinfo, (PyObject *)self, &none); | 
 | 4502 | 		if (dstflag == -1 && PyErr_Occurred()) | 
 | 4503 | 			return NULL; | 
 | 4504 |  | 
 | 4505 | 		if (none) | 
 | 4506 | 			dstflag = -1; | 
 | 4507 | 		else if (dstflag != 0) | 
 | 4508 | 			dstflag = 1; | 
 | 4509 |  | 
 | 4510 | 	} | 
 | 4511 | 	return build_struct_time(GET_YEAR(self), | 
 | 4512 | 				 GET_MONTH(self), | 
 | 4513 | 				 GET_DAY(self), | 
 | 4514 | 				 DATE_GET_HOUR(self), | 
 | 4515 | 				 DATE_GET_MINUTE(self), | 
 | 4516 | 				 DATE_GET_SECOND(self), | 
 | 4517 | 				 dstflag); | 
 | 4518 | } | 
 | 4519 |  | 
 | 4520 | static PyObject * | 
 | 4521 | datetimetz_utctimetuple(PyDateTime_DateTimeTZ *self) | 
 | 4522 | { | 
 | 4523 | 	int y = GET_YEAR(self); | 
 | 4524 | 	int m = GET_MONTH(self); | 
 | 4525 | 	int d = GET_DAY(self); | 
 | 4526 | 	int hh = DATE_GET_HOUR(self); | 
 | 4527 | 	int mm = DATE_GET_MINUTE(self); | 
 | 4528 | 	int ss = DATE_GET_SECOND(self); | 
 | 4529 | 	int us = 0;	/* microseconds are ignored in a timetuple */ | 
 | 4530 | 	int offset = 0; | 
 | 4531 |  | 
 | 4532 | 	if (self->tzinfo != Py_None) { | 
 | 4533 | 		int none; | 
 | 4534 |  | 
 | 4535 | 		offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none); | 
 | 4536 | 		if (offset == -1 && PyErr_Occurred()) | 
 | 4537 | 			return NULL; | 
 | 4538 | 	} | 
 | 4539 | 	/* Even if offset is 0, don't call timetuple() -- tm_isdst should be | 
 | 4540 | 	 * 0 in a UTC timetuple regardless of what dst() says. | 
 | 4541 | 	 */ | 
 | 4542 | 	if (offset) { | 
 | 4543 | 		/* Subtract offset minutes & normalize. */ | 
 | 4544 | 		int stat; | 
 | 4545 |  | 
 | 4546 | 		mm -= offset; | 
 | 4547 | 		stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us); | 
 | 4548 | 		if (stat < 0) { | 
 | 4549 | 			/* At the edges, it's possible we overflowed | 
 | 4550 | 			 * beyond MINYEAR or MAXYEAR. | 
 | 4551 | 			 */ | 
 | 4552 | 			if (PyErr_ExceptionMatches(PyExc_OverflowError)) | 
 | 4553 | 				PyErr_Clear(); | 
 | 4554 | 			else | 
 | 4555 | 				return NULL; | 
 | 4556 | 		} | 
 | 4557 | 	} | 
 | 4558 | 	return build_struct_time(y, m, d, hh, mm, ss, 0); | 
 | 4559 | } | 
 | 4560 |  | 
 | 4561 | static PyObject * | 
 | 4562 | datetimetz_gettimetz(PyDateTime_DateTimeTZ *self) | 
 | 4563 | { | 
 | 4564 | 	return new_timetz(DATE_GET_HOUR(self), | 
 | 4565 | 			  DATE_GET_MINUTE(self), | 
 | 4566 | 			  DATE_GET_SECOND(self), | 
 | 4567 | 			  DATE_GET_MICROSECOND(self), | 
 | 4568 | 			  self->tzinfo); | 
 | 4569 | } | 
 | 4570 |  | 
 | 4571 | /* | 
 | 4572 |  * Pickle support.  Quite a maze! | 
 | 4573 |  */ | 
 | 4574 |  | 
 | 4575 | /* Let basestate be the state string returned by datetime_getstate. | 
 | 4576 |  * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). | 
 | 4577 |  * So it's a tuple in any (non-error) case. | 
 | 4578 |  */ | 
 | 4579 | static PyObject * | 
 | 4580 | datetimetz_getstate(PyDateTime_DateTimeTZ *self) | 
 | 4581 | { | 
 | 4582 | 	PyObject *basestate; | 
 | 4583 | 	PyObject *result = NULL; | 
 | 4584 |  | 
 | 4585 | 	basestate = datetime_getstate((PyDateTime_DateTime *)self); | 
 | 4586 | 	if (basestate != NULL) { | 
 | 4587 | 		if (self->tzinfo == Py_None) | 
 | 4588 | 			result = Py_BuildValue("(O)", basestate); | 
 | 4589 | 		else | 
 | 4590 | 			result = Py_BuildValue("OO", basestate, self->tzinfo); | 
 | 4591 | 		Py_DECREF(basestate); | 
 | 4592 | 	} | 
 | 4593 | 	return result; | 
 | 4594 | } | 
 | 4595 |  | 
 | 4596 | static PyObject * | 
 | 4597 | datetimetz_setstate(PyDateTime_DateTimeTZ *self, PyObject *state) | 
 | 4598 | { | 
 | 4599 | 	PyObject *temp; | 
 | 4600 | 	PyObject *basestate; | 
 | 4601 | 	PyObject *tzinfo = Py_None; | 
 | 4602 |  | 
 | 4603 | 	if (! PyArg_ParseTuple(state, "O!|O:__setstate__", | 
 | 4604 | 			       &PyString_Type, &basestate, | 
 | 4605 | 			       &tzinfo)) | 
 | 4606 | 		return NULL; | 
 | 4607 | 	temp = datetime_setstate((PyDateTime_DateTime *)self, basestate); | 
 | 4608 | 	if (temp == NULL) | 
 | 4609 | 		return NULL; | 
 | 4610 | 	Py_DECREF(temp); | 
 | 4611 |  | 
 | 4612 | 	Py_INCREF(tzinfo); | 
 | 4613 | 	Py_XDECREF(self->tzinfo); | 
 | 4614 | 	self->tzinfo = tzinfo; | 
 | 4615 |  | 
 | 4616 | 	Py_INCREF(Py_None); | 
 | 4617 | 	return Py_None; | 
 | 4618 | } | 
 | 4619 |  | 
 | 4620 | static PyObject * | 
 | 4621 | datetimetz_pickler(PyObject *module, PyDateTime_DateTimeTZ *datetimetz) | 
 | 4622 | { | 
 | 4623 | 	PyObject *state; | 
 | 4624 | 	PyObject *result = NULL; | 
 | 4625 |  | 
 | 4626 | 	if (! PyDateTimeTZ_CheckExact(datetimetz)) { | 
 | 4627 | 		PyErr_Format(PyExc_TypeError, | 
 | 4628 | 			     "bad type passed to datetimetz pickler: %s", | 
 | 4629 | 			     datetimetz->ob_type->tp_name); | 
 | 4630 | 		return NULL; | 
 | 4631 | 	} | 
 | 4632 | 	state = datetimetz_getstate(datetimetz); | 
 | 4633 | 	if (state) { | 
 | 4634 | 		result = Py_BuildValue("O(O)", | 
 | 4635 | 				       datetimetz_unpickler_object, | 
 | 4636 | 				       state); | 
 | 4637 | 		Py_DECREF(state); | 
 | 4638 | 	} | 
 | 4639 | 	return result; | 
 | 4640 | } | 
 | 4641 |  | 
 | 4642 | static PyObject * | 
 | 4643 | datetimetz_unpickler(PyObject *module, PyObject *arg) | 
 | 4644 | { | 
 | 4645 | 	PyDateTime_DateTimeTZ *self; | 
 | 4646 |  | 
 | 4647 | 	self = PyObject_New(PyDateTime_DateTimeTZ, &PyDateTime_DateTimeTZType); | 
 | 4648 | 	if (self != NULL) { | 
 | 4649 | 		PyObject *res; | 
 | 4650 |  | 
 | 4651 | 		self->tzinfo = NULL; | 
 | 4652 | 		res = datetimetz_setstate(self, arg); | 
 | 4653 | 		if (res == NULL) { | 
 | 4654 | 			Py_DECREF(self); | 
 | 4655 | 			return NULL; | 
 | 4656 | 		} | 
 | 4657 | 		Py_DECREF(res); | 
 | 4658 | 	} | 
 | 4659 | 	return (PyObject *)self; | 
 | 4660 | } | 
 | 4661 |  | 
 | 4662 |  | 
 | 4663 | static PyMethodDef datetimetz_methods[] = { | 
 | 4664 | 	/* Class methods: */ | 
 | 4665 | 	/* Inherited: combine(), utcnow(), utcfromtimestamp() */ | 
 | 4666 |  | 
 | 4667 | 	{"now",         (PyCFunction)datetimetz_now, | 
 | 4668 | 	 METH_KEYWORDS | METH_CLASS, | 
 | 4669 | 	 PyDoc_STR("[tzinfo] -> new datetimetz with local day and time.")}, | 
 | 4670 |  | 
 | 4671 | 	{"fromtimestamp", (PyCFunction)datetimetz_fromtimestamp, | 
 | 4672 | 	 METH_KEYWORDS | METH_CLASS, | 
 | 4673 | 	 PyDoc_STR("timestamp[, tzinfo] -> local time from POSIX timestamp.")}, | 
 | 4674 |  | 
 | 4675 | 	/* Instance methods: */ | 
 | 4676 | 	/* Inherited:  date(), time(), ctime(). */ | 
 | 4677 | 	{"timetuple",   (PyCFunction)datetimetz_timetuple, METH_NOARGS, | 
 | 4678 |          PyDoc_STR("Return time tuple, compatible with time.localtime().")}, | 
 | 4679 |  | 
 | 4680 | 	{"utctimetuple",   (PyCFunction)datetimetz_utctimetuple, METH_NOARGS, | 
 | 4681 |          PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")}, | 
 | 4682 |  | 
 | 4683 | 	{"timetz",   (PyCFunction)datetimetz_gettimetz, METH_NOARGS, | 
 | 4684 |          PyDoc_STR("Return timetz object with same hour, minute, second, " | 
 | 4685 |          	   "microsecond, and tzinfo.")}, | 
 | 4686 |  | 
 | 4687 | 	{"isoformat",   (PyCFunction)datetimetz_isoformat, METH_KEYWORDS, | 
 | 4688 | 	 PyDoc_STR("[sep] -> string in ISO 8601 format, " | 
 | 4689 | 	 	   "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n" | 
 | 4690 | 	 	   "sep is used to separate the year from the time, and " | 
 | 4691 | 	 	   "defaults to 'T'.")}, | 
 | 4692 |  | 
 | 4693 | 	{"utcoffset",	(PyCFunction)datetimetz_utcoffset, METH_NOARGS, | 
 | 4694 | 	 PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, | 
 | 4695 |  | 
 | 4696 | 	{"tzname",	(PyCFunction)datetimetz_tzname,	METH_NOARGS, | 
 | 4697 | 	 PyDoc_STR("Return self.tzinfo.tzname(self).")}, | 
 | 4698 |  | 
 | 4699 | 	{"dst",		(PyCFunction)datetimetz_dst, METH_NOARGS, | 
 | 4700 | 	 PyDoc_STR("Return self.tzinfo.dst(self).")}, | 
 | 4701 |  | 
 | 4702 | 	{"__setstate__", (PyCFunction)datetimetz_setstate, METH_O, | 
 | 4703 | 	 PyDoc_STR("__setstate__(state)")}, | 
 | 4704 |  | 
 | 4705 | 	{"__getstate__", (PyCFunction)datetimetz_getstate, METH_NOARGS, | 
 | 4706 | 	 PyDoc_STR("__getstate__() -> state")}, | 
 | 4707 | 	{NULL,	NULL} | 
 | 4708 | }; | 
 | 4709 |  | 
 | 4710 | static char datetimetz_doc[] = | 
 | 4711 | PyDoc_STR("date/time type."); | 
 | 4712 |  | 
 | 4713 | static PyNumberMethods datetimetz_as_number = { | 
 | 4714 | 	datetimetz_add,				/* nb_add */ | 
 | 4715 | 	datetimetz_subtract,			/* nb_subtract */ | 
 | 4716 | 	0,					/* nb_multiply */ | 
 | 4717 | 	0,					/* nb_divide */ | 
 | 4718 | 	0,					/* nb_remainder */ | 
 | 4719 | 	0,					/* nb_divmod */ | 
 | 4720 | 	0,					/* nb_power */ | 
 | 4721 | 	0,					/* nb_negative */ | 
 | 4722 | 	0,					/* nb_positive */ | 
 | 4723 | 	0,					/* nb_absolute */ | 
 | 4724 | 	0,					/* nb_nonzero */ | 
 | 4725 | }; | 
 | 4726 |  | 
 | 4727 | statichere PyTypeObject PyDateTime_DateTimeTZType = { | 
 | 4728 | 	PyObject_HEAD_INIT(NULL) | 
 | 4729 | 	0,					/* ob_size */ | 
 | 4730 | 	"datetime.datetimetz",			/* tp_name */ | 
 | 4731 | 	sizeof(PyDateTime_DateTimeTZ),		/* tp_basicsize */ | 
 | 4732 | 	0,					/* tp_itemsize */ | 
 | 4733 | 	(destructor)datetimetz_dealloc,		/* tp_dealloc */ | 
 | 4734 | 	0,					/* tp_print */ | 
 | 4735 | 	0,					/* tp_getattr */ | 
 | 4736 | 	0,					/* tp_setattr */ | 
 | 4737 | 	0,					/* tp_compare */ | 
 | 4738 | 	(reprfunc)datetimetz_repr,		/* tp_repr */ | 
 | 4739 | 	&datetimetz_as_number,			/* tp_as_number */ | 
 | 4740 | 	0,					/* tp_as_sequence */ | 
 | 4741 | 	0,					/* tp_as_mapping */ | 
 | 4742 | 	0,					/* tp_hash */ | 
 | 4743 | 	0,              			/* tp_call */ | 
 | 4744 | 	0,					/* tp_str */ | 
 | 4745 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 4746 | 	0,					/* tp_setattro */ | 
 | 4747 | 	0,					/* tp_as_buffer */ | 
 | 4748 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | | 
 | 4749 |         Py_TPFLAGS_BASETYPE,			/* tp_flags */ | 
 | 4750 | 	datetimetz_doc,				/* tp_doc */ | 
 | 4751 | 	0,					/* tp_traverse */ | 
 | 4752 | 	0,					/* tp_clear */ | 
 | 4753 | 	0,					/* tp_richcompare */ | 
 | 4754 | 	0,					/* tp_weaklistoffset */ | 
 | 4755 | 	0,					/* tp_iter */ | 
 | 4756 | 	0,					/* tp_iternext */ | 
 | 4757 | 	datetimetz_methods,			/* tp_methods */ | 
 | 4758 | 	0,					/* tp_members */ | 
 | 4759 | 	datetimetz_getset,			/* tp_getset */ | 
 | 4760 | 	&PyDateTime_DateTimeType,		/* tp_base */ | 
 | 4761 | 	0,					/* tp_dict */ | 
 | 4762 | 	0,					/* tp_descr_get */ | 
 | 4763 | 	0,					/* tp_descr_set */ | 
 | 4764 | 	0,					/* tp_dictoffset */ | 
 | 4765 | 	0,					/* tp_init */ | 
 | 4766 | 	0,					/* tp_alloc */ | 
 | 4767 | 	datetimetz_new,				/* tp_new */ | 
 | 4768 | 	_PyObject_Del,				/* tp_free */ | 
 | 4769 | }; | 
 | 4770 |  | 
 | 4771 | /* --------------------------------------------------------------------------- | 
 | 4772 |  * Module methods and initialization. | 
 | 4773 |  */ | 
 | 4774 |  | 
 | 4775 | static PyMethodDef module_methods[] = { | 
 | 4776 | 	/* Private functions for pickling support, registered with the | 
 | 4777 | 	 * copy_reg module by the module init function. | 
 | 4778 | 	 */ | 
 | 4779 | 	{"_date_pickler",	(PyCFunction)date_pickler,	METH_O, NULL}, | 
 | 4780 | 	{"_date_unpickler",	(PyCFunction)date_unpickler, 	METH_O, NULL}, | 
 | 4781 | 	{"_datetime_pickler",	(PyCFunction)datetime_pickler,	METH_O, NULL}, | 
 | 4782 | 	{"_datetime_unpickler",	(PyCFunction)datetime_unpickler,METH_O, NULL}, | 
 | 4783 | 	{"_datetimetz_pickler",	(PyCFunction)datetimetz_pickler,METH_O, NULL}, | 
 | 4784 | 	{"_datetimetz_unpickler",(PyCFunction)datetimetz_unpickler,METH_O, NULL}, | 
 | 4785 | 	{"_time_pickler",	(PyCFunction)time_pickler,	METH_O, NULL}, | 
 | 4786 | 	{"_time_unpickler",	(PyCFunction)time_unpickler,	METH_O, NULL}, | 
 | 4787 | 	{"_timetz_pickler",	(PyCFunction)timetz_pickler,	METH_O, NULL}, | 
 | 4788 | 	{"_timetz_unpickler",	(PyCFunction)timetz_unpickler,	METH_O, NULL}, | 
 | 4789 | 	{"_tzinfo_pickler",	(PyCFunction)tzinfo_pickler,	METH_O, NULL}, | 
 | 4790 | 	{"_tzinfo_unpickler",	(PyCFunction)tzinfo_unpickler,	METH_NOARGS, | 
 | 4791 | 	 NULL}, | 
 | 4792 | 	{NULL, NULL} | 
 | 4793 | }; | 
 | 4794 |  | 
 | 4795 | PyMODINIT_FUNC | 
 | 4796 | initdatetime(void) | 
 | 4797 | { | 
 | 4798 | 	PyObject *m;	/* a module object */ | 
 | 4799 | 	PyObject *d;	/* its dict */ | 
 | 4800 | 	PyObject *x; | 
 | 4801 |  | 
 | 4802 | 	/* Types that use __reduce__ for pickling need to set the following | 
 | 4803 | 	 * magical attr in the type dict, with a true value. | 
 | 4804 | 	 */ | 
 | 4805 | 	PyObject *safepickle = PyString_FromString("__safe_for_unpickling__"); | 
 | 4806 | 	if (safepickle == NULL) | 
 | 4807 | 		return; | 
 | 4808 |  | 
 | 4809 | 	m = Py_InitModule3("datetime", module_methods, | 
 | 4810 | 			   "Fast implementation of the datetime type."); | 
 | 4811 |  | 
 | 4812 | 	if (PyType_Ready(&PyDateTime_DateType) < 0) | 
 | 4813 | 		return; | 
 | 4814 | 	if (PyType_Ready(&PyDateTime_DateTimeType) < 0) | 
 | 4815 | 		return; | 
 | 4816 | 	if (PyType_Ready(&PyDateTime_DeltaType) < 0) | 
 | 4817 | 		return; | 
 | 4818 | 	if (PyType_Ready(&PyDateTime_TimeType) < 0) | 
 | 4819 | 		return; | 
 | 4820 | 	if (PyType_Ready(&PyDateTime_TZInfoType) < 0) | 
 | 4821 | 		return; | 
 | 4822 | 	if (PyType_Ready(&PyDateTime_TimeTZType) < 0) | 
 | 4823 | 		return; | 
 | 4824 | 	if (PyType_Ready(&PyDateTime_DateTimeTZType) < 0) | 
 | 4825 | 		return; | 
 | 4826 |  | 
 | 4827 | 	/* Pickling support, via registering functions with copy_reg. */ | 
 | 4828 | 	{ | 
 | 4829 | 		PyObject *pickler; | 
 | 4830 | 		PyObject *copyreg = PyImport_ImportModule("copy_reg"); | 
 | 4831 |  | 
 | 4832 | 		if (copyreg == NULL) return; | 
 | 4833 |  | 
 | 4834 | 		pickler = PyObject_GetAttrString(m, "_date_pickler"); | 
 | 4835 | 		if (pickler == NULL) return; | 
 | 4836 | 		date_unpickler_object = PyObject_GetAttrString(m, | 
 | 4837 | 						"_date_unpickler"); | 
 | 4838 | 		if (date_unpickler_object == NULL) return; | 
 | 4839 | 	    	x = PyObject_CallMethod(copyreg, "pickle", "OOO", | 
 | 4840 | 	    				&PyDateTime_DateType, | 
 | 4841 | 	    				pickler, | 
 | 4842 | 		                    	date_unpickler_object); | 
 | 4843 | 		if (x == NULL) return; | 
 | 4844 | 		Py_DECREF(x); | 
 | 4845 | 		Py_DECREF(pickler); | 
 | 4846 |  | 
 | 4847 | 		pickler = PyObject_GetAttrString(m, "_datetime_pickler"); | 
 | 4848 | 		if (pickler == NULL) return; | 
 | 4849 | 		datetime_unpickler_object = PyObject_GetAttrString(m, | 
 | 4850 | 						"_datetime_unpickler"); | 
 | 4851 | 		if (datetime_unpickler_object == NULL) return; | 
 | 4852 | 	    	x = PyObject_CallMethod(copyreg, "pickle", "OOO", | 
 | 4853 | 	    				&PyDateTime_DateTimeType, | 
 | 4854 | 	    				pickler, | 
 | 4855 | 		                    	datetime_unpickler_object); | 
 | 4856 | 		if (x == NULL) return; | 
 | 4857 | 		Py_DECREF(x); | 
 | 4858 | 		Py_DECREF(pickler); | 
 | 4859 |  | 
 | 4860 | 		pickler = PyObject_GetAttrString(m, "_time_pickler"); | 
 | 4861 | 		if (pickler == NULL) return; | 
 | 4862 | 		time_unpickler_object = PyObject_GetAttrString(m, | 
 | 4863 | 						"_time_unpickler"); | 
 | 4864 | 		if (time_unpickler_object == NULL) return; | 
 | 4865 | 	    	x = PyObject_CallMethod(copyreg, "pickle", "OOO", | 
 | 4866 | 	    				&PyDateTime_TimeType, | 
 | 4867 | 	    				pickler, | 
 | 4868 | 		                	time_unpickler_object); | 
 | 4869 | 		if (x == NULL) return; | 
 | 4870 | 		Py_DECREF(x); | 
 | 4871 | 		Py_DECREF(pickler); | 
 | 4872 |  | 
 | 4873 | 		pickler = PyObject_GetAttrString(m, "_timetz_pickler"); | 
 | 4874 | 		if (pickler == NULL) return; | 
 | 4875 | 		timetz_unpickler_object = PyObject_GetAttrString(m, | 
 | 4876 | 						"_timetz_unpickler"); | 
 | 4877 | 		if (timetz_unpickler_object == NULL) return; | 
 | 4878 | 	    	x = PyObject_CallMethod(copyreg, "pickle", "OOO", | 
 | 4879 | 	    				&PyDateTime_TimeTZType, | 
 | 4880 | 	    				pickler, | 
 | 4881 | 		                	timetz_unpickler_object); | 
 | 4882 | 		if (x == NULL) return; | 
 | 4883 | 		Py_DECREF(x); | 
 | 4884 | 		Py_DECREF(pickler); | 
 | 4885 |  | 
 | 4886 | 		pickler = PyObject_GetAttrString(m, "_tzinfo_pickler"); | 
 | 4887 | 		if (pickler == NULL) return; | 
 | 4888 | 		tzinfo_unpickler_object = PyObject_GetAttrString(m, | 
 | 4889 | 							"_tzinfo_unpickler"); | 
 | 4890 | 		if (tzinfo_unpickler_object == NULL) return; | 
 | 4891 | 	    	x = PyObject_CallMethod(copyreg, "pickle", "OOO", | 
 | 4892 | 	    				&PyDateTime_TZInfoType, | 
 | 4893 | 	    				pickler, | 
 | 4894 | 		        		tzinfo_unpickler_object); | 
 | 4895 | 		if (x== NULL) return; | 
 | 4896 | 		Py_DECREF(x); | 
 | 4897 | 		Py_DECREF(pickler); | 
 | 4898 |  | 
 | 4899 | 		pickler = PyObject_GetAttrString(m, "_datetimetz_pickler"); | 
 | 4900 | 		if (pickler == NULL) return; | 
 | 4901 | 		datetimetz_unpickler_object = PyObject_GetAttrString(m, | 
 | 4902 | 						 "_datetimetz_unpickler"); | 
 | 4903 | 		if (datetimetz_unpickler_object == NULL) return; | 
 | 4904 | 	    	x = PyObject_CallMethod(copyreg, "pickle", "OOO", | 
 | 4905 | 	    				&PyDateTime_DateTimeTZType, | 
 | 4906 | 	    				pickler, | 
 | 4907 | 		                	datetimetz_unpickler_object); | 
 | 4908 | 		if (x== NULL) return; | 
 | 4909 | 		Py_DECREF(x); | 
 | 4910 | 		Py_DECREF(pickler); | 
 | 4911 |  | 
 | 4912 | 		Py_DECREF(copyreg); | 
 | 4913 | 	} | 
 | 4914 |  | 
 | 4915 | 	/* timedelta values */ | 
 | 4916 | 	d = PyDateTime_DeltaType.tp_dict; | 
 | 4917 |  | 
 | 4918 | 	if (PyDict_SetItem(d, safepickle, Py_True) < 0) | 
 | 4919 | 		return; | 
 | 4920 |  | 
 | 4921 | 	x = new_delta(0, 0, 1, 0); | 
 | 4922 | 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) | 
 | 4923 | 		return; | 
 | 4924 | 	Py_DECREF(x); | 
 | 4925 |  | 
 | 4926 | 	x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0); | 
 | 4927 | 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) | 
 | 4928 | 		return; | 
 | 4929 | 	Py_DECREF(x); | 
 | 4930 |  | 
 | 4931 | 	x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0); | 
 | 4932 | 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) | 
 | 4933 | 		return; | 
 | 4934 | 	Py_DECREF(x); | 
 | 4935 |  | 
 | 4936 | 	/* date values */ | 
 | 4937 | 	d = PyDateTime_DateType.tp_dict; | 
 | 4938 |  | 
 | 4939 | 	x = new_date(1, 1, 1); | 
 | 4940 | 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) | 
 | 4941 | 		return; | 
 | 4942 | 	Py_DECREF(x); | 
 | 4943 |  | 
 | 4944 | 	x = new_date(MAXYEAR, 12, 31); | 
 | 4945 | 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) | 
 | 4946 | 		return; | 
 | 4947 | 	Py_DECREF(x); | 
 | 4948 |  | 
 | 4949 | 	x = new_delta(1, 0, 0, 0); | 
 | 4950 | 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) | 
 | 4951 | 		return; | 
 | 4952 | 	Py_DECREF(x); | 
 | 4953 |  | 
 | 4954 | 	/* datetime values */ | 
 | 4955 | 	d = PyDateTime_DateTimeType.tp_dict; | 
 | 4956 |  | 
 | 4957 | 	x = new_datetime(1, 1, 1, 0, 0, 0, 0); | 
 | 4958 | 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) | 
 | 4959 | 		return; | 
 | 4960 | 	Py_DECREF(x); | 
 | 4961 |  | 
 | 4962 | 	x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999); | 
 | 4963 | 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) | 
 | 4964 | 		return; | 
 | 4965 | 	Py_DECREF(x); | 
 | 4966 |  | 
 | 4967 | 	x = new_delta(0, 0, 1, 0); | 
 | 4968 | 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) | 
 | 4969 | 		return; | 
 | 4970 | 	Py_DECREF(x); | 
 | 4971 |  | 
 | 4972 | 	/* time values */ | 
 | 4973 | 	d = PyDateTime_TimeType.tp_dict; | 
 | 4974 |  | 
 | 4975 | 	x = new_time(0, 0, 0, 0); | 
 | 4976 | 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) | 
 | 4977 | 		return; | 
 | 4978 | 	Py_DECREF(x); | 
 | 4979 |  | 
 | 4980 | 	x = new_time(23, 59, 59, 999999); | 
 | 4981 | 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) | 
 | 4982 | 		return; | 
 | 4983 | 	Py_DECREF(x); | 
 | 4984 |  | 
 | 4985 | 	x = new_delta(0, 0, 1, 0); | 
 | 4986 | 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) | 
 | 4987 | 		return; | 
 | 4988 | 	Py_DECREF(x); | 
 | 4989 |  | 
 | 4990 | 	/* timetz values */ | 
 | 4991 | 	d = PyDateTime_TimeTZType.tp_dict; | 
 | 4992 |  | 
 | 4993 | 	x = new_timetz(0, 0, 0, 0, Py_None); | 
 | 4994 | 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) | 
 | 4995 | 		return; | 
 | 4996 | 	Py_DECREF(x); | 
 | 4997 |  | 
 | 4998 | 	x = new_timetz(23, 59, 59, 999999, Py_None); | 
 | 4999 | 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) | 
 | 5000 | 		return; | 
 | 5001 | 	Py_DECREF(x); | 
 | 5002 |  | 
 | 5003 | 	x = new_delta(0, 0, 1, 0); | 
 | 5004 | 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) | 
 | 5005 | 		return; | 
 | 5006 | 	Py_DECREF(x); | 
 | 5007 |  | 
 | 5008 | 	/* datetimetz values */ | 
 | 5009 | 	d = PyDateTime_DateTimeTZType.tp_dict; | 
 | 5010 |  | 
 | 5011 | 	x = new_datetimetz(1, 1, 1, 0, 0, 0, 0, Py_None); | 
 | 5012 | 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) | 
 | 5013 | 		return; | 
 | 5014 | 	Py_DECREF(x); | 
 | 5015 |  | 
 | 5016 | 	x = new_datetimetz(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None); | 
 | 5017 | 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) | 
 | 5018 | 		return; | 
 | 5019 | 	Py_DECREF(x); | 
 | 5020 |  | 
 | 5021 | 	x = new_delta(0, 0, 1, 0); | 
 | 5022 | 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) | 
 | 5023 | 		return; | 
 | 5024 | 	Py_DECREF(x); | 
 | 5025 |  | 
 | 5026 | 	Py_DECREF(safepickle); | 
 | 5027 |  | 
 | 5028 | 	/* module initialization */ | 
 | 5029 | 	PyModule_AddIntConstant(m, "MINYEAR", MINYEAR); | 
 | 5030 | 	PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR); | 
 | 5031 |  | 
 | 5032 | 	Py_INCREF(&PyDateTime_DateType); | 
 | 5033 | 	PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType); | 
 | 5034 |  | 
 | 5035 | 	Py_INCREF(&PyDateTime_DateTimeType); | 
 | 5036 | 	PyModule_AddObject(m, "datetime", | 
 | 5037 | 			   (PyObject *) &PyDateTime_DateTimeType); | 
 | 5038 |  | 
 | 5039 | 	Py_INCREF(&PyDateTime_DeltaType); | 
 | 5040 | 	PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType); | 
 | 5041 |  | 
 | 5042 | 	Py_INCREF(&PyDateTime_TimeType); | 
 | 5043 | 	PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType); | 
 | 5044 |  | 
 | 5045 | 	Py_INCREF(&PyDateTime_TZInfoType); | 
 | 5046 | 	PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); | 
 | 5047 |  | 
 | 5048 | 	Py_INCREF(&PyDateTime_TimeTZType); | 
 | 5049 | 	PyModule_AddObject(m, "timetz", (PyObject *) &PyDateTime_TimeTZType); | 
 | 5050 |  | 
 | 5051 | 	Py_INCREF(&PyDateTime_DateTimeTZType); | 
 | 5052 | 	PyModule_AddObject(m, "datetimetz", | 
 | 5053 | 			   (PyObject *)&PyDateTime_DateTimeTZType); | 
 | 5054 |  | 
 | 5055 | 	/* A 4-year cycle has an extra leap day over what we'd get from | 
 | 5056 | 	 * pasting together 4 single years. | 
 | 5057 | 	 */ | 
 | 5058 | 	assert(DI4Y == 4 * 365 + 1); | 
 | 5059 | 	assert(DI4Y == days_before_year(4+1)); | 
 | 5060 |  | 
 | 5061 | 	/* Similarly, a 400-year cycle has an extra leap day over what we'd | 
 | 5062 | 	 * get from pasting together 4 100-year cycles. | 
 | 5063 | 	 */ | 
 | 5064 | 	assert(DI400Y == 4 * DI100Y + 1); | 
 | 5065 | 	assert(DI400Y == days_before_year(400+1)); | 
 | 5066 |  | 
 | 5067 | 	/* OTOH, a 100-year cycle has one fewer leap day than we'd get from | 
 | 5068 | 	 * pasting together 25 4-year cycles. | 
 | 5069 | 	 */ | 
 | 5070 | 	assert(DI100Y == 25 * DI4Y - 1); | 
 | 5071 | 	assert(DI100Y == days_before_year(100+1)); | 
 | 5072 |  | 
 | 5073 | 	us_per_us = PyInt_FromLong(1); | 
 | 5074 | 	us_per_ms = PyInt_FromLong(1000); | 
 | 5075 | 	us_per_second = PyInt_FromLong(1000000); | 
 | 5076 | 	us_per_minute = PyInt_FromLong(60000000); | 
 | 5077 | 	seconds_per_day = PyInt_FromLong(24 * 3600); | 
 | 5078 | 	if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL || | 
 | 5079 | 	    us_per_minute == NULL || seconds_per_day == NULL) | 
 | 5080 | 		return; | 
 | 5081 |  | 
 | 5082 | 	/* The rest are too big for 32-bit ints, but even | 
 | 5083 | 	 * us_per_week fits in 40 bits, so doubles should be exact. | 
 | 5084 | 	 */ | 
 | 5085 | 	us_per_hour = PyLong_FromDouble(3600000000.0); | 
 | 5086 | 	us_per_day = PyLong_FromDouble(86400000000.0); | 
 | 5087 | 	us_per_week = PyLong_FromDouble(604800000000.0); | 
 | 5088 | 	if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) | 
 | 5089 | 		return; | 
 | 5090 | } |