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