1/* C implementation for the date/time type documented at 2 * https://www.zope.dev/Members/fdrake/DateTimeWiki/FrontPage 3 */ 4 5/* bpo-35081: Defining this prevents including the C API capsule; 6 * internal versions of the Py*_Check macros which do not require 7 * the capsule are defined below */ 8#define _PY_DATETIME_IMPL 9 10#ifndef Py_BUILD_CORE_BUILTIN 11# define Py_BUILD_CORE_MODULE 1 12#endif 13#define NEEDS_PY_IDENTIFIER 14 15#include "Python.h" 16#include "pycore_long.h" // _PyLong_GetOne() 17#include "pycore_object.h" // _PyObject_Init() 18#include "datetime.h" 19#include "structmember.h" // PyMemberDef 20 21#include <time.h> 22 23#ifdef MS_WINDOWS 24# include <winsock2.h> /* struct timeval */ 25#endif 26 27#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType) 28#define PyDate_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateType) 29 30#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType) 31#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateTimeType) 32 33#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType) 34#define PyTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TimeType) 35 36#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType) 37#define PyDelta_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DeltaType) 38 39#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType) 40#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TZInfoType) 41 42#define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType) 43 44/*[clinic input] 45module datetime 46class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" 47class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType" 48class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCalendarDateType" 49[clinic start generated code]*/ 50/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81bec0fa19837f63]*/ 51 52#include "clinic/_datetimemodule.c.h" 53 54/* We require that C int be at least 32 bits, and use int virtually 55 * everywhere. In just a few cases we use a temp long, where a Python 56 * API returns a C long. In such cases, we have to ensure that the 57 * final result fits in a C int (this can be an issue on 64-bit boxes). 58 */ 59#if SIZEOF_INT < 4 60# error "_datetime.c requires that C int have at least 32 bits" 61#endif 62 63#define MINYEAR 1 64#define MAXYEAR 9999 65#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */ 66 67/* Nine decimal digits is easy to communicate, and leaves enough room 68 * so that two delta days can be added w/o fear of overflowing a signed 69 * 32-bit int, and with plenty of room left over to absorb any possible 70 * carries from adding seconds. 71 */ 72#define MAX_DELTA_DAYS 999999999 73 74/* Rename the long macros in datetime.h to more reasonable short names. */ 75#define GET_YEAR PyDateTime_GET_YEAR 76#define GET_MONTH PyDateTime_GET_MONTH 77#define GET_DAY PyDateTime_GET_DAY 78#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR 79#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE 80#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND 81#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND 82#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD 83 84/* Date accessors for date and datetime. */ 85#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \ 86 ((o)->data[1] = ((v) & 0x00ff))) 87#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v)) 88#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v)) 89 90/* Date/Time accessors for datetime. */ 91#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v)) 92#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v)) 93#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v)) 94#define DATE_SET_MICROSECOND(o, v) \ 95 (((o)->data[7] = ((v) & 0xff0000) >> 16), \ 96 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \ 97 ((o)->data[9] = ((v) & 0x0000ff))) 98#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v)) 99 100/* Time accessors for time. */ 101#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR 102#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE 103#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND 104#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND 105#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD 106#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v)) 107#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v)) 108#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v)) 109#define TIME_SET_MICROSECOND(o, v) \ 110 (((o)->data[3] = ((v) & 0xff0000) >> 16), \ 111 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \ 112 ((o)->data[5] = ((v) & 0x0000ff))) 113#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v)) 114 115/* Delta accessors for timedelta. */ 116#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days) 117#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds) 118#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds) 119 120#define SET_TD_DAYS(o, v) ((o)->days = (v)) 121#define SET_TD_SECONDS(o, v) ((o)->seconds = (v)) 122#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v)) 123 124#define HASTZINFO _PyDateTime_HAS_TZINFO 125#define GET_TIME_TZINFO PyDateTime_TIME_GET_TZINFO 126#define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO 127/* M is a char or int claiming to be a valid month. The macro is equivalent 128 * to the two-sided Python test 129 * 1 <= M <= 12 130 */ 131#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12) 132 133/* Forward declarations. */ 134static PyTypeObject PyDateTime_DateType; 135static PyTypeObject PyDateTime_DateTimeType; 136static PyTypeObject PyDateTime_DeltaType; 137static PyTypeObject PyDateTime_IsoCalendarDateType; 138static PyTypeObject PyDateTime_TimeType; 139static PyTypeObject PyDateTime_TZInfoType; 140static PyTypeObject PyDateTime_TimeZoneType; 141 142static int check_tzinfo_subclass(PyObject *p); 143 144_Py_IDENTIFIER(as_integer_ratio); 145_Py_IDENTIFIER(fromutc); 146_Py_IDENTIFIER(isoformat); 147_Py_IDENTIFIER(strftime); 148 149/* --------------------------------------------------------------------------- 150 * Math utilities. 151 */ 152 153/* k = i+j overflows iff k differs in sign from both inputs, 154 * iff k^i has sign bit set and k^j has sign bit set, 155 * iff (k^i)&(k^j) has sign bit set. 156 */ 157#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \ 158 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0) 159 160/* Compute Python divmod(x, y), returning the quotient and storing the 161 * remainder into *r. The quotient is the floor of x/y, and that's 162 * the real point of this. C will probably truncate instead (C99 163 * requires truncation; C89 left it implementation-defined). 164 * Simplification: we *require* that y > 0 here. That's appropriate 165 * for all the uses made of it. This simplifies the code and makes 166 * the overflow case impossible (divmod(LONG_MIN, -1) is the only 167 * overflow case). 168 */ 169static int 170divmod(int x, int y, int *r) 171{ 172 int quo; 173 174 assert(y > 0); 175 quo = x / y; 176 *r = x - quo * y; 177 if (*r < 0) { 178 --quo; 179 *r += y; 180 } 181 assert(0 <= *r && *r < y); 182 return quo; 183} 184 185/* Nearest integer to m / n for integers m and n. Half-integer results 186 * are rounded to even. 187 */ 188static PyObject * 189divide_nearest(PyObject *m, PyObject *n) 190{ 191 PyObject *result; 192 PyObject *temp; 193 194 temp = _PyLong_DivmodNear(m, n); 195 if (temp == NULL) 196 return NULL; 197 result = PyTuple_GET_ITEM(temp, 0); 198 Py_INCREF(result); 199 Py_DECREF(temp); 200 201 return result; 202} 203 204/* --------------------------------------------------------------------------- 205 * General calendrical helper functions 206 */ 207 208/* For each month ordinal in 1..12, the number of days in that month, 209 * and the number of days before that month in the same year. These 210 * are correct for non-leap years only. 211 */ 212static const int _days_in_month[] = { 213 0, /* unused; this vector uses 1-based indexing */ 214 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 215}; 216 217static const int _days_before_month[] = { 218 0, /* unused; this vector uses 1-based indexing */ 219 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 220}; 221 222/* year -> 1 if leap year, else 0. */ 223static int 224is_leap(int year) 225{ 226 /* Cast year to unsigned. The result is the same either way, but 227 * C can generate faster code for unsigned mod than for signed 228 * mod (especially for % 4 -- a good compiler should just grab 229 * the last 2 bits when the LHS is unsigned). 230 */ 231 const unsigned int ayear = (unsigned int)year; 232 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0); 233} 234 235/* year, month -> number of days in that month in that year */ 236static int 237days_in_month(int year, int month) 238{ 239 assert(month >= 1); 240 assert(month <= 12); 241 if (month == 2 && is_leap(year)) 242 return 29; 243 else 244 return _days_in_month[month]; 245} 246 247/* year, month -> number of days in year preceding first day of month */ 248static int 249days_before_month(int year, int month) 250{ 251 int days; 252 253 assert(month >= 1); 254 assert(month <= 12); 255 days = _days_before_month[month]; 256 if (month > 2 && is_leap(year)) 257 ++days; 258 return days; 259} 260 261/* year -> number of days before January 1st of year. Remember that we 262 * start with year 1, so days_before_year(1) == 0. 263 */ 264static int 265days_before_year(int year) 266{ 267 int y = year - 1; 268 /* This is incorrect if year <= 0; we really want the floor 269 * here. But so long as MINYEAR is 1, the smallest year this 270 * can see is 1. 271 */ 272 assert (year >= 1); 273 return y*365 + y/4 - y/100 + y/400; 274} 275 276/* Number of days in 4, 100, and 400 year cycles. That these have 277 * the correct values is asserted in the module init function. 278 */ 279#define DI4Y 1461 /* days_before_year(5); days in 4 years */ 280#define DI100Y 36524 /* days_before_year(101); days in 100 years */ 281#define DI400Y 146097 /* days_before_year(401); days in 400 years */ 282 283/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */ 284static void 285ord_to_ymd(int ordinal, int *year, int *month, int *day) 286{ 287 int n, n1, n4, n100, n400, leapyear, preceding; 288 289 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of 290 * leap years repeats exactly every 400 years. The basic strategy is 291 * to find the closest 400-year boundary at or before ordinal, then 292 * work with the offset from that boundary to ordinal. Life is much 293 * clearer if we subtract 1 from ordinal first -- then the values 294 * of ordinal at 400-year boundaries are exactly those divisible 295 * by DI400Y: 296 * 297 * D M Y n n-1 298 * -- --- ---- ---------- ---------------- 299 * 31 Dec -400 -DI400Y -DI400Y -1 300 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary 301 * ... 302 * 30 Dec 000 -1 -2 303 * 31 Dec 000 0 -1 304 * 1 Jan 001 1 0 400-year boundary 305 * 2 Jan 001 2 1 306 * 3 Jan 001 3 2 307 * ... 308 * 31 Dec 400 DI400Y DI400Y -1 309 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary 310 */ 311 assert(ordinal >= 1); 312 --ordinal; 313 n400 = ordinal / DI400Y; 314 n = ordinal % DI400Y; 315 *year = n400 * 400 + 1; 316 317 /* Now n is the (non-negative) offset, in days, from January 1 of 318 * year, to the desired date. Now compute how many 100-year cycles 319 * precede n. 320 * Note that it's possible for n100 to equal 4! In that case 4 full 321 * 100-year cycles precede the desired day, which implies the 322 * desired day is December 31 at the end of a 400-year cycle. 323 */ 324 n100 = n / DI100Y; 325 n = n % DI100Y; 326 327 /* Now compute how many 4-year cycles precede it. */ 328 n4 = n / DI4Y; 329 n = n % DI4Y; 330 331 /* And now how many single years. Again n1 can be 4, and again 332 * meaning that the desired day is December 31 at the end of the 333 * 4-year cycle. 334 */ 335 n1 = n / 365; 336 n = n % 365; 337 338 *year += n100 * 100 + n4 * 4 + n1; 339 if (n1 == 4 || n100 == 4) { 340 assert(n == 0); 341 *year -= 1; 342 *month = 12; 343 *day = 31; 344 return; 345 } 346 347 /* Now the year is correct, and n is the offset from January 1. We 348 * find the month via an estimate that's either exact or one too 349 * large. 350 */ 351 leapyear = n1 == 3 && (n4 != 24 || n100 == 3); 352 assert(leapyear == is_leap(*year)); 353 *month = (n + 50) >> 5; 354 preceding = (_days_before_month[*month] + (*month > 2 && leapyear)); 355 if (preceding > n) { 356 /* estimate is too large */ 357 *month -= 1; 358 preceding -= days_in_month(*year, *month); 359 } 360 n -= preceding; 361 assert(0 <= n); 362 assert(n < days_in_month(*year, *month)); 363 364 *day = n + 1; 365} 366 367/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */ 368static int 369ymd_to_ord(int year, int month, int day) 370{ 371 return days_before_year(year) + days_before_month(year, month) + day; 372} 373 374/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */ 375static int 376weekday(int year, int month, int day) 377{ 378 return (ymd_to_ord(year, month, day) + 6) % 7; 379} 380 381/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the 382 * first calendar week containing a Thursday. 383 */ 384static int 385iso_week1_monday(int year) 386{ 387 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */ 388 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */ 389 int first_weekday = (first_day + 6) % 7; 390 /* ordinal of closest Monday at or before 1/1 */ 391 int week1_monday = first_day - first_weekday; 392 393 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */ 394 week1_monday += 7; 395 return week1_monday; 396} 397 398static int 399iso_to_ymd(const int iso_year, const int iso_week, const int iso_day, 400 int *year, int *month, int *day) { 401 if (iso_week <= 0 || iso_week >= 53) { 402 int out_of_range = 1; 403 if (iso_week == 53) { 404 // ISO years have 53 weeks in it on years starting with a Thursday 405 // and on leap years starting on Wednesday 406 int first_weekday = weekday(iso_year, 1, 1); 407 if (first_weekday == 3 || (first_weekday == 2 && is_leap(iso_year))) { 408 out_of_range = 0; 409 } 410 } 411 412 if (out_of_range) { 413 return -2; 414 } 415 } 416 417 if (iso_day <= 0 || iso_day >= 8) { 418 return -3; 419 } 420 421 // Convert (Y, W, D) to (Y, M, D) in-place 422 int day_1 = iso_week1_monday(iso_year); 423 424 int day_offset = (iso_week - 1)*7 + iso_day - 1; 425 426 ord_to_ymd(day_1 + day_offset, year, month, day); 427 return 0; 428} 429 430 431/* --------------------------------------------------------------------------- 432 * Range checkers. 433 */ 434 435/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0. 436 * If not, raise OverflowError and return -1. 437 */ 438static int 439check_delta_day_range(int days) 440{ 441 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS) 442 return 0; 443 PyErr_Format(PyExc_OverflowError, 444 "days=%d; must have magnitude <= %d", 445 days, MAX_DELTA_DAYS); 446 return -1; 447} 448 449/* Check that date arguments are in range. Return 0 if they are. If they 450 * aren't, raise ValueError and return -1. 451 */ 452static int 453check_date_args(int year, int month, int day) 454{ 455 456 if (year < MINYEAR || year > MAXYEAR) { 457 PyErr_Format(PyExc_ValueError, "year %i is out of range", year); 458 return -1; 459 } 460 if (month < 1 || month > 12) { 461 PyErr_SetString(PyExc_ValueError, 462 "month must be in 1..12"); 463 return -1; 464 } 465 if (day < 1 || day > days_in_month(year, month)) { 466 PyErr_SetString(PyExc_ValueError, 467 "day is out of range for month"); 468 return -1; 469 } 470 return 0; 471} 472 473/* Check that time arguments are in range. Return 0 if they are. If they 474 * aren't, raise ValueError and return -1. 475 */ 476static int 477check_time_args(int h, int m, int s, int us, int fold) 478{ 479 if (h < 0 || h > 23) { 480 PyErr_SetString(PyExc_ValueError, 481 "hour must be in 0..23"); 482 return -1; 483 } 484 if (m < 0 || m > 59) { 485 PyErr_SetString(PyExc_ValueError, 486 "minute must be in 0..59"); 487 return -1; 488 } 489 if (s < 0 || s > 59) { 490 PyErr_SetString(PyExc_ValueError, 491 "second must be in 0..59"); 492 return -1; 493 } 494 if (us < 0 || us > 999999) { 495 PyErr_SetString(PyExc_ValueError, 496 "microsecond must be in 0..999999"); 497 return -1; 498 } 499 if (fold != 0 && fold != 1) { 500 PyErr_SetString(PyExc_ValueError, 501 "fold must be either 0 or 1"); 502 return -1; 503 } 504 return 0; 505} 506 507/* --------------------------------------------------------------------------- 508 * Normalization utilities. 509 */ 510 511/* One step of a mixed-radix conversion. A "hi" unit is equivalent to 512 * factor "lo" units. factor must be > 0. If *lo is less than 0, or 513 * at least factor, enough of *lo is converted into "hi" units so that 514 * 0 <= *lo < factor. The input values must be such that int overflow 515 * is impossible. 516 */ 517static void 518normalize_pair(int *hi, int *lo, int factor) 519{ 520 assert(factor > 0); 521 assert(lo != hi); 522 if (*lo < 0 || *lo >= factor) { 523 const int num_hi = divmod(*lo, factor, lo); 524 const int new_hi = *hi + num_hi; 525 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi)); 526 *hi = new_hi; 527 } 528 assert(0 <= *lo && *lo < factor); 529} 530 531/* Fiddle days (d), seconds (s), and microseconds (us) so that 532 * 0 <= *s < 24*3600 533 * 0 <= *us < 1000000 534 * The input values must be such that the internals don't overflow. 535 * The way this routine is used, we don't get close. 536 */ 537static void 538normalize_d_s_us(int *d, int *s, int *us) 539{ 540 if (*us < 0 || *us >= 1000000) { 541 normalize_pair(s, us, 1000000); 542 /* |s| can't be bigger than about 543 * |original s| + |original us|/1000000 now. 544 */ 545 546 } 547 if (*s < 0 || *s >= 24*3600) { 548 normalize_pair(d, s, 24*3600); 549 /* |d| can't be bigger than about 550 * |original d| + 551 * (|original s| + |original us|/1000000) / (24*3600) now. 552 */ 553 } 554 assert(0 <= *s && *s < 24*3600); 555 assert(0 <= *us && *us < 1000000); 556} 557 558/* Fiddle years (y), months (m), and days (d) so that 559 * 1 <= *m <= 12 560 * 1 <= *d <= days_in_month(*y, *m) 561 * The input values must be such that the internals don't overflow. 562 * The way this routine is used, we don't get close. 563 */ 564static int 565normalize_y_m_d(int *y, int *m, int *d) 566{ 567 int dim; /* # of days in month */ 568 569 /* In actual use, m is always the month component extracted from a 570 * date/datetime object. Therefore it is always in [1, 12] range. 571 */ 572 573 assert(1 <= *m && *m <= 12); 574 575 /* Now only day can be out of bounds (year may also be out of bounds 576 * for a datetime object, but we don't care about that here). 577 * If day is out of bounds, what to do is arguable, but at least the 578 * method here is principled and explainable. 579 */ 580 dim = days_in_month(*y, *m); 581 if (*d < 1 || *d > dim) { 582 /* Move day-1 days from the first of the month. First try to 583 * get off cheap if we're only one day out of range 584 * (adjustments for timezone alone can't be worse than that). 585 */ 586 if (*d == 0) { 587 --*m; 588 if (*m > 0) 589 *d = days_in_month(*y, *m); 590 else { 591 --*y; 592 *m = 12; 593 *d = 31; 594 } 595 } 596 else if (*d == dim + 1) { 597 /* move forward a day */ 598 ++*m; 599 *d = 1; 600 if (*m > 12) { 601 *m = 1; 602 ++*y; 603 } 604 } 605 else { 606 int ordinal = ymd_to_ord(*y, *m, 1) + 607 *d - 1; 608 if (ordinal < 1 || ordinal > MAXORDINAL) { 609 goto error; 610 } else { 611 ord_to_ymd(ordinal, y, m, d); 612 return 0; 613 } 614 } 615 } 616 assert(*m > 0); 617 assert(*d > 0); 618 if (MINYEAR <= *y && *y <= MAXYEAR) 619 return 0; 620 error: 621 PyErr_SetString(PyExc_OverflowError, 622 "date value out of range"); 623 return -1; 624 625} 626 627/* Fiddle out-of-bounds months and days so that the result makes some kind 628 * of sense. The parameters are both inputs and outputs. Returns < 0 on 629 * failure, where failure means the adjusted year is out of bounds. 630 */ 631static int 632normalize_date(int *year, int *month, int *day) 633{ 634 return normalize_y_m_d(year, month, day); 635} 636 637/* Force all the datetime fields into range. The parameters are both 638 * inputs and outputs. Returns < 0 on error. 639 */ 640static int 641normalize_datetime(int *year, int *month, int *day, 642 int *hour, int *minute, int *second, 643 int *microsecond) 644{ 645 normalize_pair(second, microsecond, 1000000); 646 normalize_pair(minute, second, 60); 647 normalize_pair(hour, minute, 60); 648 normalize_pair(day, hour, 24); 649 return normalize_date(year, month, day); 650} 651 652/* --------------------------------------------------------------------------- 653 * Basic object allocation: tp_alloc implementations. These allocate 654 * Python objects of the right size and type, and do the Python object- 655 * initialization bit. If there's not enough memory, they return NULL after 656 * setting MemoryError. All data members remain uninitialized trash. 657 * 658 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo 659 * member is needed. This is ugly, imprecise, and possibly insecure. 660 * tp_basicsize for the time and datetime types is set to the size of the 661 * struct that has room for the tzinfo member, so subclasses in Python will 662 * allocate enough space for a tzinfo member whether or not one is actually 663 * needed. That's the "ugly and imprecise" parts. The "possibly insecure" 664 * part is that PyType_GenericAlloc() (which subclasses in Python end up 665 * using) just happens today to effectively ignore the nitems argument 666 * when tp_itemsize is 0, which it is for these type objects. If that 667 * changes, perhaps the callers of tp_alloc slots in this file should 668 * be changed to force a 0 nitems argument unless the type being allocated 669 * is a base type implemented in this file (so that tp_alloc is time_alloc 670 * or datetime_alloc below, which know about the nitems abuse). 671 */ 672 673static PyObject * 674time_alloc(PyTypeObject *type, Py_ssize_t aware) 675{ 676 size_t size = aware ? sizeof(PyDateTime_Time) : sizeof(_PyDateTime_BaseTime); 677 PyObject *self = (PyObject *)PyObject_Malloc(size); 678 if (self == NULL) { 679 return PyErr_NoMemory(); 680 } 681 _PyObject_Init(self, type); 682 return self; 683} 684 685static PyObject * 686datetime_alloc(PyTypeObject *type, Py_ssize_t aware) 687{ 688 size_t size = aware ? sizeof(PyDateTime_DateTime) : sizeof(_PyDateTime_BaseDateTime); 689 PyObject *self = (PyObject *)PyObject_Malloc(size); 690 if (self == NULL) { 691 return PyErr_NoMemory(); 692 } 693 _PyObject_Init(self, type); 694 return self; 695} 696 697/* --------------------------------------------------------------------------- 698 * Helpers for setting object fields. These work on pointers to the 699 * appropriate base class. 700 */ 701 702/* For date and datetime. */ 703static void 704set_date_fields(PyDateTime_Date *self, int y, int m, int d) 705{ 706 self->hashcode = -1; 707 SET_YEAR(self, y); 708 SET_MONTH(self, m); 709 SET_DAY(self, d); 710} 711 712/* --------------------------------------------------------------------------- 713 * String parsing utilities and helper functions 714 */ 715 716static unsigned char 717is_digit(const char c) { 718 return ((unsigned int)(c - '0')) < 10; 719} 720 721static const char * 722parse_digits(const char *ptr, int *var, size_t num_digits) 723{ 724 for (size_t i = 0; i < num_digits; ++i) { 725 unsigned int tmp = (unsigned int)(*(ptr++) - '0'); 726 if (tmp > 9) { 727 return NULL; 728 } 729 *var *= 10; 730 *var += (signed int)tmp; 731 } 732 733 return ptr; 734} 735 736static int 737parse_isoformat_date(const char *dtstr, const size_t len, int *year, int *month, int *day) 738{ 739 /* Parse the date components of the result of date.isoformat() 740 * 741 * Return codes: 742 * 0: Success 743 * -1: Failed to parse date component 744 * -2: Inconsistent date separator usage 745 * -3: Failed to parse ISO week. 746 * -4: Failed to parse ISO day. 747 * -5, -6: Failure in iso_to_ymd 748 */ 749 const char *p = dtstr; 750 p = parse_digits(p, year, 4); 751 if (NULL == p) { 752 return -1; 753 } 754 755 const unsigned char uses_separator = (*p == '-'); 756 if (uses_separator) { 757 ++p; 758 } 759 760 if(*p == 'W') { 761 // This is an isocalendar-style date string 762 p++; 763 int iso_week = 0; 764 int iso_day = 0; 765 766 p = parse_digits(p, &iso_week, 2); 767 if (NULL == p) { 768 return -3; 769 } 770 771 assert(p > dtstr); 772 if ((size_t)(p - dtstr) < len) { 773 if (uses_separator && *(p++) != '-') { 774 return -2; 775 } 776 777 p = parse_digits(p, &iso_day, 1); 778 if (NULL == p) { 779 return -4; 780 } 781 } else { 782 iso_day = 1; 783 } 784 785 int rv = iso_to_ymd(*year, iso_week, iso_day, year, month, day); 786 if (rv) { 787 return -3 + rv; 788 } else { 789 return 0; 790 } 791 } 792 793 p = parse_digits(p, month, 2); 794 if (NULL == p) { 795 return -1; 796 } 797 798 if (uses_separator && *(p++) != '-') { 799 return -2; 800 } 801 p = parse_digits(p, day, 2); 802 if (p == NULL) { 803 return -1; 804 } 805 return 0; 806} 807 808static int 809parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour, 810 int *minute, int *second, int *microsecond) 811{ 812 *hour = *minute = *second = *microsecond = 0; 813 const char *p = tstr; 814 const char *p_end = tstr_end; 815 int *vals[3] = {hour, minute, second}; 816 // This is initialized to satisfy an erroneous compiler warning. 817 unsigned char has_separator = 1; 818 819 // Parse [HH[:?MM[:?SS]]] 820 for (size_t i = 0; i < 3; ++i) { 821 p = parse_digits(p, vals[i], 2); 822 if (NULL == p) { 823 return -3; 824 } 825 826 char c = *(p++); 827 if (i == 0) { 828 has_separator = (c == ':'); 829 } 830 831 if (p >= p_end) { 832 return c != '\0'; 833 } 834 else if (has_separator && (c == ':')) { 835 continue; 836 } 837 else if (c == '.' || c == ',') { 838 break; 839 } else if (!has_separator) { 840 --p; 841 } else { 842 return -4; // Malformed time separator 843 } 844 } 845 846 // Parse fractional components 847 size_t len_remains = p_end - p; 848 size_t to_parse = len_remains; 849 if (len_remains >= 6) { 850 to_parse = 6; 851 } 852 853 p = parse_digits(p, microsecond, to_parse); 854 if (NULL == p) { 855 return -3; 856 } 857 858 static int correction[] = { 859 100000, 10000, 1000, 100, 10 860 }; 861 862 if (to_parse < 6) { 863 *microsecond *= correction[to_parse-1]; 864 } 865 866 while (is_digit(*p)){ 867 ++p; // skip truncated digits 868 } 869 870 // Return 1 if it's not the end of the string 871 return *p != '\0'; 872} 873 874static int 875parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute, 876 int *second, int *microsecond, int *tzoffset, 877 int *tzmicrosecond) 878{ 879 // Parse the time portion of a datetime.isoformat() string 880 // 881 // Return codes: 882 // 0: Success (no tzoffset) 883 // 1: Success (with tzoffset) 884 // -3: Failed to parse time component 885 // -4: Failed to parse time separator 886 // -5: Malformed timezone string 887 888 const char *p = dtstr; 889 const char *p_end = dtstr + dtlen; 890 891 const char *tzinfo_pos = p; 892 do { 893 if (*tzinfo_pos == 'Z' || *tzinfo_pos == '+' || *tzinfo_pos == '-') { 894 break; 895 } 896 } while (++tzinfo_pos < p_end); 897 898 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second, 899 microsecond); 900 901 if (rv < 0) { 902 return rv; 903 } 904 else if (tzinfo_pos == p_end) { 905 // We know that there's no time zone, so if there's stuff at the 906 // end of the string it's an error. 907 if (rv == 1) { 908 return -5; 909 } 910 else { 911 return 0; 912 } 913 } 914 915 // Special case UTC / Zulu time. 916 if (*tzinfo_pos == 'Z') { 917 *tzoffset = 0; 918 *tzmicrosecond = 0; 919 920 if (*(tzinfo_pos + 1) != '\0') { 921 return -5; 922 } else { 923 return 1; 924 } 925 } 926 927 int tzsign = (*tzinfo_pos == '-') ? -1 : 1; 928 tzinfo_pos++; 929 int tzhour = 0, tzminute = 0, tzsecond = 0; 930 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond, 931 tzmicrosecond); 932 933 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond); 934 *tzmicrosecond *= tzsign; 935 936 return rv ? -5 : 1; 937} 938 939/* --------------------------------------------------------------------------- 940 * Create various objects, mostly without range checking. 941 */ 942 943/* Create a date instance with no range checking. */ 944static PyObject * 945new_date_ex(int year, int month, int day, PyTypeObject *type) 946{ 947 PyDateTime_Date *self; 948 949 if (check_date_args(year, month, day) < 0) { 950 return NULL; 951 } 952 953 self = (PyDateTime_Date *)(type->tp_alloc(type, 0)); 954 if (self != NULL) 955 set_date_fields(self, year, month, day); 956 return (PyObject *)self; 957} 958 959#define new_date(year, month, day) \ 960 new_date_ex(year, month, day, &PyDateTime_DateType) 961 962// Forward declaration 963static PyObject * 964new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *); 965 966/* Create date instance with no range checking, or call subclass constructor */ 967static PyObject * 968new_date_subclass_ex(int year, int month, int day, PyObject *cls) 969{ 970 PyObject *result; 971 // We have "fast path" constructors for two subclasses: date and datetime 972 if ((PyTypeObject *)cls == &PyDateTime_DateType) { 973 result = new_date_ex(year, month, day, (PyTypeObject *)cls); 974 } 975 else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) { 976 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None, 977 (PyTypeObject *)cls); 978 } 979 else { 980 result = PyObject_CallFunction(cls, "iii", year, month, day); 981 } 982 983 return result; 984} 985 986/* Create a datetime instance with no range checking. */ 987static PyObject * 988new_datetime_ex2(int year, int month, int day, int hour, int minute, 989 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type) 990{ 991 PyDateTime_DateTime *self; 992 char aware = tzinfo != Py_None; 993 994 if (check_date_args(year, month, day) < 0) { 995 return NULL; 996 } 997 if (check_time_args(hour, minute, second, usecond, fold) < 0) { 998 return NULL; 999 } 1000 if (check_tzinfo_subclass(tzinfo) < 0) { 1001 return NULL; 1002 } 1003 1004 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware)); 1005 if (self != NULL) { 1006 self->hastzinfo = aware; 1007 set_date_fields((PyDateTime_Date *)self, year, month, day); 1008 DATE_SET_HOUR(self, hour); 1009 DATE_SET_MINUTE(self, minute); 1010 DATE_SET_SECOND(self, second); 1011 DATE_SET_MICROSECOND(self, usecond); 1012 if (aware) { 1013 Py_INCREF(tzinfo); 1014 self->tzinfo = tzinfo; 1015 } 1016 DATE_SET_FOLD(self, fold); 1017 } 1018 return (PyObject *)self; 1019} 1020 1021static PyObject * 1022new_datetime_ex(int year, int month, int day, int hour, int minute, 1023 int second, int usecond, PyObject *tzinfo, PyTypeObject *type) 1024{ 1025 return new_datetime_ex2(year, month, day, hour, minute, second, usecond, 1026 tzinfo, 0, type); 1027} 1028 1029#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \ 1030 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \ 1031 &PyDateTime_DateTimeType) 1032 1033static PyObject * 1034new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute, 1035 int second, int usecond, PyObject *tzinfo, 1036 int fold, PyObject *cls) { 1037 PyObject* dt; 1038 if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) { 1039 // Use the fast path constructor 1040 dt = new_datetime(year, month, day, hour, minute, second, usecond, 1041 tzinfo, fold); 1042 } else { 1043 // Subclass 1044 dt = PyObject_CallFunction(cls, "iiiiiiiO", 1045 year, 1046 month, 1047 day, 1048 hour, 1049 minute, 1050 second, 1051 usecond, 1052 tzinfo); 1053 } 1054 1055 return dt; 1056} 1057 1058static PyObject * 1059new_datetime_subclass_ex(int year, int month, int day, int hour, int minute, 1060 int second, int usecond, PyObject *tzinfo, 1061 PyObject *cls) { 1062 return new_datetime_subclass_fold_ex(year, month, day, hour, minute, 1063 second, usecond, tzinfo, 0, 1064 cls); 1065} 1066 1067/* Create a time instance with no range checking. */ 1068static PyObject * 1069new_time_ex2(int hour, int minute, int second, int usecond, 1070 PyObject *tzinfo, int fold, PyTypeObject *type) 1071{ 1072 PyDateTime_Time *self; 1073 char aware = tzinfo != Py_None; 1074 1075 if (check_time_args(hour, minute, second, usecond, fold) < 0) { 1076 return NULL; 1077 } 1078 if (check_tzinfo_subclass(tzinfo) < 0) { 1079 return NULL; 1080 } 1081 1082 self = (PyDateTime_Time *) (type->tp_alloc(type, aware)); 1083 if (self != NULL) { 1084 self->hastzinfo = aware; 1085 self->hashcode = -1; 1086 TIME_SET_HOUR(self, hour); 1087 TIME_SET_MINUTE(self, minute); 1088 TIME_SET_SECOND(self, second); 1089 TIME_SET_MICROSECOND(self, usecond); 1090 if (aware) { 1091 Py_INCREF(tzinfo); 1092 self->tzinfo = tzinfo; 1093 } 1094 TIME_SET_FOLD(self, fold); 1095 } 1096 return (PyObject *)self; 1097} 1098 1099static PyObject * 1100new_time_ex(int hour, int minute, int second, int usecond, 1101 PyObject *tzinfo, PyTypeObject *type) 1102{ 1103 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type); 1104} 1105 1106#define new_time(hh, mm, ss, us, tzinfo, fold) \ 1107 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType) 1108 1109/* Create a timedelta instance. Normalize the members iff normalize is 1110 * true. Passing false is a speed optimization, if you know for sure 1111 * that seconds and microseconds are already in their proper ranges. In any 1112 * case, raises OverflowError and returns NULL if the normalized days is out 1113 * of range. 1114 */ 1115static PyObject * 1116new_delta_ex(int days, int seconds, int microseconds, int normalize, 1117 PyTypeObject *type) 1118{ 1119 PyDateTime_Delta *self; 1120 1121 if (normalize) 1122 normalize_d_s_us(&days, &seconds, µseconds); 1123 assert(0 <= seconds && seconds < 24*3600); 1124 assert(0 <= microseconds && microseconds < 1000000); 1125 1126 if (check_delta_day_range(days) < 0) 1127 return NULL; 1128 1129 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0)); 1130 if (self != NULL) { 1131 self->hashcode = -1; 1132 SET_TD_DAYS(self, days); 1133 SET_TD_SECONDS(self, seconds); 1134 SET_TD_MICROSECONDS(self, microseconds); 1135 } 1136 return (PyObject *) self; 1137} 1138 1139#define new_delta(d, s, us, normalize) \ 1140 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType) 1141 1142 1143typedef struct 1144{ 1145 PyObject_HEAD 1146 PyObject *offset; 1147 PyObject *name; 1148} PyDateTime_TimeZone; 1149 1150/* The interned UTC timezone instance */ 1151static PyObject *PyDateTime_TimeZone_UTC; 1152/* The interned Epoch datetime instance */ 1153static PyObject *PyDateTime_Epoch; 1154 1155/* Create new timezone instance checking offset range. This 1156 function does not check the name argument. Caller must assure 1157 that offset is a timedelta instance and name is either NULL 1158 or a unicode object. */ 1159static PyObject * 1160create_timezone(PyObject *offset, PyObject *name) 1161{ 1162 PyDateTime_TimeZone *self; 1163 PyTypeObject *type = &PyDateTime_TimeZoneType; 1164 1165 assert(offset != NULL); 1166 assert(PyDelta_Check(offset)); 1167 assert(name == NULL || PyUnicode_Check(name)); 1168 1169 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0)); 1170 if (self == NULL) { 1171 return NULL; 1172 } 1173 Py_INCREF(offset); 1174 self->offset = offset; 1175 Py_XINCREF(name); 1176 self->name = name; 1177 return (PyObject *)self; 1178} 1179 1180static int delta_bool(PyDateTime_Delta *self); 1181 1182static PyObject * 1183new_timezone(PyObject *offset, PyObject *name) 1184{ 1185 assert(offset != NULL); 1186 assert(PyDelta_Check(offset)); 1187 assert(name == NULL || PyUnicode_Check(name)); 1188 1189 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) { 1190 Py_INCREF(PyDateTime_TimeZone_UTC); 1191 return PyDateTime_TimeZone_UTC; 1192 } 1193 if ((GET_TD_DAYS(offset) == -1 && 1194 GET_TD_SECONDS(offset) == 0 && 1195 GET_TD_MICROSECONDS(offset) < 1) || 1196 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { 1197 PyErr_Format(PyExc_ValueError, "offset must be a timedelta" 1198 " strictly between -timedelta(hours=24) and" 1199 " timedelta(hours=24)," 1200 " not %R.", offset); 1201 return NULL; 1202 } 1203 1204 return create_timezone(offset, name); 1205} 1206 1207/* --------------------------------------------------------------------------- 1208 * tzinfo helpers. 1209 */ 1210 1211/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not 1212 * raise TypeError and return -1. 1213 */ 1214static int 1215check_tzinfo_subclass(PyObject *p) 1216{ 1217 if (p == Py_None || PyTZInfo_Check(p)) 1218 return 0; 1219 PyErr_Format(PyExc_TypeError, 1220 "tzinfo argument must be None or of a tzinfo subclass, " 1221 "not type '%s'", 1222 Py_TYPE(p)->tp_name); 1223 return -1; 1224} 1225 1226/* If self has a tzinfo member, return a BORROWED reference to it. Else 1227 * return NULL, which is NOT AN ERROR. There are no error returns here, 1228 * and the caller must not decref the result. 1229 */ 1230static PyObject * 1231get_tzinfo_member(PyObject *self) 1232{ 1233 PyObject *tzinfo = NULL; 1234 1235 if (PyDateTime_Check(self) && HASTZINFO(self)) 1236 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo; 1237 else if (PyTime_Check(self) && HASTZINFO(self)) 1238 tzinfo = ((PyDateTime_Time *)self)->tzinfo; 1239 1240 return tzinfo; 1241} 1242 1243/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must 1244 * be an instance of the tzinfo class. If the method returns None, this 1245 * returns None. If the method doesn't return None or timedelta, TypeError is 1246 * raised and this returns NULL. If it returns a timedelta and the value is 1247 * out of range or isn't a whole number of minutes, ValueError is raised and 1248 * this returns NULL. Else result is returned. 1249 */ 1250static PyObject * 1251call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg) 1252{ 1253 PyObject *offset; 1254 1255 assert(tzinfo != NULL); 1256 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None); 1257 assert(tzinfoarg != NULL); 1258 1259 if (tzinfo == Py_None) 1260 Py_RETURN_NONE; 1261 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg); 1262 if (offset == Py_None || offset == NULL) 1263 return offset; 1264 if (PyDelta_Check(offset)) { 1265 if ((GET_TD_DAYS(offset) == -1 && 1266 GET_TD_SECONDS(offset) == 0 && 1267 GET_TD_MICROSECONDS(offset) < 1) || 1268 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { 1269 Py_DECREF(offset); 1270 PyErr_Format(PyExc_ValueError, "offset must be a timedelta" 1271 " strictly between -timedelta(hours=24) and" 1272 " timedelta(hours=24)."); 1273 return NULL; 1274 } 1275 } 1276 else { 1277 PyErr_Format(PyExc_TypeError, 1278 "tzinfo.%s() must return None or " 1279 "timedelta, not '%.200s'", 1280 name, Py_TYPE(offset)->tp_name); 1281 Py_DECREF(offset); 1282 return NULL; 1283 } 1284 1285 return offset; 1286} 1287 1288/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the 1289 * result. tzinfo must be an instance of the tzinfo class. If utcoffset() 1290 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset() 1291 * doesn't return None or timedelta, TypeError is raised and this returns -1. 1292 * If utcoffset() returns an out of range timedelta, 1293 * ValueError is raised and this returns -1. Else *none is 1294 * set to 0 and the offset is returned (as timedelta, positive east of UTC). 1295 */ 1296static PyObject * 1297call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg) 1298{ 1299 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg); 1300} 1301 1302/* Call tzinfo.dst(tzinfoarg), and extract an integer from the 1303 * result. tzinfo must be an instance of the tzinfo class. If dst() 1304 * returns None, call_dst returns 0 and sets *none to 1. If dst() 1305 * doesn't return None or timedelta, TypeError is raised and this 1306 * returns -1. If dst() returns an invalid timedelta for a UTC offset, 1307 * ValueError is raised and this returns -1. Else *none is set to 0 and 1308 * the offset is returned (as timedelta, positive east of UTC). 1309 */ 1310static PyObject * 1311call_dst(PyObject *tzinfo, PyObject *tzinfoarg) 1312{ 1313 return call_tzinfo_method(tzinfo, "dst", tzinfoarg); 1314} 1315 1316/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be 1317 * an instance of the tzinfo class or None. If tzinfo isn't None, and 1318 * tzname() doesn't return None or a string, TypeError is raised and this 1319 * returns NULL. If the result is a string, we ensure it is a Unicode 1320 * string. 1321 */ 1322static PyObject * 1323call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) 1324{ 1325 PyObject *result; 1326 _Py_IDENTIFIER(tzname); 1327 1328 assert(tzinfo != NULL); 1329 assert(check_tzinfo_subclass(tzinfo) >= 0); 1330 assert(tzinfoarg != NULL); 1331 1332 if (tzinfo == Py_None) 1333 Py_RETURN_NONE; 1334 1335 result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg); 1336 1337 if (result == NULL || result == Py_None) 1338 return result; 1339 1340 if (!PyUnicode_Check(result)) { 1341 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must " 1342 "return None or a string, not '%s'", 1343 Py_TYPE(result)->tp_name); 1344 Py_DECREF(result); 1345 result = NULL; 1346 } 1347 1348 return result; 1349} 1350 1351/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None, 1352 * stuff 1353 * ", tzinfo=" + repr(tzinfo) 1354 * before the closing ")". 1355 */ 1356static PyObject * 1357append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo) 1358{ 1359 PyObject *temp; 1360 1361 assert(PyUnicode_Check(repr)); 1362 assert(tzinfo); 1363 if (tzinfo == Py_None) 1364 return repr; 1365 /* Get rid of the trailing ')'. */ 1366 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')'); 1367 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1); 1368 Py_DECREF(repr); 1369 if (temp == NULL) 1370 return NULL; 1371 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo); 1372 Py_DECREF(temp); 1373 return repr; 1374} 1375 1376/* repr is like "someclass(arg1, arg2)". If fold isn't 0, 1377 * stuff 1378 * ", fold=" + repr(tzinfo) 1379 * before the closing ")". 1380 */ 1381static PyObject * 1382append_keyword_fold(PyObject *repr, int fold) 1383{ 1384 PyObject *temp; 1385 1386 assert(PyUnicode_Check(repr)); 1387 if (fold == 0) 1388 return repr; 1389 /* Get rid of the trailing ')'. */ 1390 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')'); 1391 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1); 1392 Py_DECREF(repr); 1393 if (temp == NULL) 1394 return NULL; 1395 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold); 1396 Py_DECREF(temp); 1397 return repr; 1398} 1399 1400static inline PyObject * 1401tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) 1402{ 1403 PyObject *tzinfo; 1404 if (rv == 1) { 1405 // Create a timezone from offset in seconds (0 returns UTC) 1406 if (tzoffset == 0) { 1407 Py_INCREF(PyDateTime_TimeZone_UTC); 1408 return PyDateTime_TimeZone_UTC; 1409 } 1410 1411 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1); 1412 if (delta == NULL) { 1413 return NULL; 1414 } 1415 tzinfo = new_timezone(delta, NULL); 1416 Py_DECREF(delta); 1417 } 1418 else { 1419 tzinfo = Py_None; 1420 Py_INCREF(Py_None); 1421 } 1422 1423 return tzinfo; 1424} 1425 1426/* --------------------------------------------------------------------------- 1427 * String format helpers. 1428 */ 1429 1430static PyObject * 1431format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds) 1432{ 1433 static const char * const DayNames[] = { 1434 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" 1435 }; 1436 static const char * const MonthNames[] = { 1437 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 1438 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 1439 }; 1440 1441 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date)); 1442 1443 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d", 1444 DayNames[wday], MonthNames[GET_MONTH(date)-1], 1445 GET_DAY(date), hours, minutes, seconds, 1446 GET_YEAR(date)); 1447} 1448 1449static PyObject *delta_negative(PyDateTime_Delta *self); 1450 1451/* Add formatted UTC offset string to buf. buf has no more than 1452 * buflen bytes remaining. The UTC offset is gotten by calling 1453 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into 1454 * *buf, and that's all. Else the returned value is checked for sanity (an 1455 * integer in range), and if that's OK it's converted to an hours & minutes 1456 * string of the form 1457 * sign HH sep MM [sep SS [. UUUUUU]] 1458 * Returns 0 if everything is OK. If the return value from utcoffset() is 1459 * bogus, an appropriate exception is set and -1 is returned. 1460 */ 1461static int 1462format_utcoffset(char *buf, size_t buflen, const char *sep, 1463 PyObject *tzinfo, PyObject *tzinfoarg) 1464{ 1465 PyObject *offset; 1466 int hours, minutes, seconds, microseconds; 1467 char sign; 1468 1469 assert(buflen >= 1); 1470 1471 offset = call_utcoffset(tzinfo, tzinfoarg); 1472 if (offset == NULL) 1473 return -1; 1474 if (offset == Py_None) { 1475 Py_DECREF(offset); 1476 *buf = '\0'; 1477 return 0; 1478 } 1479 /* Offset is normalized, so it is negative if days < 0 */ 1480 if (GET_TD_DAYS(offset) < 0) { 1481 sign = '-'; 1482 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset)); 1483 if (offset == NULL) 1484 return -1; 1485 } 1486 else { 1487 sign = '+'; 1488 } 1489 /* Offset is not negative here. */ 1490 microseconds = GET_TD_MICROSECONDS(offset); 1491 seconds = GET_TD_SECONDS(offset); 1492 Py_DECREF(offset); 1493 minutes = divmod(seconds, 60, &seconds); 1494 hours = divmod(minutes, 60, &minutes); 1495 if (microseconds) { 1496 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign, 1497 hours, sep, minutes, sep, seconds, microseconds); 1498 return 0; 1499 } 1500 if (seconds) { 1501 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours, 1502 sep, minutes, sep, seconds); 1503 return 0; 1504 } 1505 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes); 1506 return 0; 1507} 1508 1509static PyObject * 1510make_Zreplacement(PyObject *object, PyObject *tzinfoarg) 1511{ 1512 PyObject *temp; 1513 PyObject *tzinfo = get_tzinfo_member(object); 1514 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0); 1515 _Py_IDENTIFIER(replace); 1516 1517 if (Zreplacement == NULL) 1518 return NULL; 1519 if (tzinfo == Py_None || tzinfo == NULL) 1520 return Zreplacement; 1521 1522 assert(tzinfoarg != NULL); 1523 temp = call_tzname(tzinfo, tzinfoarg); 1524 if (temp == NULL) 1525 goto Error; 1526 if (temp == Py_None) { 1527 Py_DECREF(temp); 1528 return Zreplacement; 1529 } 1530 1531 assert(PyUnicode_Check(temp)); 1532 /* Since the tzname is getting stuffed into the 1533 * format, we have to double any % signs so that 1534 * strftime doesn't treat them as format codes. 1535 */ 1536 Py_DECREF(Zreplacement); 1537 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%"); 1538 Py_DECREF(temp); 1539 if (Zreplacement == NULL) 1540 return NULL; 1541 if (!PyUnicode_Check(Zreplacement)) { 1542 PyErr_SetString(PyExc_TypeError, 1543 "tzname.replace() did not return a string"); 1544 goto Error; 1545 } 1546 return Zreplacement; 1547 1548 Error: 1549 Py_DECREF(Zreplacement); 1550 return NULL; 1551} 1552 1553static PyObject * 1554make_freplacement(PyObject *object) 1555{ 1556 char freplacement[64]; 1557 if (PyTime_Check(object)) 1558 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object)); 1559 else if (PyDateTime_Check(object)) 1560 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object)); 1561 else 1562 sprintf(freplacement, "%06d", 0); 1563 1564 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement)); 1565} 1566 1567/* I sure don't want to reproduce the strftime code from the time module, 1568 * so this imports the module and calls it. All the hair is due to 1569 * giving special meanings to the %z, %Z and %f format codes via a 1570 * preprocessing step on the format string. 1571 * tzinfoarg is the argument to pass to the object's tzinfo method, if 1572 * needed. 1573 */ 1574static PyObject * 1575wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, 1576 PyObject *tzinfoarg) 1577{ 1578 PyObject *result = NULL; /* guilty until proved innocent */ 1579 1580 PyObject *zreplacement = NULL; /* py string, replacement for %z */ 1581 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */ 1582 PyObject *freplacement = NULL; /* py string, replacement for %f */ 1583 1584 const char *pin; /* pointer to next char in input format */ 1585 Py_ssize_t flen; /* length of input format */ 1586 char ch; /* next char in input format */ 1587 1588 PyObject *newfmt = NULL; /* py string, the output format */ 1589 char *pnew; /* pointer to available byte in output format */ 1590 size_t totalnew; /* number bytes total in output format buffer, 1591 exclusive of trailing \0 */ 1592 size_t usednew; /* number bytes used so far in output format buffer */ 1593 1594 const char *ptoappend; /* ptr to string to append to output buffer */ 1595 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */ 1596 1597 assert(object && format && timetuple); 1598 assert(PyUnicode_Check(format)); 1599 /* Convert the input format to a C string and size */ 1600 pin = PyUnicode_AsUTF8AndSize(format, &flen); 1601 if (!pin) 1602 return NULL; 1603 1604 /* Scan the input format, looking for %z/%Z/%f escapes, building 1605 * a new format. Since computing the replacements for those codes 1606 * is expensive, don't unless they're actually used. 1607 */ 1608 if (flen > INT_MAX - 1) { 1609 PyErr_NoMemory(); 1610 goto Done; 1611 } 1612 1613 totalnew = flen + 1; /* realistic if no %z/%Z */ 1614 newfmt = PyBytes_FromStringAndSize(NULL, totalnew); 1615 if (newfmt == NULL) goto Done; 1616 pnew = PyBytes_AsString(newfmt); 1617 usednew = 0; 1618 1619 while ((ch = *pin++) != '\0') { 1620 if (ch != '%') { 1621 ptoappend = pin - 1; 1622 ntoappend = 1; 1623 } 1624 else if ((ch = *pin++) == '\0') { 1625 /* Null byte follows %, copy only '%'. 1626 * 1627 * Back the pin up one char so that we catch the null check 1628 * the next time through the loop.*/ 1629 pin--; 1630 ptoappend = pin - 1; 1631 ntoappend = 1; 1632 } 1633 /* A % has been seen and ch is the character after it. */ 1634 else if (ch == 'z') { 1635 if (zreplacement == NULL) { 1636 /* format utcoffset */ 1637 char buf[100]; 1638 PyObject *tzinfo = get_tzinfo_member(object); 1639 zreplacement = PyBytes_FromStringAndSize("", 0); 1640 if (zreplacement == NULL) goto Done; 1641 if (tzinfo != Py_None && tzinfo != NULL) { 1642 assert(tzinfoarg != NULL); 1643 if (format_utcoffset(buf, 1644 sizeof(buf), 1645 "", 1646 tzinfo, 1647 tzinfoarg) < 0) 1648 goto Done; 1649 Py_DECREF(zreplacement); 1650 zreplacement = 1651 PyBytes_FromStringAndSize(buf, 1652 strlen(buf)); 1653 if (zreplacement == NULL) 1654 goto Done; 1655 } 1656 } 1657 assert(zreplacement != NULL); 1658 ptoappend = PyBytes_AS_STRING(zreplacement); 1659 ntoappend = PyBytes_GET_SIZE(zreplacement); 1660 } 1661 else if (ch == 'Z') { 1662 /* format tzname */ 1663 if (Zreplacement == NULL) { 1664 Zreplacement = make_Zreplacement(object, 1665 tzinfoarg); 1666 if (Zreplacement == NULL) 1667 goto Done; 1668 } 1669 assert(Zreplacement != NULL); 1670 assert(PyUnicode_Check(Zreplacement)); 1671 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement, 1672 &ntoappend); 1673 if (ptoappend == NULL) 1674 goto Done; 1675 } 1676 else if (ch == 'f') { 1677 /* format microseconds */ 1678 if (freplacement == NULL) { 1679 freplacement = make_freplacement(object); 1680 if (freplacement == NULL) 1681 goto Done; 1682 } 1683 assert(freplacement != NULL); 1684 assert(PyBytes_Check(freplacement)); 1685 ptoappend = PyBytes_AS_STRING(freplacement); 1686 ntoappend = PyBytes_GET_SIZE(freplacement); 1687 } 1688 else { 1689 /* percent followed by neither z nor Z */ 1690 ptoappend = pin - 2; 1691 ntoappend = 2; 1692 } 1693 1694 /* Append the ntoappend chars starting at ptoappend to 1695 * the new format. 1696 */ 1697 if (ntoappend == 0) 1698 continue; 1699 assert(ptoappend != NULL); 1700 assert(ntoappend > 0); 1701 while (usednew + ntoappend > totalnew) { 1702 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */ 1703 PyErr_NoMemory(); 1704 goto Done; 1705 } 1706 totalnew <<= 1; 1707 if (_PyBytes_Resize(&newfmt, totalnew) < 0) 1708 goto Done; 1709 pnew = PyBytes_AsString(newfmt) + usednew; 1710 } 1711 memcpy(pnew, ptoappend, ntoappend); 1712 pnew += ntoappend; 1713 usednew += ntoappend; 1714 assert(usednew <= totalnew); 1715 } /* end while() */ 1716 1717 if (_PyBytes_Resize(&newfmt, usednew) < 0) 1718 goto Done; 1719 { 1720 PyObject *format; 1721 PyObject *time = PyImport_ImportModule("time"); 1722 1723 if (time == NULL) 1724 goto Done; 1725 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt)); 1726 if (format != NULL) { 1727 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime, 1728 format, timetuple, NULL); 1729 Py_DECREF(format); 1730 } 1731 Py_DECREF(time); 1732 } 1733 Done: 1734 Py_XDECREF(freplacement); 1735 Py_XDECREF(zreplacement); 1736 Py_XDECREF(Zreplacement); 1737 Py_XDECREF(newfmt); 1738 return result; 1739} 1740 1741/* --------------------------------------------------------------------------- 1742 * Wrap functions from the time module. These aren't directly available 1743 * from C. Perhaps they should be. 1744 */ 1745 1746/* Call time.time() and return its result (a Python float). */ 1747static PyObject * 1748time_time(void) 1749{ 1750 PyObject *result = NULL; 1751 PyObject *time = PyImport_ImportModule("time"); 1752 1753 if (time != NULL) { 1754 _Py_IDENTIFIER(time); 1755 1756 result = _PyObject_CallMethodIdNoArgs(time, &PyId_time); 1757 Py_DECREF(time); 1758 } 1759 return result; 1760} 1761 1762/* Build a time.struct_time. The weekday and day number are automatically 1763 * computed from the y,m,d args. 1764 */ 1765static PyObject * 1766build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) 1767{ 1768 PyObject *time; 1769 PyObject *result; 1770 _Py_IDENTIFIER(struct_time); 1771 PyObject *args; 1772 1773 1774 time = PyImport_ImportModule("time"); 1775 if (time == NULL) { 1776 return NULL; 1777 } 1778 1779 args = Py_BuildValue("iiiiiiiii", 1780 y, m, d, 1781 hh, mm, ss, 1782 weekday(y, m, d), 1783 days_before_month(y, m) + d, 1784 dstflag); 1785 if (args == NULL) { 1786 Py_DECREF(time); 1787 return NULL; 1788 } 1789 1790 result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args); 1791 Py_DECREF(time); 1792 Py_DECREF(args); 1793 return result; 1794} 1795 1796/* --------------------------------------------------------------------------- 1797 * Miscellaneous helpers. 1798 */ 1799 1800/* The comparisons here all most naturally compute a cmp()-like result. 1801 * This little helper turns that into a bool result for rich comparisons. 1802 */ 1803static PyObject * 1804diff_to_bool(int diff, int op) 1805{ 1806 Py_RETURN_RICHCOMPARE(diff, 0, op); 1807} 1808 1809/* Raises a "can't compare" TypeError and returns NULL. */ 1810static PyObject * 1811cmperror(PyObject *a, PyObject *b) 1812{ 1813 PyErr_Format(PyExc_TypeError, 1814 "can't compare %s to %s", 1815 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); 1816 return NULL; 1817} 1818 1819/* --------------------------------------------------------------------------- 1820 * Cached Python objects; these are set by the module init function. 1821 */ 1822 1823/* Conversion factors. */ 1824static PyObject *us_per_ms = NULL; /* 1000 */ 1825static PyObject *us_per_second = NULL; /* 1000000 */ 1826static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */ 1827static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */ 1828static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */ 1829static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */ 1830static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */ 1831 1832/* --------------------------------------------------------------------------- 1833 * Class implementations. 1834 */ 1835 1836/* 1837 * PyDateTime_Delta implementation. 1838 */ 1839 1840/* Convert a timedelta to a number of us, 1841 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds 1842 * as a Python int. 1843 * Doing mixed-radix arithmetic by hand instead is excruciating in C, 1844 * due to ubiquitous overflow possibilities. 1845 */ 1846static PyObject * 1847delta_to_microseconds(PyDateTime_Delta *self) 1848{ 1849 PyObject *x1 = NULL; 1850 PyObject *x2 = NULL; 1851 PyObject *x3 = NULL; 1852 PyObject *result = NULL; 1853 1854 x1 = PyLong_FromLong(GET_TD_DAYS(self)); 1855 if (x1 == NULL) 1856 goto Done; 1857 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */ 1858 if (x2 == NULL) 1859 goto Done; 1860 Py_DECREF(x1); 1861 x1 = NULL; 1862 1863 /* x2 has days in seconds */ 1864 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */ 1865 if (x1 == NULL) 1866 goto Done; 1867 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */ 1868 if (x3 == NULL) 1869 goto Done; 1870 Py_DECREF(x1); 1871 Py_DECREF(x2); 1872 /* x1 = */ x2 = NULL; 1873 1874 /* x3 has days+seconds in seconds */ 1875 x1 = PyNumber_Multiply(x3, us_per_second); /* us */ 1876 if (x1 == NULL) 1877 goto Done; 1878 Py_DECREF(x3); 1879 x3 = NULL; 1880 1881 /* x1 has days+seconds in us */ 1882 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self)); 1883 if (x2 == NULL) 1884 goto Done; 1885 result = PyNumber_Add(x1, x2); 1886 assert(result == NULL || PyLong_CheckExact(result)); 1887 1888Done: 1889 Py_XDECREF(x1); 1890 Py_XDECREF(x2); 1891 Py_XDECREF(x3); 1892 return result; 1893} 1894 1895static PyObject * 1896checked_divmod(PyObject *a, PyObject *b) 1897{ 1898 PyObject *result = PyNumber_Divmod(a, b); 1899 if (result != NULL) { 1900 if (!PyTuple_Check(result)) { 1901 PyErr_Format(PyExc_TypeError, 1902 "divmod() returned non-tuple (type %.200s)", 1903 Py_TYPE(result)->tp_name); 1904 Py_DECREF(result); 1905 return NULL; 1906 } 1907 if (PyTuple_GET_SIZE(result) != 2) { 1908 PyErr_Format(PyExc_TypeError, 1909 "divmod() returned a tuple of size %zd", 1910 PyTuple_GET_SIZE(result)); 1911 Py_DECREF(result); 1912 return NULL; 1913 } 1914 } 1915 return result; 1916} 1917 1918/* Convert a number of us (as a Python int) to a timedelta. 1919 */ 1920static PyObject * 1921microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) 1922{ 1923 int us; 1924 int s; 1925 int d; 1926 1927 PyObject *tuple = NULL; 1928 PyObject *num = NULL; 1929 PyObject *result = NULL; 1930 1931 tuple = checked_divmod(pyus, us_per_second); 1932 if (tuple == NULL) { 1933 goto Done; 1934 } 1935 1936 num = PyTuple_GET_ITEM(tuple, 1); /* us */ 1937 us = _PyLong_AsInt(num); 1938 num = NULL; 1939 if (us == -1 && PyErr_Occurred()) { 1940 goto Done; 1941 } 1942 if (!(0 <= us && us < 1000000)) { 1943 goto BadDivmod; 1944 } 1945 1946 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */ 1947 Py_INCREF(num); 1948 Py_DECREF(tuple); 1949 1950 tuple = checked_divmod(num, seconds_per_day); 1951 if (tuple == NULL) 1952 goto Done; 1953 Py_DECREF(num); 1954 1955 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */ 1956 s = _PyLong_AsInt(num); 1957 num = NULL; 1958 if (s == -1 && PyErr_Occurred()) { 1959 goto Done; 1960 } 1961 if (!(0 <= s && s < 24*3600)) { 1962 goto BadDivmod; 1963 } 1964 1965 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */ 1966 Py_INCREF(num); 1967 d = _PyLong_AsInt(num); 1968 if (d == -1 && PyErr_Occurred()) { 1969 goto Done; 1970 } 1971 result = new_delta_ex(d, s, us, 0, type); 1972 1973Done: 1974 Py_XDECREF(tuple); 1975 Py_XDECREF(num); 1976 return result; 1977 1978BadDivmod: 1979 PyErr_SetString(PyExc_TypeError, 1980 "divmod() returned a value out of range"); 1981 goto Done; 1982} 1983 1984#define microseconds_to_delta(pymicros) \ 1985 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType) 1986 1987static PyObject * 1988multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta) 1989{ 1990 PyObject *pyus_in; 1991 PyObject *pyus_out; 1992 PyObject *result; 1993 1994 pyus_in = delta_to_microseconds(delta); 1995 if (pyus_in == NULL) 1996 return NULL; 1997 1998 pyus_out = PyNumber_Multiply(intobj, pyus_in); 1999 Py_DECREF(pyus_in); 2000 if (pyus_out == NULL) 2001 return NULL; 2002 2003 result = microseconds_to_delta(pyus_out); 2004 Py_DECREF(pyus_out); 2005 return result; 2006} 2007 2008static PyObject * 2009get_float_as_integer_ratio(PyObject *floatobj) 2010{ 2011 PyObject *ratio; 2012 2013 assert(floatobj && PyFloat_Check(floatobj)); 2014 ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio); 2015 if (ratio == NULL) { 2016 return NULL; 2017 } 2018 if (!PyTuple_Check(ratio)) { 2019 PyErr_Format(PyExc_TypeError, 2020 "unexpected return type from as_integer_ratio(): " 2021 "expected tuple, got '%.200s'", 2022 Py_TYPE(ratio)->tp_name); 2023 Py_DECREF(ratio); 2024 return NULL; 2025 } 2026 if (PyTuple_Size(ratio) != 2) { 2027 PyErr_SetString(PyExc_ValueError, 2028 "as_integer_ratio() must return a 2-tuple"); 2029 Py_DECREF(ratio); 2030 return NULL; 2031 } 2032 return ratio; 2033} 2034 2035/* op is 0 for multiplication, 1 for division */ 2036static PyObject * 2037multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op) 2038{ 2039 PyObject *result = NULL; 2040 PyObject *pyus_in = NULL, *temp, *pyus_out; 2041 PyObject *ratio = NULL; 2042 2043 pyus_in = delta_to_microseconds(delta); 2044 if (pyus_in == NULL) 2045 return NULL; 2046 ratio = get_float_as_integer_ratio(floatobj); 2047 if (ratio == NULL) { 2048 goto error; 2049 } 2050 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op)); 2051 Py_DECREF(pyus_in); 2052 pyus_in = NULL; 2053 if (temp == NULL) 2054 goto error; 2055 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op)); 2056 Py_DECREF(temp); 2057 if (pyus_out == NULL) 2058 goto error; 2059 result = microseconds_to_delta(pyus_out); 2060 Py_DECREF(pyus_out); 2061 error: 2062 Py_XDECREF(pyus_in); 2063 Py_XDECREF(ratio); 2064 2065 return result; 2066} 2067 2068static PyObject * 2069divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj) 2070{ 2071 PyObject *pyus_in; 2072 PyObject *pyus_out; 2073 PyObject *result; 2074 2075 pyus_in = delta_to_microseconds(delta); 2076 if (pyus_in == NULL) 2077 return NULL; 2078 2079 pyus_out = PyNumber_FloorDivide(pyus_in, intobj); 2080 Py_DECREF(pyus_in); 2081 if (pyus_out == NULL) 2082 return NULL; 2083 2084 result = microseconds_to_delta(pyus_out); 2085 Py_DECREF(pyus_out); 2086 return result; 2087} 2088 2089static PyObject * 2090divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) 2091{ 2092 PyObject *pyus_left; 2093 PyObject *pyus_right; 2094 PyObject *result; 2095 2096 pyus_left = delta_to_microseconds(left); 2097 if (pyus_left == NULL) 2098 return NULL; 2099 2100 pyus_right = delta_to_microseconds(right); 2101 if (pyus_right == NULL) { 2102 Py_DECREF(pyus_left); 2103 return NULL; 2104 } 2105 2106 result = PyNumber_FloorDivide(pyus_left, pyus_right); 2107 Py_DECREF(pyus_left); 2108 Py_DECREF(pyus_right); 2109 return result; 2110} 2111 2112static PyObject * 2113truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) 2114{ 2115 PyObject *pyus_left; 2116 PyObject *pyus_right; 2117 PyObject *result; 2118 2119 pyus_left = delta_to_microseconds(left); 2120 if (pyus_left == NULL) 2121 return NULL; 2122 2123 pyus_right = delta_to_microseconds(right); 2124 if (pyus_right == NULL) { 2125 Py_DECREF(pyus_left); 2126 return NULL; 2127 } 2128 2129 result = PyNumber_TrueDivide(pyus_left, pyus_right); 2130 Py_DECREF(pyus_left); 2131 Py_DECREF(pyus_right); 2132 return result; 2133} 2134 2135static PyObject * 2136truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i) 2137{ 2138 PyObject *result; 2139 PyObject *pyus_in, *pyus_out; 2140 pyus_in = delta_to_microseconds(delta); 2141 if (pyus_in == NULL) 2142 return NULL; 2143 pyus_out = divide_nearest(pyus_in, i); 2144 Py_DECREF(pyus_in); 2145 if (pyus_out == NULL) 2146 return NULL; 2147 result = microseconds_to_delta(pyus_out); 2148 Py_DECREF(pyus_out); 2149 2150 return result; 2151} 2152 2153static PyObject * 2154delta_add(PyObject *left, PyObject *right) 2155{ 2156 PyObject *result = Py_NotImplemented; 2157 2158 if (PyDelta_Check(left) && PyDelta_Check(right)) { 2159 /* delta + delta */ 2160 /* The C-level additions can't overflow because of the 2161 * invariant bounds. 2162 */ 2163 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right); 2164 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right); 2165 int microseconds = GET_TD_MICROSECONDS(left) + 2166 GET_TD_MICROSECONDS(right); 2167 result = new_delta(days, seconds, microseconds, 1); 2168 } 2169 2170 if (result == Py_NotImplemented) 2171 Py_INCREF(result); 2172 return result; 2173} 2174 2175static PyObject * 2176delta_negative(PyDateTime_Delta *self) 2177{ 2178 return new_delta(-GET_TD_DAYS(self), 2179 -GET_TD_SECONDS(self), 2180 -GET_TD_MICROSECONDS(self), 2181 1); 2182} 2183 2184static PyObject * 2185delta_positive(PyDateTime_Delta *self) 2186{ 2187 /* Could optimize this (by returning self) if this isn't a 2188 * subclass -- but who uses unary + ? Approximately nobody. 2189 */ 2190 return new_delta(GET_TD_DAYS(self), 2191 GET_TD_SECONDS(self), 2192 GET_TD_MICROSECONDS(self), 2193 0); 2194} 2195 2196static PyObject * 2197delta_abs(PyDateTime_Delta *self) 2198{ 2199 PyObject *result; 2200 2201 assert(GET_TD_MICROSECONDS(self) >= 0); 2202 assert(GET_TD_SECONDS(self) >= 0); 2203 2204 if (GET_TD_DAYS(self) < 0) 2205 result = delta_negative(self); 2206 else 2207 result = delta_positive(self); 2208 2209 return result; 2210} 2211 2212static PyObject * 2213delta_subtract(PyObject *left, PyObject *right) 2214{ 2215 PyObject *result = Py_NotImplemented; 2216 2217 if (PyDelta_Check(left) && PyDelta_Check(right)) { 2218 /* delta - delta */ 2219 /* The C-level additions can't overflow because of the 2220 * invariant bounds. 2221 */ 2222 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right); 2223 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right); 2224 int microseconds = GET_TD_MICROSECONDS(left) - 2225 GET_TD_MICROSECONDS(right); 2226 result = new_delta(days, seconds, microseconds, 1); 2227 } 2228 2229 if (result == Py_NotImplemented) 2230 Py_INCREF(result); 2231 return result; 2232} 2233 2234static int 2235delta_cmp(PyObject *self, PyObject *other) 2236{ 2237 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other); 2238 if (diff == 0) { 2239 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other); 2240 if (diff == 0) 2241 diff = GET_TD_MICROSECONDS(self) - 2242 GET_TD_MICROSECONDS(other); 2243 } 2244 return diff; 2245} 2246 2247static PyObject * 2248delta_richcompare(PyObject *self, PyObject *other, int op) 2249{ 2250 if (PyDelta_Check(other)) { 2251 int diff = delta_cmp(self, other); 2252 return diff_to_bool(diff, op); 2253 } 2254 else { 2255 Py_RETURN_NOTIMPLEMENTED; 2256 } 2257} 2258 2259static PyObject *delta_getstate(PyDateTime_Delta *self); 2260 2261static Py_hash_t 2262delta_hash(PyDateTime_Delta *self) 2263{ 2264 if (self->hashcode == -1) { 2265 PyObject *temp = delta_getstate(self); 2266 if (temp != NULL) { 2267 self->hashcode = PyObject_Hash(temp); 2268 Py_DECREF(temp); 2269 } 2270 } 2271 return self->hashcode; 2272} 2273 2274static PyObject * 2275delta_multiply(PyObject *left, PyObject *right) 2276{ 2277 PyObject *result = Py_NotImplemented; 2278 2279 if (PyDelta_Check(left)) { 2280 /* delta * ??? */ 2281 if (PyLong_Check(right)) 2282 result = multiply_int_timedelta(right, 2283 (PyDateTime_Delta *) left); 2284 else if (PyFloat_Check(right)) 2285 result = multiply_truedivide_timedelta_float( 2286 (PyDateTime_Delta *) left, right, 0); 2287 } 2288 else if (PyLong_Check(left)) 2289 result = multiply_int_timedelta(left, 2290 (PyDateTime_Delta *) right); 2291 else if (PyFloat_Check(left)) 2292 result = multiply_truedivide_timedelta_float( 2293 (PyDateTime_Delta *) right, left, 0); 2294 2295 if (result == Py_NotImplemented) 2296 Py_INCREF(result); 2297 return result; 2298} 2299 2300static PyObject * 2301delta_divide(PyObject *left, PyObject *right) 2302{ 2303 PyObject *result = Py_NotImplemented; 2304 2305 if (PyDelta_Check(left)) { 2306 /* delta * ??? */ 2307 if (PyLong_Check(right)) 2308 result = divide_timedelta_int( 2309 (PyDateTime_Delta *)left, 2310 right); 2311 else if (PyDelta_Check(right)) 2312 result = divide_timedelta_timedelta( 2313 (PyDateTime_Delta *)left, 2314 (PyDateTime_Delta *)right); 2315 } 2316 2317 if (result == Py_NotImplemented) 2318 Py_INCREF(result); 2319 return result; 2320} 2321 2322static PyObject * 2323delta_truedivide(PyObject *left, PyObject *right) 2324{ 2325 PyObject *result = Py_NotImplemented; 2326 2327 if (PyDelta_Check(left)) { 2328 if (PyDelta_Check(right)) 2329 result = truedivide_timedelta_timedelta( 2330 (PyDateTime_Delta *)left, 2331 (PyDateTime_Delta *)right); 2332 else if (PyFloat_Check(right)) 2333 result = multiply_truedivide_timedelta_float( 2334 (PyDateTime_Delta *)left, right, 1); 2335 else if (PyLong_Check(right)) 2336 result = truedivide_timedelta_int( 2337 (PyDateTime_Delta *)left, right); 2338 } 2339 2340 if (result == Py_NotImplemented) 2341 Py_INCREF(result); 2342 return result; 2343} 2344 2345static PyObject * 2346delta_remainder(PyObject *left, PyObject *right) 2347{ 2348 PyObject *pyus_left; 2349 PyObject *pyus_right; 2350 PyObject *pyus_remainder; 2351 PyObject *remainder; 2352 2353 if (!PyDelta_Check(left) || !PyDelta_Check(right)) 2354 Py_RETURN_NOTIMPLEMENTED; 2355 2356 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left); 2357 if (pyus_left == NULL) 2358 return NULL; 2359 2360 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right); 2361 if (pyus_right == NULL) { 2362 Py_DECREF(pyus_left); 2363 return NULL; 2364 } 2365 2366 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right); 2367 Py_DECREF(pyus_left); 2368 Py_DECREF(pyus_right); 2369 if (pyus_remainder == NULL) 2370 return NULL; 2371 2372 remainder = microseconds_to_delta(pyus_remainder); 2373 Py_DECREF(pyus_remainder); 2374 if (remainder == NULL) 2375 return NULL; 2376 2377 return remainder; 2378} 2379 2380static PyObject * 2381delta_divmod(PyObject *left, PyObject *right) 2382{ 2383 PyObject *pyus_left; 2384 PyObject *pyus_right; 2385 PyObject *divmod; 2386 PyObject *delta; 2387 PyObject *result; 2388 2389 if (!PyDelta_Check(left) || !PyDelta_Check(right)) 2390 Py_RETURN_NOTIMPLEMENTED; 2391 2392 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left); 2393 if (pyus_left == NULL) 2394 return NULL; 2395 2396 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right); 2397 if (pyus_right == NULL) { 2398 Py_DECREF(pyus_left); 2399 return NULL; 2400 } 2401 2402 divmod = checked_divmod(pyus_left, pyus_right); 2403 Py_DECREF(pyus_left); 2404 Py_DECREF(pyus_right); 2405 if (divmod == NULL) 2406 return NULL; 2407 2408 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1)); 2409 if (delta == NULL) { 2410 Py_DECREF(divmod); 2411 return NULL; 2412 } 2413 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta); 2414 Py_DECREF(delta); 2415 Py_DECREF(divmod); 2416 return result; 2417} 2418 2419/* Fold in the value of the tag ("seconds", "weeks", etc) component of a 2420 * timedelta constructor. sofar is the # of microseconds accounted for 2421 * so far, and there are factor microseconds per current unit, the number 2422 * of which is given by num. num * factor is added to sofar in a 2423 * numerically careful way, and that's the result. Any fractional 2424 * microseconds left over (this can happen if num is a float type) are 2425 * added into *leftover. 2426 * Note that there are many ways this can give an error (NULL) return. 2427 */ 2428static PyObject * 2429accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor, 2430 double *leftover) 2431{ 2432 PyObject *prod; 2433 PyObject *sum; 2434 2435 assert(num != NULL); 2436 2437 if (PyLong_Check(num)) { 2438 prod = PyNumber_Multiply(num, factor); 2439 if (prod == NULL) 2440 return NULL; 2441 sum = PyNumber_Add(sofar, prod); 2442 Py_DECREF(prod); 2443 return sum; 2444 } 2445 2446 if (PyFloat_Check(num)) { 2447 double dnum; 2448 double fracpart; 2449 double intpart; 2450 PyObject *x; 2451 PyObject *y; 2452 2453 /* The Plan: decompose num into an integer part and a 2454 * fractional part, num = intpart + fracpart. 2455 * Then num * factor == 2456 * intpart * factor + fracpart * factor 2457 * and the LHS can be computed exactly in long arithmetic. 2458 * The RHS is again broken into an int part and frac part. 2459 * and the frac part is added into *leftover. 2460 */ 2461 dnum = PyFloat_AsDouble(num); 2462 if (dnum == -1.0 && PyErr_Occurred()) 2463 return NULL; 2464 fracpart = modf(dnum, &intpart); 2465 x = PyLong_FromDouble(intpart); 2466 if (x == NULL) 2467 return NULL; 2468 2469 prod = PyNumber_Multiply(x, factor); 2470 Py_DECREF(x); 2471 if (prod == NULL) 2472 return NULL; 2473 2474 sum = PyNumber_Add(sofar, prod); 2475 Py_DECREF(prod); 2476 if (sum == NULL) 2477 return NULL; 2478 2479 if (fracpart == 0.0) 2480 return sum; 2481 /* So far we've lost no information. Dealing with the 2482 * fractional part requires float arithmetic, and may 2483 * lose a little info. 2484 */ 2485 assert(PyLong_CheckExact(factor)); 2486 dnum = PyLong_AsDouble(factor); 2487 2488 dnum *= fracpart; 2489 fracpart = modf(dnum, &intpart); 2490 x = PyLong_FromDouble(intpart); 2491 if (x == NULL) { 2492 Py_DECREF(sum); 2493 return NULL; 2494 } 2495 2496 y = PyNumber_Add(sum, x); 2497 Py_DECREF(sum); 2498 Py_DECREF(x); 2499 *leftover += fracpart; 2500 return y; 2501 } 2502 2503 PyErr_Format(PyExc_TypeError, 2504 "unsupported type for timedelta %s component: %s", 2505 tag, Py_TYPE(num)->tp_name); 2506 return NULL; 2507} 2508 2509static PyObject * 2510delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) 2511{ 2512 PyObject *self = NULL; 2513 2514 /* Argument objects. */ 2515 PyObject *day = NULL; 2516 PyObject *second = NULL; 2517 PyObject *us = NULL; 2518 PyObject *ms = NULL; 2519 PyObject *minute = NULL; 2520 PyObject *hour = NULL; 2521 PyObject *week = NULL; 2522 2523 PyObject *x = NULL; /* running sum of microseconds */ 2524 PyObject *y = NULL; /* temp sum of microseconds */ 2525 double leftover_us = 0.0; 2526 2527 static char *keywords[] = { 2528 "days", "seconds", "microseconds", "milliseconds", 2529 "minutes", "hours", "weeks", NULL 2530 }; 2531 2532 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__", 2533 keywords, 2534 &day, &second, &us, 2535 &ms, &minute, &hour, &week) == 0) 2536 goto Done; 2537 2538 x = PyLong_FromLong(0); 2539 if (x == NULL) 2540 goto Done; 2541 2542#define CLEANUP \ 2543 Py_DECREF(x); \ 2544 x = y; \ 2545 if (x == NULL) \ 2546 goto Done 2547 2548 if (us) { 2549 y = accum("microseconds", x, us, _PyLong_GetOne(), &leftover_us); 2550 CLEANUP; 2551 } 2552 if (ms) { 2553 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us); 2554 CLEANUP; 2555 } 2556 if (second) { 2557 y = accum("seconds", x, second, us_per_second, &leftover_us); 2558 CLEANUP; 2559 } 2560 if (minute) { 2561 y = accum("minutes", x, minute, us_per_minute, &leftover_us); 2562 CLEANUP; 2563 } 2564 if (hour) { 2565 y = accum("hours", x, hour, us_per_hour, &leftover_us); 2566 CLEANUP; 2567 } 2568 if (day) { 2569 y = accum("days", x, day, us_per_day, &leftover_us); 2570 CLEANUP; 2571 } 2572 if (week) { 2573 y = accum("weeks", x, week, us_per_week, &leftover_us); 2574 CLEANUP; 2575 } 2576 if (leftover_us) { 2577 /* Round to nearest whole # of us, and add into x. */ 2578 double whole_us = round(leftover_us); 2579 int x_is_odd; 2580 PyObject *temp; 2581 2582 if (fabs(whole_us - leftover_us) == 0.5) { 2583 /* We're exactly halfway between two integers. In order 2584 * to do round-half-to-even, we must determine whether x 2585 * is odd. Note that x is odd when it's last bit is 1. The 2586 * code below uses bitwise and operation to check the last 2587 * bit. */ 2588 temp = PyNumber_And(x, _PyLong_GetOne()); /* temp <- x & 1 */ 2589 if (temp == NULL) { 2590 Py_DECREF(x); 2591 goto Done; 2592 } 2593 x_is_odd = PyObject_IsTrue(temp); 2594 Py_DECREF(temp); 2595 if (x_is_odd == -1) { 2596 Py_DECREF(x); 2597 goto Done; 2598 } 2599 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd; 2600 } 2601 2602 temp = PyLong_FromLong((long)whole_us); 2603 2604 if (temp == NULL) { 2605 Py_DECREF(x); 2606 goto Done; 2607 } 2608 y = PyNumber_Add(x, temp); 2609 Py_DECREF(temp); 2610 CLEANUP; 2611 } 2612 2613 self = microseconds_to_delta_ex(x, type); 2614 Py_DECREF(x); 2615Done: 2616 return self; 2617 2618#undef CLEANUP 2619} 2620 2621static int 2622delta_bool(PyDateTime_Delta *self) 2623{ 2624 return (GET_TD_DAYS(self) != 0 2625 || GET_TD_SECONDS(self) != 0 2626 || GET_TD_MICROSECONDS(self) != 0); 2627} 2628 2629static PyObject * 2630delta_repr(PyDateTime_Delta *self) 2631{ 2632 PyObject *args = PyUnicode_FromString(""); 2633 2634 if (args == NULL) { 2635 return NULL; 2636 } 2637 2638 const char *sep = ""; 2639 2640 if (GET_TD_DAYS(self) != 0) { 2641 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self))); 2642 if (args == NULL) { 2643 return NULL; 2644 } 2645 sep = ", "; 2646 } 2647 2648 if (GET_TD_SECONDS(self) != 0) { 2649 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep, 2650 GET_TD_SECONDS(self))); 2651 if (args == NULL) { 2652 return NULL; 2653 } 2654 sep = ", "; 2655 } 2656 2657 if (GET_TD_MICROSECONDS(self) != 0) { 2658 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep, 2659 GET_TD_MICROSECONDS(self))); 2660 if (args == NULL) { 2661 return NULL; 2662 } 2663 } 2664 2665 if (PyUnicode_GET_LENGTH(args) == 0) { 2666 Py_SETREF(args, PyUnicode_FromString("0")); 2667 if (args == NULL) { 2668 return NULL; 2669 } 2670 } 2671 2672 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name, 2673 args); 2674 Py_DECREF(args); 2675 return repr; 2676} 2677 2678static PyObject * 2679delta_str(PyDateTime_Delta *self) 2680{ 2681 int us = GET_TD_MICROSECONDS(self); 2682 int seconds = GET_TD_SECONDS(self); 2683 int minutes = divmod(seconds, 60, &seconds); 2684 int hours = divmod(minutes, 60, &minutes); 2685 int days = GET_TD_DAYS(self); 2686 2687 if (days) { 2688 if (us) 2689 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d", 2690 days, (days == 1 || days == -1) ? "" : "s", 2691 hours, minutes, seconds, us); 2692 else 2693 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d", 2694 days, (days == 1 || days == -1) ? "" : "s", 2695 hours, minutes, seconds); 2696 } else { 2697 if (us) 2698 return PyUnicode_FromFormat("%d:%02d:%02d.%06d", 2699 hours, minutes, seconds, us); 2700 else 2701 return PyUnicode_FromFormat("%d:%02d:%02d", 2702 hours, minutes, seconds); 2703 } 2704 2705} 2706 2707/* Pickle support, a simple use of __reduce__. */ 2708 2709/* __getstate__ isn't exposed */ 2710static PyObject * 2711delta_getstate(PyDateTime_Delta *self) 2712{ 2713 return Py_BuildValue("iii", GET_TD_DAYS(self), 2714 GET_TD_SECONDS(self), 2715 GET_TD_MICROSECONDS(self)); 2716} 2717 2718static PyObject * 2719delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored)) 2720{ 2721 PyObject *total_seconds; 2722 PyObject *total_microseconds; 2723 2724 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self); 2725 if (total_microseconds == NULL) 2726 return NULL; 2727 2728 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second); 2729 2730 Py_DECREF(total_microseconds); 2731 return total_seconds; 2732} 2733 2734static PyObject * 2735delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored)) 2736{ 2737 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self)); 2738} 2739 2740#define OFFSET(field) offsetof(PyDateTime_Delta, field) 2741 2742static PyMemberDef delta_members[] = { 2743 2744 {"days", T_INT, OFFSET(days), READONLY, 2745 PyDoc_STR("Number of days.")}, 2746 2747 {"seconds", T_INT, OFFSET(seconds), READONLY, 2748 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")}, 2749 2750 {"microseconds", T_INT, OFFSET(microseconds), READONLY, 2751 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")}, 2752 {NULL} 2753}; 2754 2755static PyMethodDef delta_methods[] = { 2756 {"total_seconds", delta_total_seconds, METH_NOARGS, 2757 PyDoc_STR("Total seconds in the duration.")}, 2758 2759 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, 2760 PyDoc_STR("__reduce__() -> (cls, state)")}, 2761 2762 {NULL, NULL}, 2763}; 2764 2765static const char delta_doc[] = 2766PyDoc_STR("Difference between two datetime values.\n\n" 2767 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, " 2768 "minutes=0, hours=0, weeks=0)\n\n" 2769 "All arguments are optional and default to 0.\n" 2770 "Arguments may be integers or floats, and may be positive or negative."); 2771 2772static PyNumberMethods delta_as_number = { 2773 delta_add, /* nb_add */ 2774 delta_subtract, /* nb_subtract */ 2775 delta_multiply, /* nb_multiply */ 2776 delta_remainder, /* nb_remainder */ 2777 delta_divmod, /* nb_divmod */ 2778 0, /* nb_power */ 2779 (unaryfunc)delta_negative, /* nb_negative */ 2780 (unaryfunc)delta_positive, /* nb_positive */ 2781 (unaryfunc)delta_abs, /* nb_absolute */ 2782 (inquiry)delta_bool, /* nb_bool */ 2783 0, /*nb_invert*/ 2784 0, /*nb_lshift*/ 2785 0, /*nb_rshift*/ 2786 0, /*nb_and*/ 2787 0, /*nb_xor*/ 2788 0, /*nb_or*/ 2789 0, /*nb_int*/ 2790 0, /*nb_reserved*/ 2791 0, /*nb_float*/ 2792 0, /*nb_inplace_add*/ 2793 0, /*nb_inplace_subtract*/ 2794 0, /*nb_inplace_multiply*/ 2795 0, /*nb_inplace_remainder*/ 2796 0, /*nb_inplace_power*/ 2797 0, /*nb_inplace_lshift*/ 2798 0, /*nb_inplace_rshift*/ 2799 0, /*nb_inplace_and*/ 2800 0, /*nb_inplace_xor*/ 2801 0, /*nb_inplace_or*/ 2802 delta_divide, /* nb_floor_divide */ 2803 delta_truedivide, /* nb_true_divide */ 2804 0, /* nb_inplace_floor_divide */ 2805 0, /* nb_inplace_true_divide */ 2806}; 2807 2808static PyTypeObject PyDateTime_DeltaType = { 2809 PyVarObject_HEAD_INIT(NULL, 0) 2810 "datetime.timedelta", /* tp_name */ 2811 sizeof(PyDateTime_Delta), /* tp_basicsize */ 2812 0, /* tp_itemsize */ 2813 0, /* tp_dealloc */ 2814 0, /* tp_vectorcall_offset */ 2815 0, /* tp_getattr */ 2816 0, /* tp_setattr */ 2817 0, /* tp_as_async */ 2818 (reprfunc)delta_repr, /* tp_repr */ 2819 &delta_as_number, /* tp_as_number */ 2820 0, /* tp_as_sequence */ 2821 0, /* tp_as_mapping */ 2822 (hashfunc)delta_hash, /* tp_hash */ 2823 0, /* tp_call */ 2824 (reprfunc)delta_str, /* tp_str */ 2825 PyObject_GenericGetAttr, /* tp_getattro */ 2826 0, /* tp_setattro */ 2827 0, /* tp_as_buffer */ 2828 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 2829 delta_doc, /* tp_doc */ 2830 0, /* tp_traverse */ 2831 0, /* tp_clear */ 2832 delta_richcompare, /* tp_richcompare */ 2833 0, /* tp_weaklistoffset */ 2834 0, /* tp_iter */ 2835 0, /* tp_iternext */ 2836 delta_methods, /* tp_methods */ 2837 delta_members, /* tp_members */ 2838 0, /* tp_getset */ 2839 0, /* tp_base */ 2840 0, /* tp_dict */ 2841 0, /* tp_descr_get */ 2842 0, /* tp_descr_set */ 2843 0, /* tp_dictoffset */ 2844 0, /* tp_init */ 2845 0, /* tp_alloc */ 2846 delta_new, /* tp_new */ 2847 0, /* tp_free */ 2848}; 2849 2850/* 2851 * PyDateTime_Date implementation. 2852 */ 2853 2854/* Accessor properties. */ 2855 2856static PyObject * 2857date_year(PyDateTime_Date *self, void *unused) 2858{ 2859 return PyLong_FromLong(GET_YEAR(self)); 2860} 2861 2862static PyObject * 2863date_month(PyDateTime_Date *self, void *unused) 2864{ 2865 return PyLong_FromLong(GET_MONTH(self)); 2866} 2867 2868static PyObject * 2869date_day(PyDateTime_Date *self, void *unused) 2870{ 2871 return PyLong_FromLong(GET_DAY(self)); 2872} 2873 2874static PyGetSetDef date_getset[] = { 2875 {"year", (getter)date_year}, 2876 {"month", (getter)date_month}, 2877 {"day", (getter)date_day}, 2878 {NULL} 2879}; 2880 2881/* Constructors. */ 2882 2883static char *date_kws[] = {"year", "month", "day", NULL}; 2884 2885static PyObject * 2886date_from_pickle(PyTypeObject *type, PyObject *state) 2887{ 2888 PyDateTime_Date *me; 2889 2890 me = (PyDateTime_Date *) (type->tp_alloc(type, 0)); 2891 if (me != NULL) { 2892 const char *pdata = PyBytes_AS_STRING(state); 2893 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE); 2894 me->hashcode = -1; 2895 } 2896 return (PyObject *)me; 2897} 2898 2899static PyObject * 2900date_new(PyTypeObject *type, PyObject *args, PyObject *kw) 2901{ 2902 PyObject *self = NULL; 2903 int year; 2904 int month; 2905 int day; 2906 2907 /* Check for invocation from pickle with __getstate__ state */ 2908 if (PyTuple_GET_SIZE(args) == 1) { 2909 PyObject *state = PyTuple_GET_ITEM(args, 0); 2910 if (PyBytes_Check(state)) { 2911 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE && 2912 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2])) 2913 { 2914 return date_from_pickle(type, state); 2915 } 2916 } 2917 else if (PyUnicode_Check(state)) { 2918 if (PyUnicode_READY(state)) { 2919 return NULL; 2920 } 2921 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE && 2922 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2))) 2923 { 2924 state = PyUnicode_AsLatin1String(state); 2925 if (state == NULL) { 2926 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { 2927 /* More informative error message. */ 2928 PyErr_SetString(PyExc_ValueError, 2929 "Failed to encode latin1 string when unpickling " 2930 "a date object. " 2931 "pickle.load(data, encoding='latin1') is assumed."); 2932 } 2933 return NULL; 2934 } 2935 self = date_from_pickle(type, state); 2936 Py_DECREF(state); 2937 return self; 2938 } 2939 } 2940 } 2941 2942 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws, 2943 &year, &month, &day)) { 2944 self = new_date_ex(year, month, day, type); 2945 } 2946 return self; 2947} 2948 2949static PyObject * 2950date_fromtimestamp(PyObject *cls, PyObject *obj) 2951{ 2952 struct tm tm; 2953 time_t t; 2954 2955 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1) 2956 return NULL; 2957 2958 if (_PyTime_localtime(t, &tm) != 0) 2959 return NULL; 2960 2961 return new_date_subclass_ex(tm.tm_year + 1900, 2962 tm.tm_mon + 1, 2963 tm.tm_mday, 2964 cls); 2965} 2966 2967/* Return new date from current time. 2968 * We say this is equivalent to fromtimestamp(time.time()), and the 2969 * only way to be sure of that is to *call* time.time(). That's not 2970 * generally the same as calling C's time. 2971 */ 2972static PyObject * 2973date_today(PyObject *cls, PyObject *dummy) 2974{ 2975 PyObject *time; 2976 PyObject *result; 2977 _Py_IDENTIFIER(fromtimestamp); 2978 2979 time = time_time(); 2980 if (time == NULL) 2981 return NULL; 2982 2983 /* Note well: today() is a class method, so this may not call 2984 * date.fromtimestamp. For example, it may call 2985 * datetime.fromtimestamp. That's why we need all the accuracy 2986 * time.time() delivers; if someone were gonzo about optimization, 2987 * date.today() could get away with plain C time(). 2988 */ 2989 result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time); 2990 Py_DECREF(time); 2991 return result; 2992} 2993 2994/*[clinic input] 2995@classmethod 2996datetime.date.fromtimestamp 2997 2998 timestamp: object 2999 / 3000 3001Create a date from a POSIX timestamp. 3002 3003The timestamp is a number, e.g. created via time.time(), that is interpreted 3004as local time. 3005[clinic start generated code]*/ 3006 3007static PyObject * 3008datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp) 3009/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/ 3010{ 3011 return date_fromtimestamp((PyObject *) type, timestamp); 3012} 3013 3014/* bpo-36025: This is a wrapper for API compatibility with the public C API, 3015 * which expects a function that takes an *args tuple, whereas the argument 3016 * clinic generates code that takes METH_O. 3017 */ 3018static PyObject * 3019datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args) 3020{ 3021 PyObject *timestamp; 3022 PyObject *result = NULL; 3023 3024 if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, ×tamp)) { 3025 result = date_fromtimestamp(cls, timestamp); 3026 } 3027 3028 return result; 3029} 3030 3031/* Return new date from proleptic Gregorian ordinal. Raises ValueError if 3032 * the ordinal is out of range. 3033 */ 3034static PyObject * 3035date_fromordinal(PyObject *cls, PyObject *args) 3036{ 3037 PyObject *result = NULL; 3038 int ordinal; 3039 3040 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) { 3041 int year; 3042 int month; 3043 int day; 3044 3045 if (ordinal < 1) 3046 PyErr_SetString(PyExc_ValueError, "ordinal must be " 3047 ">= 1"); 3048 else { 3049 ord_to_ymd(ordinal, &year, &month, &day); 3050 result = new_date_subclass_ex(year, month, day, cls); 3051 } 3052 } 3053 return result; 3054} 3055 3056/* Return the new date from a string as generated by date.isoformat() */ 3057static PyObject * 3058date_fromisoformat(PyObject *cls, PyObject *dtstr) 3059{ 3060 assert(dtstr != NULL); 3061 3062 if (!PyUnicode_Check(dtstr)) { 3063 PyErr_SetString(PyExc_TypeError, 3064 "fromisoformat: argument must be str"); 3065 return NULL; 3066 } 3067 3068 Py_ssize_t len; 3069 3070 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len); 3071 if (dt_ptr == NULL) { 3072 goto invalid_string_error; 3073 } 3074 3075 int year = 0, month = 0, day = 0; 3076 3077 int rv; 3078 if (len == 7 || len == 8 || len == 10) { 3079 rv = parse_isoformat_date(dt_ptr, len, &year, &month, &day); 3080 } 3081 else { 3082 rv = -1; 3083 } 3084 3085 if (rv < 0) { 3086 goto invalid_string_error; 3087 } 3088 3089 return new_date_subclass_ex(year, month, day, cls); 3090 3091invalid_string_error: 3092 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr); 3093 return NULL; 3094} 3095 3096 3097static PyObject * 3098date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw) 3099{ 3100 static char *keywords[] = { 3101 "year", "week", "day", NULL 3102 }; 3103 3104 int year, week, day; 3105 if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar", 3106 keywords, 3107 &year, &week, &day) == 0) { 3108 if (PyErr_ExceptionMatches(PyExc_OverflowError)) { 3109 PyErr_Format(PyExc_ValueError, 3110 "ISO calendar component out of range"); 3111 3112 } 3113 return NULL; 3114 } 3115 3116 // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5) 3117 if (year < MINYEAR || year > MAXYEAR) { 3118 PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year); 3119 return NULL; 3120 } 3121 3122 int month; 3123 int rv = iso_to_ymd(year, week, day, &year, &month, &day); 3124 3125 3126 if (rv == -2) { 3127 PyErr_Format(PyExc_ValueError, "Invalid week: %d", week); 3128 return NULL; 3129 } 3130 3131 if (rv == -3) { 3132 PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])", 3133 day); 3134 return NULL; 3135 } 3136 3137 return new_date_subclass_ex(year, month, day, cls); 3138} 3139 3140 3141/* 3142 * Date arithmetic. 3143 */ 3144 3145/* date + timedelta -> date. If arg negate is true, subtract the timedelta 3146 * instead. 3147 */ 3148static PyObject * 3149add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate) 3150{ 3151 PyObject *result = NULL; 3152 int year = GET_YEAR(date); 3153 int month = GET_MONTH(date); 3154 int deltadays = GET_TD_DAYS(delta); 3155 /* C-level overflow is impossible because |deltadays| < 1e9. */ 3156 int day = GET_DAY(date) + (negate ? -deltadays : deltadays); 3157 3158 if (normalize_date(&year, &month, &day) >= 0) 3159 result = new_date_subclass_ex(year, month, day, 3160 (PyObject* )Py_TYPE(date)); 3161 return result; 3162} 3163 3164static PyObject * 3165date_add(PyObject *left, PyObject *right) 3166{ 3167 if (PyDateTime_Check(left) || PyDateTime_Check(right)) 3168 Py_RETURN_NOTIMPLEMENTED; 3169 3170 if (PyDate_Check(left)) { 3171 /* date + ??? */ 3172 if (PyDelta_Check(right)) 3173 /* date + delta */ 3174 return add_date_timedelta((PyDateTime_Date *) left, 3175 (PyDateTime_Delta *) right, 3176 0); 3177 } 3178 else { 3179 /* ??? + date 3180 * 'right' must be one of us, or we wouldn't have been called 3181 */ 3182 if (PyDelta_Check(left)) 3183 /* delta + date */ 3184 return add_date_timedelta((PyDateTime_Date *) right, 3185 (PyDateTime_Delta *) left, 3186 0); 3187 } 3188 Py_RETURN_NOTIMPLEMENTED; 3189} 3190 3191static PyObject * 3192date_subtract(PyObject *left, PyObject *right) 3193{ 3194 if (PyDateTime_Check(left) || PyDateTime_Check(right)) 3195 Py_RETURN_NOTIMPLEMENTED; 3196 3197 if (PyDate_Check(left)) { 3198 if (PyDate_Check(right)) { 3199 /* date - date */ 3200 int left_ord = ymd_to_ord(GET_YEAR(left), 3201 GET_MONTH(left), 3202 GET_DAY(left)); 3203 int right_ord = ymd_to_ord(GET_YEAR(right), 3204 GET_MONTH(right), 3205 GET_DAY(right)); 3206 return new_delta(left_ord - right_ord, 0, 0, 0); 3207 } 3208 if (PyDelta_Check(right)) { 3209 /* date - delta */ 3210 return add_date_timedelta((PyDateTime_Date *) left, 3211 (PyDateTime_Delta *) right, 3212 1); 3213 } 3214 } 3215 Py_RETURN_NOTIMPLEMENTED; 3216} 3217 3218 3219/* Various ways to turn a date into a string. */ 3220 3221static PyObject * 3222date_repr(PyDateTime_Date *self) 3223{ 3224 return PyUnicode_FromFormat("%s(%d, %d, %d)", 3225 Py_TYPE(self)->tp_name, 3226 GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); 3227} 3228 3229static PyObject * 3230date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) 3231{ 3232 return PyUnicode_FromFormat("%04d-%02d-%02d", 3233 GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); 3234} 3235 3236/* str() calls the appropriate isoformat() method. */ 3237static PyObject * 3238date_str(PyDateTime_Date *self) 3239{ 3240 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); 3241} 3242 3243 3244static PyObject * 3245date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) 3246{ 3247 return format_ctime(self, 0, 0, 0); 3248} 3249 3250static PyObject * 3251date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) 3252{ 3253 /* This method can be inherited, and needs to call the 3254 * timetuple() method appropriate to self's class. 3255 */ 3256 PyObject *result; 3257 PyObject *tuple; 3258 PyObject *format; 3259 _Py_IDENTIFIER(timetuple); 3260 static char *keywords[] = {"format", NULL}; 3261 3262 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords, 3263 &format)) 3264 return NULL; 3265 3266 tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple); 3267 if (tuple == NULL) 3268 return NULL; 3269 result = wrap_strftime((PyObject *)self, format, tuple, 3270 (PyObject *)self); 3271 Py_DECREF(tuple); 3272 return result; 3273} 3274 3275static PyObject * 3276date_format(PyDateTime_Date *self, PyObject *args) 3277{ 3278 PyObject *format; 3279 3280 if (!PyArg_ParseTuple(args, "U:__format__", &format)) 3281 return NULL; 3282 3283 /* if the format is zero length, return str(self) */ 3284 if (PyUnicode_GetLength(format) == 0) 3285 return PyObject_Str((PyObject *)self); 3286 3287 return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime, 3288 format); 3289} 3290 3291/* ISO methods. */ 3292 3293static PyObject * 3294date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) 3295{ 3296 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); 3297 3298 return PyLong_FromLong(dow + 1); 3299} 3300 3301PyDoc_STRVAR(iso_calendar_date__doc__, 3302"The result of date.isocalendar() or datetime.isocalendar()\n\n\ 3303This object may be accessed either as a tuple of\n\ 3304 ((year, week, weekday)\n\ 3305or via the object attributes as named in the above tuple."); 3306 3307typedef struct { 3308 PyTupleObject tuple; 3309} PyDateTime_IsoCalendarDate; 3310 3311static PyObject * 3312iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self) 3313{ 3314 PyObject* year = PyTuple_GetItem((PyObject *)self, 0); 3315 if (year == NULL) { 3316 return NULL; 3317 } 3318 PyObject* week = PyTuple_GetItem((PyObject *)self, 1); 3319 if (week == NULL) { 3320 return NULL; 3321 } 3322 PyObject* weekday = PyTuple_GetItem((PyObject *)self, 2); 3323 if (weekday == NULL) { 3324 return NULL; 3325 } 3326 3327 return PyUnicode_FromFormat("%.200s(year=%S, week=%S, weekday=%S)", 3328 Py_TYPE(self)->tp_name, year, week, weekday); 3329} 3330 3331static PyObject * 3332iso_calendar_date_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) 3333{ 3334 // Construct the tuple that this reduces to 3335 PyObject * reduce_tuple = Py_BuildValue( 3336 "O((OOO))", &PyTuple_Type, 3337 PyTuple_GET_ITEM(self, 0), 3338 PyTuple_GET_ITEM(self, 1), 3339 PyTuple_GET_ITEM(self, 2) 3340 ); 3341 3342 return reduce_tuple; 3343} 3344 3345static PyObject * 3346iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused) 3347{ 3348 PyObject *year = PyTuple_GetItem((PyObject *)self, 0); 3349 if (year == NULL) { 3350 return NULL; 3351 } 3352 Py_INCREF(year); 3353 return year; 3354} 3355 3356static PyObject * 3357iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused) 3358{ 3359 PyObject *week = PyTuple_GetItem((PyObject *)self, 1); 3360 if (week == NULL) { 3361 return NULL; 3362 } 3363 Py_INCREF(week); 3364 return week; 3365} 3366 3367static PyObject * 3368iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused) 3369{ 3370 PyObject *weekday = PyTuple_GetItem((PyObject *)self, 2); 3371 if (weekday == NULL) { 3372 return NULL; 3373 } 3374 Py_INCREF(weekday); 3375 return weekday; 3376} 3377 3378static PyGetSetDef iso_calendar_date_getset[] = { 3379 {"year", (getter)iso_calendar_date_year}, 3380 {"week", (getter)iso_calendar_date_week}, 3381 {"weekday", (getter)iso_calendar_date_weekday}, 3382 {NULL} 3383}; 3384 3385static PyMethodDef iso_calendar_date_methods[] = { 3386 {"__reduce__", (PyCFunction)iso_calendar_date_reduce, METH_NOARGS, 3387 PyDoc_STR("__reduce__() -> (cls, state)")}, 3388 {NULL, NULL}, 3389}; 3390 3391static PyTypeObject PyDateTime_IsoCalendarDateType = { 3392 PyVarObject_HEAD_INIT(NULL, 0) 3393 .tp_name = "datetime.IsoCalendarDate", 3394 .tp_basicsize = sizeof(PyDateTime_IsoCalendarDate), 3395 .tp_repr = (reprfunc) iso_calendar_date_repr, 3396 .tp_flags = Py_TPFLAGS_DEFAULT, 3397 .tp_doc = iso_calendar_date__doc__, 3398 .tp_methods = iso_calendar_date_methods, 3399 .tp_getset = iso_calendar_date_getset, 3400 // .tp_base = &PyTuple_Type, // filled in PyInit__datetime 3401 .tp_new = iso_calendar_date_new, 3402}; 3403 3404/*[clinic input] 3405@classmethod 3406datetime.IsoCalendarDate.__new__ as iso_calendar_date_new 3407 year: int 3408 week: int 3409 weekday: int 3410[clinic start generated code]*/ 3411 3412static PyObject * 3413iso_calendar_date_new_impl(PyTypeObject *type, int year, int week, 3414 int weekday) 3415/*[clinic end generated code: output=383d33d8dc7183a2 input=4f2c663c9d19c4ee]*/ 3416 3417{ 3418 PyDateTime_IsoCalendarDate *self; 3419 self = (PyDateTime_IsoCalendarDate *) type->tp_alloc(type, 3); 3420 if (self == NULL) { 3421 return NULL; 3422 } 3423 3424 PyTuple_SET_ITEM(self, 0, PyLong_FromLong(year)); 3425 PyTuple_SET_ITEM(self, 1, PyLong_FromLong(week)); 3426 PyTuple_SET_ITEM(self, 2, PyLong_FromLong(weekday)); 3427 3428 return (PyObject *)self; 3429} 3430 3431static PyObject * 3432date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) 3433{ 3434 int year = GET_YEAR(self); 3435 int week1_monday = iso_week1_monday(year); 3436 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self)); 3437 int week; 3438 int day; 3439 3440 week = divmod(today - week1_monday, 7, &day); 3441 if (week < 0) { 3442 --year; 3443 week1_monday = iso_week1_monday(year); 3444 week = divmod(today - week1_monday, 7, &day); 3445 } 3446 else if (week >= 52 && today >= iso_week1_monday(year + 1)) { 3447 ++year; 3448 week = 0; 3449 } 3450 3451 PyObject* v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType, 3452 year, week + 1, day + 1); 3453 if (v == NULL) { 3454 return NULL; 3455 } 3456 return v; 3457} 3458 3459/* Miscellaneous methods. */ 3460 3461static PyObject * 3462date_richcompare(PyObject *self, PyObject *other, int op) 3463{ 3464 if (PyDate_Check(other)) { 3465 int diff = memcmp(((PyDateTime_Date *)self)->data, 3466 ((PyDateTime_Date *)other)->data, 3467 _PyDateTime_DATE_DATASIZE); 3468 return diff_to_bool(diff, op); 3469 } 3470 else 3471 Py_RETURN_NOTIMPLEMENTED; 3472} 3473 3474static PyObject * 3475date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) 3476{ 3477 return build_struct_time(GET_YEAR(self), 3478 GET_MONTH(self), 3479 GET_DAY(self), 3480 0, 0, 0, -1); 3481} 3482 3483static PyObject * 3484date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw) 3485{ 3486 PyObject *clone; 3487 PyObject *tuple; 3488 int year = GET_YEAR(self); 3489 int month = GET_MONTH(self); 3490 int day = GET_DAY(self); 3491 3492 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws, 3493 &year, &month, &day)) 3494 return NULL; 3495 tuple = Py_BuildValue("iii", year, month, day); 3496 if (tuple == NULL) 3497 return NULL; 3498 clone = date_new(Py_TYPE(self), tuple, NULL); 3499 Py_DECREF(tuple); 3500 return clone; 3501} 3502 3503static Py_hash_t 3504generic_hash(unsigned char *data, int len) 3505{ 3506 return _Py_HashBytes(data, len); 3507} 3508 3509 3510static PyObject *date_getstate(PyDateTime_Date *self); 3511 3512static Py_hash_t 3513date_hash(PyDateTime_Date *self) 3514{ 3515 if (self->hashcode == -1) { 3516 self->hashcode = generic_hash( 3517 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE); 3518 } 3519 3520 return self->hashcode; 3521} 3522 3523static PyObject * 3524date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) 3525{ 3526 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self), 3527 GET_DAY(self))); 3528} 3529 3530static PyObject * 3531date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) 3532{ 3533 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); 3534 3535 return PyLong_FromLong(dow); 3536} 3537 3538/* Pickle support, a simple use of __reduce__. */ 3539 3540/* __getstate__ isn't exposed */ 3541static PyObject * 3542date_getstate(PyDateTime_Date *self) 3543{ 3544 PyObject* field; 3545 field = PyBytes_FromStringAndSize((char*)self->data, 3546 _PyDateTime_DATE_DATASIZE); 3547 return Py_BuildValue("(N)", field); 3548} 3549 3550static PyObject * 3551date_reduce(PyDateTime_Date *self, PyObject *arg) 3552{ 3553 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self)); 3554} 3555 3556static PyMethodDef date_methods[] = { 3557 3558 /* Class methods: */ 3559 DATETIME_DATE_FROMTIMESTAMP_METHODDEF 3560 3561 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS | 3562 METH_CLASS, 3563 PyDoc_STR("int -> date corresponding to a proleptic Gregorian " 3564 "ordinal.")}, 3565 3566 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O | 3567 METH_CLASS, 3568 PyDoc_STR("str -> Construct a date from a string in ISO 8601 format.")}, 3569 3570 {"fromisocalendar", _PyCFunction_CAST(date_fromisocalendar), 3571 METH_VARARGS | METH_KEYWORDS | METH_CLASS, 3572 PyDoc_STR("int, int, int -> Construct a date from the ISO year, week " 3573 "number and weekday.\n\n" 3574 "This is the inverse of the date.isocalendar() function")}, 3575 3576 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS, 3577 PyDoc_STR("Current date or datetime: same as " 3578 "self.__class__.fromtimestamp(time.time()).")}, 3579 3580 /* Instance methods: */ 3581 3582 {"ctime", (PyCFunction)date_ctime, METH_NOARGS, 3583 PyDoc_STR("Return ctime() style string.")}, 3584 3585 {"strftime", _PyCFunction_CAST(date_strftime), METH_VARARGS | METH_KEYWORDS, 3586 PyDoc_STR("format -> strftime() style string.")}, 3587 3588 {"__format__", (PyCFunction)date_format, METH_VARARGS, 3589 PyDoc_STR("Formats self with strftime.")}, 3590 3591 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS, 3592 PyDoc_STR("Return time tuple, compatible with time.localtime().")}, 3593 3594 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS, 3595 PyDoc_STR("Return a named tuple containing ISO year, week number, and " 3596 "weekday.")}, 3597 3598 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS, 3599 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")}, 3600 3601 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS, 3602 PyDoc_STR("Return the day of the week represented by the date.\n" 3603 "Monday == 1 ... Sunday == 7")}, 3604 3605 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS, 3606 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year " 3607 "1 is day 1.")}, 3608 3609 {"weekday", (PyCFunction)date_weekday, METH_NOARGS, 3610 PyDoc_STR("Return the day of the week represented by the date.\n" 3611 "Monday == 0 ... Sunday == 6")}, 3612 3613 {"replace", _PyCFunction_CAST(date_replace), METH_VARARGS | METH_KEYWORDS, 3614 PyDoc_STR("Return date with new specified fields.")}, 3615 3616 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS, 3617 PyDoc_STR("__reduce__() -> (cls, state)")}, 3618 3619 {NULL, NULL} 3620}; 3621 3622static const char date_doc[] = 3623PyDoc_STR("date(year, month, day) --> date object"); 3624 3625static PyNumberMethods date_as_number = { 3626 date_add, /* nb_add */ 3627 date_subtract, /* nb_subtract */ 3628 0, /* nb_multiply */ 3629 0, /* nb_remainder */ 3630 0, /* nb_divmod */ 3631 0, /* nb_power */ 3632 0, /* nb_negative */ 3633 0, /* nb_positive */ 3634 0, /* nb_absolute */ 3635 0, /* nb_bool */ 3636}; 3637 3638static PyTypeObject PyDateTime_DateType = { 3639 PyVarObject_HEAD_INIT(NULL, 0) 3640 "datetime.date", /* tp_name */ 3641 sizeof(PyDateTime_Date), /* tp_basicsize */ 3642 0, /* tp_itemsize */ 3643 0, /* tp_dealloc */ 3644 0, /* tp_vectorcall_offset */ 3645 0, /* tp_getattr */ 3646 0, /* tp_setattr */ 3647 0, /* tp_as_async */ 3648 (reprfunc)date_repr, /* tp_repr */ 3649 &date_as_number, /* tp_as_number */ 3650 0, /* tp_as_sequence */ 3651 0, /* tp_as_mapping */ 3652 (hashfunc)date_hash, /* tp_hash */ 3653 0, /* tp_call */ 3654 (reprfunc)date_str, /* tp_str */ 3655 PyObject_GenericGetAttr, /* tp_getattro */ 3656 0, /* tp_setattro */ 3657 0, /* tp_as_buffer */ 3658 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 3659 date_doc, /* tp_doc */ 3660 0, /* tp_traverse */ 3661 0, /* tp_clear */ 3662 date_richcompare, /* tp_richcompare */ 3663 0, /* tp_weaklistoffset */ 3664 0, /* tp_iter */ 3665 0, /* tp_iternext */ 3666 date_methods, /* tp_methods */ 3667 0, /* tp_members */ 3668 date_getset, /* tp_getset */ 3669 0, /* tp_base */ 3670 0, /* tp_dict */ 3671 0, /* tp_descr_get */ 3672 0, /* tp_descr_set */ 3673 0, /* tp_dictoffset */ 3674 0, /* tp_init */ 3675 0, /* tp_alloc */ 3676 date_new, /* tp_new */ 3677 0, /* tp_free */ 3678}; 3679 3680/* 3681 * PyDateTime_TZInfo implementation. 3682 */ 3683 3684/* This is a pure abstract base class, so doesn't do anything beyond 3685 * raising NotImplemented exceptions. Real tzinfo classes need 3686 * to derive from this. This is mostly for clarity, and for efficiency in 3687 * datetime and time constructors (their tzinfo arguments need to 3688 * be subclasses of this tzinfo class, which is easy and quick to check). 3689 * 3690 * Note: For reasons having to do with pickling of subclasses, we have 3691 * to allow tzinfo objects to be instantiated. This wasn't an issue 3692 * in the Python implementation (__init__() could raise NotImplementedError 3693 * there without ill effect), but doing so in the C implementation hit a 3694 * brick wall. 3695 */ 3696 3697static PyObject * 3698tzinfo_nogo(const char* methodname) 3699{ 3700 PyErr_Format(PyExc_NotImplementedError, 3701 "a tzinfo subclass must implement %s()", 3702 methodname); 3703 return NULL; 3704} 3705 3706/* Methods. A subclass must implement these. */ 3707 3708static PyObject * 3709tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt) 3710{ 3711 return tzinfo_nogo("tzname"); 3712} 3713 3714static PyObject * 3715tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt) 3716{ 3717 return tzinfo_nogo("utcoffset"); 3718} 3719 3720static PyObject * 3721tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt) 3722{ 3723 return tzinfo_nogo("dst"); 3724} 3725 3726 3727static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date, 3728 PyDateTime_Delta *delta, 3729 int factor); 3730static PyObject *datetime_utcoffset(PyObject *self, PyObject *); 3731static PyObject *datetime_dst(PyObject *self, PyObject *); 3732 3733static PyObject * 3734tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt) 3735{ 3736 PyObject *result = NULL; 3737 PyObject *off = NULL, *dst = NULL; 3738 PyDateTime_Delta *delta = NULL; 3739 3740 if (!PyDateTime_Check(dt)) { 3741 PyErr_SetString(PyExc_TypeError, 3742 "fromutc: argument must be a datetime"); 3743 return NULL; 3744 } 3745 if (GET_DT_TZINFO(dt) != (PyObject *)self) { 3746 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo " 3747 "is not self"); 3748 return NULL; 3749 } 3750 3751 off = datetime_utcoffset(dt, NULL); 3752 if (off == NULL) 3753 return NULL; 3754 if (off == Py_None) { 3755 PyErr_SetString(PyExc_ValueError, "fromutc: non-None " 3756 "utcoffset() result required"); 3757 goto Fail; 3758 } 3759 3760 dst = datetime_dst(dt, NULL); 3761 if (dst == NULL) 3762 goto Fail; 3763 if (dst == Py_None) { 3764 PyErr_SetString(PyExc_ValueError, "fromutc: non-None " 3765 "dst() result required"); 3766 goto Fail; 3767 } 3768 3769 delta = (PyDateTime_Delta *)delta_subtract(off, dst); 3770 if (delta == NULL) 3771 goto Fail; 3772 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1); 3773 if (result == NULL) 3774 goto Fail; 3775 3776 Py_DECREF(dst); 3777 dst = call_dst(GET_DT_TZINFO(dt), result); 3778 if (dst == NULL) 3779 goto Fail; 3780 if (dst == Py_None) 3781 goto Inconsistent; 3782 if (delta_bool((PyDateTime_Delta *)dst) != 0) { 3783 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result, 3784 (PyDateTime_Delta *)dst, 1)); 3785 if (result == NULL) 3786 goto Fail; 3787 } 3788 Py_DECREF(delta); 3789 Py_DECREF(dst); 3790 Py_DECREF(off); 3791 return result; 3792 3793Inconsistent: 3794 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave " 3795 "inconsistent results; cannot convert"); 3796 3797 /* fall through to failure */ 3798Fail: 3799 Py_XDECREF(off); 3800 Py_XDECREF(dst); 3801 Py_XDECREF(delta); 3802 Py_XDECREF(result); 3803 return NULL; 3804} 3805 3806/* 3807 * Pickle support. This is solely so that tzinfo subclasses can use 3808 * pickling -- tzinfo itself is supposed to be uninstantiable. 3809 */ 3810 3811static PyObject * 3812tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) 3813{ 3814 PyObject *args, *state; 3815 PyObject *getinitargs; 3816 _Py_IDENTIFIER(__getinitargs__); 3817 3818 if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) { 3819 return NULL; 3820 } 3821 if (getinitargs != NULL) { 3822 args = PyObject_CallNoArgs(getinitargs); 3823 Py_DECREF(getinitargs); 3824 } 3825 else { 3826 args = PyTuple_New(0); 3827 } 3828 if (args == NULL) { 3829 return NULL; 3830 } 3831 3832 state = _PyObject_GetState(self); 3833 if (state == NULL) { 3834 Py_DECREF(args); 3835 return NULL; 3836 } 3837 3838 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state); 3839} 3840 3841static PyMethodDef tzinfo_methods[] = { 3842 3843 {"tzname", (PyCFunction)tzinfo_tzname, METH_O, 3844 PyDoc_STR("datetime -> string name of time zone.")}, 3845 3846 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O, 3847 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative " 3848 "values indicating West of UTC")}, 3849 3850 {"dst", (PyCFunction)tzinfo_dst, METH_O, 3851 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")}, 3852 3853 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O, 3854 PyDoc_STR("datetime in UTC -> datetime in local time.")}, 3855 3856 {"__reduce__", tzinfo_reduce, METH_NOARGS, 3857 PyDoc_STR("-> (cls, state)")}, 3858 3859 {NULL, NULL} 3860}; 3861 3862static const char tzinfo_doc[] = 3863PyDoc_STR("Abstract base class for time zone info objects."); 3864 3865static PyTypeObject PyDateTime_TZInfoType = { 3866 PyVarObject_HEAD_INIT(NULL, 0) 3867 "datetime.tzinfo", /* tp_name */ 3868 sizeof(PyDateTime_TZInfo), /* tp_basicsize */ 3869 0, /* tp_itemsize */ 3870 0, /* tp_dealloc */ 3871 0, /* tp_vectorcall_offset */ 3872 0, /* tp_getattr */ 3873 0, /* tp_setattr */ 3874 0, /* tp_as_async */ 3875 0, /* tp_repr */ 3876 0, /* tp_as_number */ 3877 0, /* tp_as_sequence */ 3878 0, /* tp_as_mapping */ 3879 0, /* tp_hash */ 3880 0, /* tp_call */ 3881 0, /* tp_str */ 3882 PyObject_GenericGetAttr, /* tp_getattro */ 3883 0, /* tp_setattro */ 3884 0, /* tp_as_buffer */ 3885 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 3886 tzinfo_doc, /* tp_doc */ 3887 0, /* tp_traverse */ 3888 0, /* tp_clear */ 3889 0, /* tp_richcompare */ 3890 0, /* tp_weaklistoffset */ 3891 0, /* tp_iter */ 3892 0, /* tp_iternext */ 3893 tzinfo_methods, /* tp_methods */ 3894 0, /* tp_members */ 3895 0, /* tp_getset */ 3896 0, /* tp_base */ 3897 0, /* tp_dict */ 3898 0, /* tp_descr_get */ 3899 0, /* tp_descr_set */ 3900 0, /* tp_dictoffset */ 3901 0, /* tp_init */ 3902 0, /* tp_alloc */ 3903 PyType_GenericNew, /* tp_new */ 3904 0, /* tp_free */ 3905}; 3906 3907static char *timezone_kws[] = {"offset", "name", NULL}; 3908 3909static PyObject * 3910timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw) 3911{ 3912 PyObject *offset; 3913 PyObject *name = NULL; 3914 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws, 3915 &PyDateTime_DeltaType, &offset, &name)) 3916 return new_timezone(offset, name); 3917 3918 return NULL; 3919} 3920 3921static void 3922timezone_dealloc(PyDateTime_TimeZone *self) 3923{ 3924 Py_CLEAR(self->offset); 3925 Py_CLEAR(self->name); 3926 Py_TYPE(self)->tp_free((PyObject *)self); 3927} 3928 3929static PyObject * 3930timezone_richcompare(PyDateTime_TimeZone *self, 3931 PyDateTime_TimeZone *other, int op) 3932{ 3933 if (op != Py_EQ && op != Py_NE) 3934 Py_RETURN_NOTIMPLEMENTED; 3935 if (!PyTimezone_Check(other)) { 3936 Py_RETURN_NOTIMPLEMENTED; 3937 } 3938 return delta_richcompare(self->offset, other->offset, op); 3939} 3940 3941static Py_hash_t 3942timezone_hash(PyDateTime_TimeZone *self) 3943{ 3944 return delta_hash((PyDateTime_Delta *)self->offset); 3945} 3946 3947/* Check argument type passed to tzname, utcoffset, or dst methods. 3948 Returns 0 for good argument. Returns -1 and sets exception info 3949 otherwise. 3950 */ 3951static int 3952_timezone_check_argument(PyObject *dt, const char *meth) 3953{ 3954 if (dt == Py_None || PyDateTime_Check(dt)) 3955 return 0; 3956 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance" 3957 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name); 3958 return -1; 3959} 3960 3961static PyObject * 3962timezone_repr(PyDateTime_TimeZone *self) 3963{ 3964 /* Note that although timezone is not subclassable, it is convenient 3965 to use Py_TYPE(self)->tp_name here. */ 3966 const char *type_name = Py_TYPE(self)->tp_name; 3967 3968 if (((PyObject *)self) == PyDateTime_TimeZone_UTC) 3969 return PyUnicode_FromFormat("%s.utc", type_name); 3970 3971 if (self->name == NULL) 3972 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset); 3973 3974 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset, 3975 self->name); 3976} 3977 3978 3979static PyObject * 3980timezone_str(PyDateTime_TimeZone *self) 3981{ 3982 int hours, minutes, seconds, microseconds; 3983 PyObject *offset; 3984 char sign; 3985 3986 if (self->name != NULL) { 3987 Py_INCREF(self->name); 3988 return self->name; 3989 } 3990 if ((PyObject *)self == PyDateTime_TimeZone_UTC || 3991 (GET_TD_DAYS(self->offset) == 0 && 3992 GET_TD_SECONDS(self->offset) == 0 && 3993 GET_TD_MICROSECONDS(self->offset) == 0)) 3994 return PyUnicode_FromString("UTC"); 3995 /* Offset is normalized, so it is negative if days < 0 */ 3996 if (GET_TD_DAYS(self->offset) < 0) { 3997 sign = '-'; 3998 offset = delta_negative((PyDateTime_Delta *)self->offset); 3999 if (offset == NULL) 4000 return NULL; 4001 } 4002 else { 4003 sign = '+'; 4004 offset = self->offset; 4005 Py_INCREF(offset); 4006 } 4007 /* Offset is not negative here. */ 4008 microseconds = GET_TD_MICROSECONDS(offset); 4009 seconds = GET_TD_SECONDS(offset); 4010 Py_DECREF(offset); 4011 minutes = divmod(seconds, 60, &seconds); 4012 hours = divmod(minutes, 60, &minutes); 4013 if (microseconds != 0) { 4014 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d", 4015 sign, hours, minutes, 4016 seconds, microseconds); 4017 } 4018 if (seconds != 0) { 4019 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d", 4020 sign, hours, minutes, seconds); 4021 } 4022 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes); 4023} 4024 4025static PyObject * 4026timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt) 4027{ 4028 if (_timezone_check_argument(dt, "tzname") == -1) 4029 return NULL; 4030 4031 return timezone_str(self); 4032} 4033 4034static PyObject * 4035timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt) 4036{ 4037 if (_timezone_check_argument(dt, "utcoffset") == -1) 4038 return NULL; 4039 4040 Py_INCREF(self->offset); 4041 return self->offset; 4042} 4043 4044static PyObject * 4045timezone_dst(PyObject *self, PyObject *dt) 4046{ 4047 if (_timezone_check_argument(dt, "dst") == -1) 4048 return NULL; 4049 4050 Py_RETURN_NONE; 4051} 4052 4053static PyObject * 4054timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt) 4055{ 4056 if (!PyDateTime_Check(dt)) { 4057 PyErr_SetString(PyExc_TypeError, 4058 "fromutc: argument must be a datetime"); 4059 return NULL; 4060 } 4061 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) { 4062 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo " 4063 "is not self"); 4064 return NULL; 4065 } 4066 4067 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1); 4068} 4069 4070static PyObject * 4071timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored)) 4072{ 4073 if (self->name == NULL) 4074 return Py_BuildValue("(O)", self->offset); 4075 return Py_BuildValue("(OO)", self->offset, self->name); 4076} 4077 4078static PyMethodDef timezone_methods[] = { 4079 {"tzname", (PyCFunction)timezone_tzname, METH_O, 4080 PyDoc_STR("If name is specified when timezone is created, returns the name." 4081 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")}, 4082 4083 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O, 4084 PyDoc_STR("Return fixed offset.")}, 4085 4086 {"dst", (PyCFunction)timezone_dst, METH_O, 4087 PyDoc_STR("Return None.")}, 4088 4089 {"fromutc", (PyCFunction)timezone_fromutc, METH_O, 4090 PyDoc_STR("datetime in UTC -> datetime in local time.")}, 4091 4092 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS, 4093 PyDoc_STR("pickle support")}, 4094 4095 {NULL, NULL} 4096}; 4097 4098static const char timezone_doc[] = 4099PyDoc_STR("Fixed offset from UTC implementation of tzinfo."); 4100 4101static PyTypeObject PyDateTime_TimeZoneType = { 4102 PyVarObject_HEAD_INIT(NULL, 0) 4103 "datetime.timezone", /* tp_name */ 4104 sizeof(PyDateTime_TimeZone), /* tp_basicsize */ 4105 0, /* tp_itemsize */ 4106 (destructor)timezone_dealloc, /* tp_dealloc */ 4107 0, /* tp_vectorcall_offset */ 4108 0, /* tp_getattr */ 4109 0, /* tp_setattr */ 4110 0, /* tp_as_async */ 4111 (reprfunc)timezone_repr, /* tp_repr */ 4112 0, /* tp_as_number */ 4113 0, /* tp_as_sequence */ 4114 0, /* tp_as_mapping */ 4115 (hashfunc)timezone_hash, /* tp_hash */ 4116 0, /* tp_call */ 4117 (reprfunc)timezone_str, /* tp_str */ 4118 0, /* tp_getattro */ 4119 0, /* tp_setattro */ 4120 0, /* tp_as_buffer */ 4121 Py_TPFLAGS_DEFAULT, /* tp_flags */ 4122 timezone_doc, /* tp_doc */ 4123 0, /* tp_traverse */ 4124 0, /* tp_clear */ 4125 (richcmpfunc)timezone_richcompare,/* tp_richcompare */ 4126 0, /* tp_weaklistoffset */ 4127 0, /* tp_iter */ 4128 0, /* tp_iternext */ 4129 timezone_methods, /* tp_methods */ 4130 0, /* tp_members */ 4131 0, /* tp_getset */ 4132 0, /* tp_base; filled in PyInit__datetime */ 4133 0, /* tp_dict */ 4134 0, /* tp_descr_get */ 4135 0, /* tp_descr_set */ 4136 0, /* tp_dictoffset */ 4137 0, /* tp_init */ 4138 0, /* tp_alloc */ 4139 timezone_new, /* tp_new */ 4140}; 4141 4142/* 4143 * PyDateTime_Time implementation. 4144 */ 4145 4146/* Accessor properties. 4147 */ 4148 4149static PyObject * 4150time_hour(PyDateTime_Time *self, void *unused) 4151{ 4152 return PyLong_FromLong(TIME_GET_HOUR(self)); 4153} 4154 4155static PyObject * 4156time_minute(PyDateTime_Time *self, void *unused) 4157{ 4158 return PyLong_FromLong(TIME_GET_MINUTE(self)); 4159} 4160 4161/* The name time_second conflicted with some platform header file. */ 4162static PyObject * 4163py_time_second(PyDateTime_Time *self, void *unused) 4164{ 4165 return PyLong_FromLong(TIME_GET_SECOND(self)); 4166} 4167 4168static PyObject * 4169time_microsecond(PyDateTime_Time *self, void *unused) 4170{ 4171 return PyLong_FromLong(TIME_GET_MICROSECOND(self)); 4172} 4173 4174static PyObject * 4175time_tzinfo(PyDateTime_Time *self, void *unused) 4176{ 4177 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; 4178 Py_INCREF(result); 4179 return result; 4180} 4181 4182static PyObject * 4183time_fold(PyDateTime_Time *self, void *unused) 4184{ 4185 return PyLong_FromLong(TIME_GET_FOLD(self)); 4186} 4187 4188static PyGetSetDef time_getset[] = { 4189 {"hour", (getter)time_hour}, 4190 {"minute", (getter)time_minute}, 4191 {"second", (getter)py_time_second}, 4192 {"microsecond", (getter)time_microsecond}, 4193 {"tzinfo", (getter)time_tzinfo}, 4194 {"fold", (getter)time_fold}, 4195 {NULL} 4196}; 4197 4198/* 4199 * Constructors. 4200 */ 4201 4202static char *time_kws[] = {"hour", "minute", "second", "microsecond", 4203 "tzinfo", "fold", NULL}; 4204 4205static PyObject * 4206time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) 4207{ 4208 PyDateTime_Time *me; 4209 char aware = (char)(tzinfo != Py_None); 4210 4211 if (aware && check_tzinfo_subclass(tzinfo) < 0) { 4212 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg"); 4213 return NULL; 4214 } 4215 4216 me = (PyDateTime_Time *) (type->tp_alloc(type, aware)); 4217 if (me != NULL) { 4218 const char *pdata = PyBytes_AS_STRING(state); 4219 4220 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE); 4221 me->hashcode = -1; 4222 me->hastzinfo = aware; 4223 if (aware) { 4224 Py_INCREF(tzinfo); 4225 me->tzinfo = tzinfo; 4226 } 4227 if (pdata[0] & (1 << 7)) { 4228 me->data[0] -= 128; 4229 me->fold = 1; 4230 } 4231 else { 4232 me->fold = 0; 4233 } 4234 } 4235 return (PyObject *)me; 4236} 4237 4238static PyObject * 4239time_new(PyTypeObject *type, PyObject *args, PyObject *kw) 4240{ 4241 PyObject *self = NULL; 4242 int hour = 0; 4243 int minute = 0; 4244 int second = 0; 4245 int usecond = 0; 4246 PyObject *tzinfo = Py_None; 4247 int fold = 0; 4248 4249 /* Check for invocation from pickle with __getstate__ state */ 4250 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) { 4251 PyObject *state = PyTuple_GET_ITEM(args, 0); 4252 if (PyTuple_GET_SIZE(args) == 2) { 4253 tzinfo = PyTuple_GET_ITEM(args, 1); 4254 } 4255 if (PyBytes_Check(state)) { 4256 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE && 4257 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24) 4258 { 4259 return time_from_pickle(type, state, tzinfo); 4260 } 4261 } 4262 else if (PyUnicode_Check(state)) { 4263 if (PyUnicode_READY(state)) { 4264 return NULL; 4265 } 4266 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE && 4267 (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24) 4268 { 4269 state = PyUnicode_AsLatin1String(state); 4270 if (state == NULL) { 4271 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { 4272 /* More informative error message. */ 4273 PyErr_SetString(PyExc_ValueError, 4274 "Failed to encode latin1 string when unpickling " 4275 "a time object. " 4276 "pickle.load(data, encoding='latin1') is assumed."); 4277 } 4278 return NULL; 4279 } 4280 self = time_from_pickle(type, state, tzinfo); 4281 Py_DECREF(state); 4282 return self; 4283 } 4284 } 4285 tzinfo = Py_None; 4286 } 4287 4288 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws, 4289 &hour, &minute, &second, &usecond, 4290 &tzinfo, &fold)) { 4291 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold, 4292 type); 4293 } 4294 return self; 4295} 4296 4297/* 4298 * Destructor. 4299 */ 4300 4301static void 4302time_dealloc(PyDateTime_Time *self) 4303{ 4304 if (HASTZINFO(self)) { 4305 Py_XDECREF(self->tzinfo); 4306 } 4307 Py_TYPE(self)->tp_free((PyObject *)self); 4308} 4309 4310/* 4311 * Indirect access to tzinfo methods. 4312 */ 4313 4314/* These are all METH_NOARGS, so don't need to check the arglist. */ 4315static PyObject * 4316time_utcoffset(PyObject *self, PyObject *unused) { 4317 return call_utcoffset(GET_TIME_TZINFO(self), Py_None); 4318} 4319 4320static PyObject * 4321time_dst(PyObject *self, PyObject *unused) { 4322 return call_dst(GET_TIME_TZINFO(self), Py_None); 4323} 4324 4325static PyObject * 4326time_tzname(PyDateTime_Time *self, PyObject *unused) { 4327 return call_tzname(GET_TIME_TZINFO(self), Py_None); 4328} 4329 4330/* 4331 * Various ways to turn a time into a string. 4332 */ 4333 4334static PyObject * 4335time_repr(PyDateTime_Time *self) 4336{ 4337 const char *type_name = Py_TYPE(self)->tp_name; 4338 int h = TIME_GET_HOUR(self); 4339 int m = TIME_GET_MINUTE(self); 4340 int s = TIME_GET_SECOND(self); 4341 int us = TIME_GET_MICROSECOND(self); 4342 int fold = TIME_GET_FOLD(self); 4343 PyObject *result = NULL; 4344 4345 if (us) 4346 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)", 4347 type_name, h, m, s, us); 4348 else if (s) 4349 result = PyUnicode_FromFormat("%s(%d, %d, %d)", 4350 type_name, h, m, s); 4351 else 4352 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m); 4353 if (result != NULL && HASTZINFO(self)) 4354 result = append_keyword_tzinfo(result, self->tzinfo); 4355 if (result != NULL && fold) 4356 result = append_keyword_fold(result, fold); 4357 return result; 4358} 4359 4360static PyObject * 4361time_str(PyDateTime_Time *self) 4362{ 4363 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); 4364} 4365 4366static PyObject * 4367time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw) 4368{ 4369 char buf[100]; 4370 const char *timespec = NULL; 4371 static char *keywords[] = {"timespec", NULL}; 4372 PyObject *result; 4373 int us = TIME_GET_MICROSECOND(self); 4374 static const char *specs[][2] = { 4375 {"hours", "%02d"}, 4376 {"minutes", "%02d:%02d"}, 4377 {"seconds", "%02d:%02d:%02d"}, 4378 {"milliseconds", "%02d:%02d:%02d.%03d"}, 4379 {"microseconds", "%02d:%02d:%02d.%06d"}, 4380 }; 4381 size_t given_spec; 4382 4383 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, ×pec)) 4384 return NULL; 4385 4386 if (timespec == NULL || strcmp(timespec, "auto") == 0) { 4387 if (us == 0) { 4388 /* seconds */ 4389 given_spec = 2; 4390 } 4391 else { 4392 /* microseconds */ 4393 given_spec = 4; 4394 } 4395 } 4396 else { 4397 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) { 4398 if (strcmp(timespec, specs[given_spec][0]) == 0) { 4399 if (given_spec == 3) { 4400 /* milliseconds */ 4401 us = us / 1000; 4402 } 4403 break; 4404 } 4405 } 4406 } 4407 4408 if (given_spec == Py_ARRAY_LENGTH(specs)) { 4409 PyErr_Format(PyExc_ValueError, "Unknown timespec value"); 4410 return NULL; 4411 } 4412 else { 4413 result = PyUnicode_FromFormat(specs[given_spec][1], 4414 TIME_GET_HOUR(self), TIME_GET_MINUTE(self), 4415 TIME_GET_SECOND(self), us); 4416 } 4417 4418 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None) 4419 return result; 4420 4421 /* We need to append the UTC offset. */ 4422 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo, 4423 Py_None) < 0) { 4424 Py_DECREF(result); 4425 return NULL; 4426 } 4427 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf)); 4428 return result; 4429} 4430 4431static PyObject * 4432time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw) 4433{ 4434 PyObject *result; 4435 PyObject *tuple; 4436 PyObject *format; 4437 static char *keywords[] = {"format", NULL}; 4438 4439 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords, 4440 &format)) 4441 return NULL; 4442 4443 /* Python's strftime does insane things with the year part of the 4444 * timetuple. The year is forced to (the otherwise nonsensical) 4445 * 1900 to work around that. 4446 */ 4447 tuple = Py_BuildValue("iiiiiiiii", 4448 1900, 1, 1, /* year, month, day */ 4449 TIME_GET_HOUR(self), 4450 TIME_GET_MINUTE(self), 4451 TIME_GET_SECOND(self), 4452 0, 1, -1); /* weekday, daynum, dst */ 4453 if (tuple == NULL) 4454 return NULL; 4455 assert(PyTuple_Size(tuple) == 9); 4456 result = wrap_strftime((PyObject *)self, format, tuple, 4457 Py_None); 4458 Py_DECREF(tuple); 4459 return result; 4460} 4461 4462/* 4463 * Miscellaneous methods. 4464 */ 4465 4466static PyObject * 4467time_richcompare(PyObject *self, PyObject *other, int op) 4468{ 4469 PyObject *result = NULL; 4470 PyObject *offset1, *offset2; 4471 int diff; 4472 4473 if (! PyTime_Check(other)) 4474 Py_RETURN_NOTIMPLEMENTED; 4475 4476 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) { 4477 diff = memcmp(((PyDateTime_Time *)self)->data, 4478 ((PyDateTime_Time *)other)->data, 4479 _PyDateTime_TIME_DATASIZE); 4480 return diff_to_bool(diff, op); 4481 } 4482 offset1 = time_utcoffset(self, NULL); 4483 if (offset1 == NULL) 4484 return NULL; 4485 offset2 = time_utcoffset(other, NULL); 4486 if (offset2 == NULL) 4487 goto done; 4488 /* If they're both naive, or both aware and have the same offsets, 4489 * we get off cheap. Note that if they're both naive, offset1 == 4490 * offset2 == Py_None at this point. 4491 */ 4492 if ((offset1 == offset2) || 4493 (PyDelta_Check(offset1) && PyDelta_Check(offset2) && 4494 delta_cmp(offset1, offset2) == 0)) { 4495 diff = memcmp(((PyDateTime_Time *)self)->data, 4496 ((PyDateTime_Time *)other)->data, 4497 _PyDateTime_TIME_DATASIZE); 4498 result = diff_to_bool(diff, op); 4499 } 4500 /* The hard case: both aware with different UTC offsets */ 4501 else if (offset1 != Py_None && offset2 != Py_None) { 4502 int offsecs1, offsecs2; 4503 assert(offset1 != offset2); /* else last "if" handled it */ 4504 offsecs1 = TIME_GET_HOUR(self) * 3600 + 4505 TIME_GET_MINUTE(self) * 60 + 4506 TIME_GET_SECOND(self) - 4507 GET_TD_DAYS(offset1) * 86400 - 4508 GET_TD_SECONDS(offset1); 4509 offsecs2 = TIME_GET_HOUR(other) * 3600 + 4510 TIME_GET_MINUTE(other) * 60 + 4511 TIME_GET_SECOND(other) - 4512 GET_TD_DAYS(offset2) * 86400 - 4513 GET_TD_SECONDS(offset2); 4514 diff = offsecs1 - offsecs2; 4515 if (diff == 0) 4516 diff = TIME_GET_MICROSECOND(self) - 4517 TIME_GET_MICROSECOND(other); 4518 result = diff_to_bool(diff, op); 4519 } 4520 else if (op == Py_EQ) { 4521 result = Py_False; 4522 Py_INCREF(result); 4523 } 4524 else if (op == Py_NE) { 4525 result = Py_True; 4526 Py_INCREF(result); 4527 } 4528 else { 4529 PyErr_SetString(PyExc_TypeError, 4530 "can't compare offset-naive and " 4531 "offset-aware times"); 4532 } 4533 done: 4534 Py_DECREF(offset1); 4535 Py_XDECREF(offset2); 4536 return result; 4537} 4538 4539static Py_hash_t 4540time_hash(PyDateTime_Time *self) 4541{ 4542 if (self->hashcode == -1) { 4543 PyObject *offset, *self0; 4544 if (TIME_GET_FOLD(self)) { 4545 self0 = new_time_ex2(TIME_GET_HOUR(self), 4546 TIME_GET_MINUTE(self), 4547 TIME_GET_SECOND(self), 4548 TIME_GET_MICROSECOND(self), 4549 HASTZINFO(self) ? self->tzinfo : Py_None, 4550 0, Py_TYPE(self)); 4551 if (self0 == NULL) 4552 return -1; 4553 } 4554 else { 4555 self0 = (PyObject *)self; 4556 Py_INCREF(self0); 4557 } 4558 offset = time_utcoffset(self0, NULL); 4559 Py_DECREF(self0); 4560 4561 if (offset == NULL) 4562 return -1; 4563 4564 /* Reduce this to a hash of another object. */ 4565 if (offset == Py_None) 4566 self->hashcode = generic_hash( 4567 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE); 4568 else { 4569 PyObject *temp1, *temp2; 4570 int seconds, microseconds; 4571 assert(HASTZINFO(self)); 4572 seconds = TIME_GET_HOUR(self) * 3600 + 4573 TIME_GET_MINUTE(self) * 60 + 4574 TIME_GET_SECOND(self); 4575 microseconds = TIME_GET_MICROSECOND(self); 4576 temp1 = new_delta(0, seconds, microseconds, 1); 4577 if (temp1 == NULL) { 4578 Py_DECREF(offset); 4579 return -1; 4580 } 4581 temp2 = delta_subtract(temp1, offset); 4582 Py_DECREF(temp1); 4583 if (temp2 == NULL) { 4584 Py_DECREF(offset); 4585 return -1; 4586 } 4587 self->hashcode = PyObject_Hash(temp2); 4588 Py_DECREF(temp2); 4589 } 4590 Py_DECREF(offset); 4591 } 4592 return self->hashcode; 4593} 4594 4595static PyObject * 4596time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) 4597{ 4598 PyObject *clone; 4599 PyObject *tuple; 4600 int hh = TIME_GET_HOUR(self); 4601 int mm = TIME_GET_MINUTE(self); 4602 int ss = TIME_GET_SECOND(self); 4603 int us = TIME_GET_MICROSECOND(self); 4604 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None; 4605 int fold = TIME_GET_FOLD(self); 4606 4607 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace", 4608 time_kws, 4609 &hh, &mm, &ss, &us, &tzinfo, &fold)) 4610 return NULL; 4611 if (fold != 0 && fold != 1) { 4612 PyErr_SetString(PyExc_ValueError, 4613 "fold must be either 0 or 1"); 4614 return NULL; 4615 } 4616 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo); 4617 if (tuple == NULL) 4618 return NULL; 4619 clone = time_new(Py_TYPE(self), tuple, NULL); 4620 if (clone != NULL) { 4621 TIME_SET_FOLD(clone, fold); 4622 } 4623 Py_DECREF(tuple); 4624 return clone; 4625} 4626 4627static PyObject * 4628time_fromisoformat(PyObject *cls, PyObject *tstr) { 4629 assert(tstr != NULL); 4630 4631 if (!PyUnicode_Check(tstr)) { 4632 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str"); 4633 return NULL; 4634 } 4635 4636 Py_ssize_t len; 4637 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len); 4638 4639 if (p == NULL) { 4640 goto invalid_string_error; 4641 } 4642 4643 // The spec actually requires that time-only ISO 8601 strings start with 4644 // T, but the extended format allows this to be omitted as long as there 4645 // is no ambiguity with date strings. 4646 if (*p == 'T') { 4647 ++p; 4648 len -= 1; 4649 } 4650 4651 int hour = 0, minute = 0, second = 0, microsecond = 0; 4652 int tzoffset, tzimicrosecond = 0; 4653 int rv = parse_isoformat_time(p, len, 4654 &hour, &minute, &second, µsecond, 4655 &tzoffset, &tzimicrosecond); 4656 4657 if (rv < 0) { 4658 goto invalid_string_error; 4659 } 4660 4661 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, 4662 tzimicrosecond); 4663 4664 if (tzinfo == NULL) { 4665 return NULL; 4666 } 4667 4668 PyObject *t; 4669 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) { 4670 t = new_time(hour, minute, second, microsecond, tzinfo, 0); 4671 } else { 4672 t = PyObject_CallFunction(cls, "iiiiO", 4673 hour, minute, second, microsecond, tzinfo); 4674 } 4675 4676 Py_DECREF(tzinfo); 4677 return t; 4678 4679invalid_string_error: 4680 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr); 4681 return NULL; 4682} 4683 4684 4685/* Pickle support, a simple use of __reduce__. */ 4686 4687/* Let basestate be the non-tzinfo data string. 4688 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). 4689 * So it's a tuple in any (non-error) case. 4690 * __getstate__ isn't exposed. 4691 */ 4692static PyObject * 4693time_getstate(PyDateTime_Time *self, int proto) 4694{ 4695 PyObject *basestate; 4696 PyObject *result = NULL; 4697 4698 basestate = PyBytes_FromStringAndSize((char *)self->data, 4699 _PyDateTime_TIME_DATASIZE); 4700 if (basestate != NULL) { 4701 if (proto > 3 && TIME_GET_FOLD(self)) 4702 /* Set the first bit of the first byte */ 4703 PyBytes_AS_STRING(basestate)[0] |= (1 << 7); 4704 if (! HASTZINFO(self) || self->tzinfo == Py_None) 4705 result = PyTuple_Pack(1, basestate); 4706 else 4707 result = PyTuple_Pack(2, basestate, self->tzinfo); 4708 Py_DECREF(basestate); 4709 } 4710 return result; 4711} 4712 4713static PyObject * 4714time_reduce_ex(PyDateTime_Time *self, PyObject *args) 4715{ 4716 int proto; 4717 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto)) 4718 return NULL; 4719 4720 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto)); 4721} 4722 4723static PyObject * 4724time_reduce(PyDateTime_Time *self, PyObject *arg) 4725{ 4726 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2)); 4727} 4728 4729static PyMethodDef time_methods[] = { 4730 4731 {"isoformat", _PyCFunction_CAST(time_isoformat), METH_VARARGS | METH_KEYWORDS, 4732 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]" 4733 "[+HH:MM].\n\n" 4734 "The optional argument timespec specifies the number " 4735 "of additional terms\nof the time to include. Valid " 4736 "options are 'auto', 'hours', 'minutes',\n'seconds', " 4737 "'milliseconds' and 'microseconds'.\n")}, 4738 4739 {"strftime", _PyCFunction_CAST(time_strftime), METH_VARARGS | METH_KEYWORDS, 4740 PyDoc_STR("format -> strftime() style string.")}, 4741 4742 {"__format__", (PyCFunction)date_format, METH_VARARGS, 4743 PyDoc_STR("Formats self with strftime.")}, 4744 4745 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS, 4746 PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, 4747 4748 {"tzname", (PyCFunction)time_tzname, METH_NOARGS, 4749 PyDoc_STR("Return self.tzinfo.tzname(self).")}, 4750 4751 {"dst", (PyCFunction)time_dst, METH_NOARGS, 4752 PyDoc_STR("Return self.tzinfo.dst(self).")}, 4753 4754 {"replace", _PyCFunction_CAST(time_replace), METH_VARARGS | METH_KEYWORDS, 4755 PyDoc_STR("Return time with new specified fields.")}, 4756 4757 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS, 4758 PyDoc_STR("string -> time from a string in ISO 8601 format")}, 4759 4760 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS, 4761 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")}, 4762 4763 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS, 4764 PyDoc_STR("__reduce__() -> (cls, state)")}, 4765 4766 {NULL, NULL} 4767}; 4768 4769static const char time_doc[] = 4770PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\ 4771\n\ 4772All arguments are optional. tzinfo may be None, or an instance of\n\ 4773a tzinfo subclass. The remaining arguments may be ints.\n"); 4774 4775static PyTypeObject PyDateTime_TimeType = { 4776 PyVarObject_HEAD_INIT(NULL, 0) 4777 "datetime.time", /* tp_name */ 4778 sizeof(PyDateTime_Time), /* tp_basicsize */ 4779 0, /* tp_itemsize */ 4780 (destructor)time_dealloc, /* tp_dealloc */ 4781 0, /* tp_vectorcall_offset */ 4782 0, /* tp_getattr */ 4783 0, /* tp_setattr */ 4784 0, /* tp_as_async */ 4785 (reprfunc)time_repr, /* tp_repr */ 4786 0, /* tp_as_number */ 4787 0, /* tp_as_sequence */ 4788 0, /* tp_as_mapping */ 4789 (hashfunc)time_hash, /* tp_hash */ 4790 0, /* tp_call */ 4791 (reprfunc)time_str, /* tp_str */ 4792 PyObject_GenericGetAttr, /* tp_getattro */ 4793 0, /* tp_setattro */ 4794 0, /* tp_as_buffer */ 4795 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 4796 time_doc, /* tp_doc */ 4797 0, /* tp_traverse */ 4798 0, /* tp_clear */ 4799 time_richcompare, /* tp_richcompare */ 4800 0, /* tp_weaklistoffset */ 4801 0, /* tp_iter */ 4802 0, /* tp_iternext */ 4803 time_methods, /* tp_methods */ 4804 0, /* tp_members */ 4805 time_getset, /* tp_getset */ 4806 0, /* tp_base */ 4807 0, /* tp_dict */ 4808 0, /* tp_descr_get */ 4809 0, /* tp_descr_set */ 4810 0, /* tp_dictoffset */ 4811 0, /* tp_init */ 4812 time_alloc, /* tp_alloc */ 4813 time_new, /* tp_new */ 4814 0, /* tp_free */ 4815}; 4816 4817/* 4818 * PyDateTime_DateTime implementation. 4819 */ 4820 4821/* Accessor properties. Properties for day, month, and year are inherited 4822 * from date. 4823 */ 4824 4825static PyObject * 4826datetime_hour(PyDateTime_DateTime *self, void *unused) 4827{ 4828 return PyLong_FromLong(DATE_GET_HOUR(self)); 4829} 4830 4831static PyObject * 4832datetime_minute(PyDateTime_DateTime *self, void *unused) 4833{ 4834 return PyLong_FromLong(DATE_GET_MINUTE(self)); 4835} 4836 4837static PyObject * 4838datetime_second(PyDateTime_DateTime *self, void *unused) 4839{ 4840 return PyLong_FromLong(DATE_GET_SECOND(self)); 4841} 4842 4843static PyObject * 4844datetime_microsecond(PyDateTime_DateTime *self, void *unused) 4845{ 4846 return PyLong_FromLong(DATE_GET_MICROSECOND(self)); 4847} 4848 4849static PyObject * 4850datetime_tzinfo(PyDateTime_DateTime *self, void *unused) 4851{ 4852 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; 4853 Py_INCREF(result); 4854 return result; 4855} 4856 4857static PyObject * 4858datetime_fold(PyDateTime_DateTime *self, void *unused) 4859{ 4860 return PyLong_FromLong(DATE_GET_FOLD(self)); 4861} 4862 4863static PyGetSetDef datetime_getset[] = { 4864 {"hour", (getter)datetime_hour}, 4865 {"minute", (getter)datetime_minute}, 4866 {"second", (getter)datetime_second}, 4867 {"microsecond", (getter)datetime_microsecond}, 4868 {"tzinfo", (getter)datetime_tzinfo}, 4869 {"fold", (getter)datetime_fold}, 4870 {NULL} 4871}; 4872 4873/* 4874 * Constructors. 4875 */ 4876 4877static char *datetime_kws[] = { 4878 "year", "month", "day", "hour", "minute", "second", 4879 "microsecond", "tzinfo", "fold", NULL 4880}; 4881 4882static PyObject * 4883datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) 4884{ 4885 PyDateTime_DateTime *me; 4886 char aware = (char)(tzinfo != Py_None); 4887 4888 if (aware && check_tzinfo_subclass(tzinfo) < 0) { 4889 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg"); 4890 return NULL; 4891 } 4892 4893 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware)); 4894 if (me != NULL) { 4895 const char *pdata = PyBytes_AS_STRING(state); 4896 4897 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE); 4898 me->hashcode = -1; 4899 me->hastzinfo = aware; 4900 if (aware) { 4901 Py_INCREF(tzinfo); 4902 me->tzinfo = tzinfo; 4903 } 4904 if (pdata[2] & (1 << 7)) { 4905 me->data[2] -= 128; 4906 me->fold = 1; 4907 } 4908 else { 4909 me->fold = 0; 4910 } 4911 } 4912 return (PyObject *)me; 4913} 4914 4915static PyObject * 4916datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) 4917{ 4918 PyObject *self = NULL; 4919 int year; 4920 int month; 4921 int day; 4922 int hour = 0; 4923 int minute = 0; 4924 int second = 0; 4925 int usecond = 0; 4926 int fold = 0; 4927 PyObject *tzinfo = Py_None; 4928 4929 /* Check for invocation from pickle with __getstate__ state */ 4930 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) { 4931 PyObject *state = PyTuple_GET_ITEM(args, 0); 4932 if (PyTuple_GET_SIZE(args) == 2) { 4933 tzinfo = PyTuple_GET_ITEM(args, 1); 4934 } 4935 if (PyBytes_Check(state)) { 4936 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE && 4937 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F)) 4938 { 4939 return datetime_from_pickle(type, state, tzinfo); 4940 } 4941 } 4942 else if (PyUnicode_Check(state)) { 4943 if (PyUnicode_READY(state)) { 4944 return NULL; 4945 } 4946 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE && 4947 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F)) 4948 { 4949 state = PyUnicode_AsLatin1String(state); 4950 if (state == NULL) { 4951 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { 4952 /* More informative error message. */ 4953 PyErr_SetString(PyExc_ValueError, 4954 "Failed to encode latin1 string when unpickling " 4955 "a datetime object. " 4956 "pickle.load(data, encoding='latin1') is assumed."); 4957 } 4958 return NULL; 4959 } 4960 self = datetime_from_pickle(type, state, tzinfo); 4961 Py_DECREF(state); 4962 return self; 4963 } 4964 } 4965 tzinfo = Py_None; 4966 } 4967 4968 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws, 4969 &year, &month, &day, &hour, &minute, 4970 &second, &usecond, &tzinfo, &fold)) { 4971 self = new_datetime_ex2(year, month, day, 4972 hour, minute, second, usecond, 4973 tzinfo, fold, type); 4974 } 4975 return self; 4976} 4977 4978/* TM_FUNC is the shared type of _PyTime_localtime() and 4979 * _PyTime_gmtime(). */ 4980typedef int (*TM_FUNC)(time_t timer, struct tm*); 4981 4982/* As of version 2015f max fold in IANA database is 4983 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */ 4984static long long max_fold_seconds = 24 * 3600; 4985/* NB: date(1970,1,1).toordinal() == 719163 */ 4986static long long epoch = 719163LL * 24 * 60 * 60; 4987 4988static long long 4989utc_to_seconds(int year, int month, int day, 4990 int hour, int minute, int second) 4991{ 4992 long long ordinal; 4993 4994 /* ymd_to_ord() doesn't support year <= 0 */ 4995 if (year < MINYEAR || year > MAXYEAR) { 4996 PyErr_Format(PyExc_ValueError, "year %i is out of range", year); 4997 return -1; 4998 } 4999 5000 ordinal = ymd_to_ord(year, month, day); 5001 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second; 5002} 5003 5004static long long 5005local(long long u) 5006{ 5007 struct tm local_time; 5008 time_t t; 5009 u -= epoch; 5010 t = u; 5011 if (t != u) { 5012 PyErr_SetString(PyExc_OverflowError, 5013 "timestamp out of range for platform time_t"); 5014 return -1; 5015 } 5016 if (_PyTime_localtime(t, &local_time) != 0) 5017 return -1; 5018 return utc_to_seconds(local_time.tm_year + 1900, 5019 local_time.tm_mon + 1, 5020 local_time.tm_mday, 5021 local_time.tm_hour, 5022 local_time.tm_min, 5023 local_time.tm_sec); 5024} 5025 5026/* Internal helper. 5027 * Build datetime from a time_t and a distinct count of microseconds. 5028 * Pass localtime or gmtime for f, to control the interpretation of timet. 5029 */ 5030static PyObject * 5031datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, 5032 PyObject *tzinfo) 5033{ 5034 struct tm tm; 5035 int year, month, day, hour, minute, second, fold = 0; 5036 5037 if (f(timet, &tm) != 0) 5038 return NULL; 5039 5040 year = tm.tm_year + 1900; 5041 month = tm.tm_mon + 1; 5042 day = tm.tm_mday; 5043 hour = tm.tm_hour; 5044 minute = tm.tm_min; 5045 /* The platform localtime/gmtime may insert leap seconds, 5046 * indicated by tm.tm_sec > 59. We don't care about them, 5047 * except to the extent that passing them on to the datetime 5048 * constructor would raise ValueError for a reason that 5049 * made no sense to the user. 5050 */ 5051 second = Py_MIN(59, tm.tm_sec); 5052 5053 /* local timezone requires to compute fold */ 5054 if (tzinfo == Py_None && f == _PyTime_localtime 5055 /* On Windows, passing a negative value to local results 5056 * in an OSError because localtime_s on Windows does 5057 * not support negative timestamps. Unfortunately this 5058 * means that fold detection for time values between 5059 * 0 and max_fold_seconds will result in an identical 5060 * error since we subtract max_fold_seconds to detect a 5061 * fold. However, since we know there haven't been any 5062 * folds in the interval [0, max_fold_seconds) in any 5063 * timezone, we can hackily just forego fold detection 5064 * for this time range. 5065 */ 5066#ifdef MS_WINDOWS 5067 && (timet - max_fold_seconds > 0) 5068#endif 5069 ) { 5070 long long probe_seconds, result_seconds, transition; 5071 5072 result_seconds = utc_to_seconds(year, month, day, 5073 hour, minute, second); 5074 if (result_seconds == -1 && PyErr_Occurred()) { 5075 return NULL; 5076 } 5077 5078 /* Probe max_fold_seconds to detect a fold. */ 5079 probe_seconds = local(epoch + timet - max_fold_seconds); 5080 if (probe_seconds == -1) 5081 return NULL; 5082 transition = result_seconds - probe_seconds - max_fold_seconds; 5083 if (transition < 0) { 5084 probe_seconds = local(epoch + timet + transition); 5085 if (probe_seconds == -1) 5086 return NULL; 5087 if (probe_seconds == result_seconds) 5088 fold = 1; 5089 } 5090 } 5091 return new_datetime_subclass_fold_ex(year, month, day, hour, minute, 5092 second, us, tzinfo, fold, cls); 5093} 5094 5095/* Internal helper. 5096 * Build datetime from a Python timestamp. Pass localtime or gmtime for f, 5097 * to control the interpretation of the timestamp. Since a double doesn't 5098 * have enough bits to cover a datetime's full range of precision, it's 5099 * better to call datetime_from_timet_and_us provided you have a way 5100 * to get that much precision (e.g., C time() isn't good enough). 5101 */ 5102static PyObject * 5103datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, 5104 PyObject *tzinfo) 5105{ 5106 time_t timet; 5107 long us; 5108 5109 if (_PyTime_ObjectToTimeval(timestamp, 5110 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1) 5111 return NULL; 5112 5113 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo); 5114} 5115 5116/* Internal helper. 5117 * Build most accurate possible datetime for current time. Pass localtime or 5118 * gmtime for f as appropriate. 5119 */ 5120static PyObject * 5121datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo) 5122{ 5123 _PyTime_t ts = _PyTime_GetSystemClock(); 5124 time_t secs; 5125 int us; 5126 5127 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0) 5128 return NULL; 5129 assert(0 <= us && us <= 999999); 5130 5131 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo); 5132} 5133 5134/*[clinic input] 5135 5136@classmethod 5137datetime.datetime.now 5138 5139 tz: object = None 5140 Timezone object. 5141 5142Returns new datetime object representing current time local to tz. 5143 5144If no tz is specified, uses local timezone. 5145[clinic start generated code]*/ 5146 5147static PyObject * 5148datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz) 5149/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/ 5150{ 5151 PyObject *self; 5152 5153 /* Return best possible local time -- this isn't constrained by the 5154 * precision of a timestamp. 5155 */ 5156 if (check_tzinfo_subclass(tz) < 0) 5157 return NULL; 5158 5159 self = datetime_best_possible((PyObject *)type, 5160 tz == Py_None ? _PyTime_localtime : 5161 _PyTime_gmtime, 5162 tz); 5163 if (self != NULL && tz != Py_None) { 5164 /* Convert UTC to tzinfo's zone. */ 5165 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self); 5166 } 5167 return self; 5168} 5169 5170/* Return best possible UTC time -- this isn't constrained by the 5171 * precision of a timestamp. 5172 */ 5173static PyObject * 5174datetime_utcnow(PyObject *cls, PyObject *dummy) 5175{ 5176 return datetime_best_possible(cls, _PyTime_gmtime, Py_None); 5177} 5178 5179/* Return new local datetime from timestamp (Python timestamp -- a double). */ 5180static PyObject * 5181datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) 5182{ 5183 PyObject *self; 5184 PyObject *timestamp; 5185 PyObject *tzinfo = Py_None; 5186 static char *keywords[] = {"timestamp", "tz", NULL}; 5187 5188 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp", 5189 keywords, ×tamp, &tzinfo)) 5190 return NULL; 5191 if (check_tzinfo_subclass(tzinfo) < 0) 5192 return NULL; 5193 5194 self = datetime_from_timestamp(cls, 5195 tzinfo == Py_None ? _PyTime_localtime : 5196 _PyTime_gmtime, 5197 timestamp, 5198 tzinfo); 5199 if (self != NULL && tzinfo != Py_None) { 5200 /* Convert UTC to tzinfo's zone. */ 5201 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self); 5202 } 5203 return self; 5204} 5205 5206/* Return new UTC datetime from timestamp (Python timestamp -- a double). */ 5207static PyObject * 5208datetime_utcfromtimestamp(PyObject *cls, PyObject *args) 5209{ 5210 PyObject *timestamp; 5211 PyObject *result = NULL; 5212 5213 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", ×tamp)) 5214 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp, 5215 Py_None); 5216 return result; 5217} 5218 5219/* Return new datetime from _strptime.strptime_datetime(). */ 5220static PyObject * 5221datetime_strptime(PyObject *cls, PyObject *args) 5222{ 5223 static PyObject *module = NULL; 5224 PyObject *string, *format; 5225 _Py_IDENTIFIER(_strptime_datetime); 5226 5227 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format)) 5228 return NULL; 5229 5230 if (module == NULL) { 5231 module = PyImport_ImportModule("_strptime"); 5232 if (module == NULL) 5233 return NULL; 5234 } 5235 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime, 5236 cls, string, format, NULL); 5237} 5238 5239/* Return new datetime from date/datetime and time arguments. */ 5240static PyObject * 5241datetime_combine(PyObject *cls, PyObject *args, PyObject *kw) 5242{ 5243 static char *keywords[] = {"date", "time", "tzinfo", NULL}; 5244 PyObject *date; 5245 PyObject *time; 5246 PyObject *tzinfo = NULL; 5247 PyObject *result = NULL; 5248 5249 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords, 5250 &PyDateTime_DateType, &date, 5251 &PyDateTime_TimeType, &time, &tzinfo)) { 5252 if (tzinfo == NULL) { 5253 if (HASTZINFO(time)) 5254 tzinfo = ((PyDateTime_Time *)time)->tzinfo; 5255 else 5256 tzinfo = Py_None; 5257 } 5258 result = new_datetime_subclass_fold_ex(GET_YEAR(date), 5259 GET_MONTH(date), 5260 GET_DAY(date), 5261 TIME_GET_HOUR(time), 5262 TIME_GET_MINUTE(time), 5263 TIME_GET_SECOND(time), 5264 TIME_GET_MICROSECOND(time), 5265 tzinfo, 5266 TIME_GET_FOLD(time), 5267 cls); 5268 } 5269 return result; 5270} 5271 5272static PyObject * 5273_sanitize_isoformat_str(PyObject *dtstr) 5274{ 5275 Py_ssize_t len = PyUnicode_GetLength(dtstr); 5276 if (len < 7) { // All valid ISO 8601 strings are at least 7 characters long 5277 return NULL; 5278 } 5279 5280 // `fromisoformat` allows surrogate characters in exactly one position, 5281 // the separator; to allow datetime_fromisoformat to make the simplifying 5282 // assumption that all valid strings can be encoded in UTF-8, this function 5283 // replaces any surrogate character separators with `T`. 5284 // 5285 // The result of this, if not NULL, returns a new reference 5286 const void* const unicode_data = PyUnicode_DATA(dtstr); 5287 const unsigned int kind = PyUnicode_KIND(dtstr); 5288 5289 // Depending on the format of the string, the separator can only ever be 5290 // in positions 7, 8 or 10. We'll check each of these for a surrogate and 5291 // if we find one, replace it with `T`. If there is more than one surrogate, 5292 // we don't have to bother sanitizing it, because the function will later 5293 // fail when we try to encode the string as ASCII. 5294 static const size_t potential_separators[3] = {7, 8, 10}; 5295 size_t surrogate_separator = 0; 5296 for(size_t idx = 0; 5297 idx < sizeof(potential_separators) / sizeof(*potential_separators); 5298 ++idx) { 5299 size_t pos = potential_separators[idx]; 5300 if (pos > (size_t)len) { 5301 break; 5302 } 5303 5304 if(Py_UNICODE_IS_SURROGATE(PyUnicode_READ(kind, unicode_data, pos))) { 5305 surrogate_separator = pos; 5306 break; 5307 } 5308 } 5309 5310 if (surrogate_separator == 0) { 5311 Py_INCREF(dtstr); 5312 return dtstr; 5313 } 5314 5315 PyObject *str_out = _PyUnicode_Copy(dtstr); 5316 if (str_out == NULL) { 5317 return NULL; 5318 } 5319 5320 if (PyUnicode_WriteChar(str_out, surrogate_separator, (Py_UCS4)'T')) { 5321 Py_DECREF(str_out); 5322 return NULL; 5323 } 5324 5325 return str_out; 5326} 5327 5328 5329static Py_ssize_t 5330_find_isoformat_datetime_separator(const char *dtstr, Py_ssize_t len) { 5331 // The valid date formats can all be distinguished by characters 4 and 5 5332 // and further narrowed down by character 5333 // which tells us where to look for the separator character. 5334 // Format | As-rendered | Position 5335 // --------------------------------------- 5336 // %Y-%m-%d | YYYY-MM-DD | 10 5337 // %Y%m%d | YYYYMMDD | 8 5338 // %Y-W%V | YYYY-Www | 8 5339 // %YW%V | YYYYWww | 7 5340 // %Y-W%V-%u | YYYY-Www-d | 10 5341 // %YW%V%u | YYYYWwwd | 8 5342 // %Y-%j | YYYY-DDD | 8 5343 // %Y%j | YYYYDDD | 7 5344 // 5345 // Note that because we allow *any* character for the separator, in the 5346 // case where character 4 is W, it's not straightforward to determine where 5347 // the separator is — in the case of YYYY-Www-d, you have actual ambiguity, 5348 // e.g. 2020-W01-0000 could be YYYY-Www-D0HH or YYYY-Www-HHMM, when the 5349 // separator character is a number in the former case or a hyphen in the 5350 // latter case. 5351 // 5352 // The case of YYYYWww can be distinguished from YYYYWwwd by tracking ahead 5353 // to either the end of the string or the first non-numeric character — 5354 // since the time components all come in pairs YYYYWww#HH can be 5355 // distinguished from YYYYWwwd#HH by the fact that there will always be an 5356 // odd number of digits before the first non-digit character in the former 5357 // case. 5358 static const char date_separator = '-'; 5359 static const char week_indicator = 'W'; 5360 5361 if (len == 7) { 5362 return 7; 5363 } 5364 5365 if (dtstr[4] == date_separator) { 5366 // YYYY-??? 5367 5368 if (dtstr[5] == week_indicator) { 5369 // YYYY-W?? 5370 5371 if (len < 8) { 5372 return -1; 5373 } 5374 5375 if (len > 8 && dtstr[8] == date_separator) { 5376 // YYYY-Www-D (10) or YYYY-Www-HH (8) 5377 if (len == 9) { return -1; } 5378 if (len > 10 && is_digit(dtstr[10])) { 5379 // This is as far as we'll try to go to resolve the 5380 // ambiguity for the moment — if we have YYYY-Www-##, the 5381 // separator is either a hyphen at 8 or a number at 10. 5382 // 5383 // We'll assume it's a hyphen at 8 because it's way more 5384 // likely that someone will use a hyphen as a separator 5385 // than a number, but at this point it's really best effort 5386 // because this is an extension of the spec anyway. 5387 return 8; 5388 } 5389 5390 return 10; 5391 } else { 5392 // YYYY-Www (8) 5393 return 8; 5394 } 5395 } else { 5396 // YYYY-MM-DD (10) 5397 return 10; 5398 } 5399 } else { 5400 // YYYY??? 5401 if (dtstr[4] == week_indicator) { 5402 // YYYYWww (7) or YYYYWwwd (8) 5403 size_t idx = 7; 5404 for (; idx < (size_t)len; ++idx) { 5405 // Keep going until we run out of digits. 5406 if (!is_digit(dtstr[idx])) { 5407 break; 5408 } 5409 } 5410 5411 if (idx < 9) { 5412 return idx; 5413 } 5414 5415 if (idx % 2 == 0) { 5416 // If the index of the last number is even, it's YYYYWww 5417 return 7; 5418 } else { 5419 return 8; 5420 } 5421 } else { 5422 // YYYYMMDD (8) 5423 return 8; 5424 } 5425 } 5426} 5427 5428static PyObject * 5429datetime_fromisoformat(PyObject *cls, PyObject *dtstr) 5430{ 5431 assert(dtstr != NULL); 5432 5433 if (!PyUnicode_Check(dtstr)) { 5434 PyErr_SetString(PyExc_TypeError, 5435 "fromisoformat: argument must be str"); 5436 return NULL; 5437 } 5438 5439 // We only need to sanitize this string if the separator is a surrogate 5440 // character. In the situation where the separator location is ambiguous, 5441 // we don't have to sanitize it anything because that can only happen when 5442 // the separator is either '-' or a number. This should mostly be a noop 5443 // but it makes the reference counting easier if we still sanitize. 5444 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr); 5445 if (dtstr_clean == NULL) { 5446 goto invalid_string_error; 5447 } 5448 5449 Py_ssize_t len; 5450 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len); 5451 5452 if (dt_ptr == NULL) { 5453 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { 5454 // Encoding errors are invalid string errors at this point 5455 goto invalid_string_error; 5456 } 5457 else { 5458 goto error; 5459 } 5460 } 5461 5462 const Py_ssize_t separator_location = _find_isoformat_datetime_separator( 5463 dt_ptr, len); 5464 5465 5466 const char *p = dt_ptr; 5467 5468 int year = 0, month = 0, day = 0; 5469 int hour = 0, minute = 0, second = 0, microsecond = 0; 5470 int tzoffset = 0, tzusec = 0; 5471 5472 // date runs up to separator_location 5473 int rv = parse_isoformat_date(p, separator_location, &year, &month, &day); 5474 5475 if (!rv && len > separator_location) { 5476 // In UTF-8, the length of multi-byte characters is encoded in the MSB 5477 p += separator_location; 5478 if ((p[0] & 0x80) == 0) { 5479 p += 1; 5480 } 5481 else { 5482 switch (p[0] & 0xf0) { 5483 case 0xe0: 5484 p += 3; 5485 break; 5486 case 0xf0: 5487 p += 4; 5488 break; 5489 default: 5490 p += 2; 5491 break; 5492 } 5493 } 5494 5495 len -= (p - dt_ptr); 5496 rv = parse_isoformat_time(p, len, &hour, &minute, &second, 5497 µsecond, &tzoffset, &tzusec); 5498 } 5499 if (rv < 0) { 5500 goto invalid_string_error; 5501 } 5502 5503 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec); 5504 if (tzinfo == NULL) { 5505 goto error; 5506 } 5507 5508 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute, 5509 second, microsecond, tzinfo, cls); 5510 5511 Py_DECREF(tzinfo); 5512 Py_DECREF(dtstr_clean); 5513 return dt; 5514 5515invalid_string_error: 5516 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr); 5517 5518error: 5519 Py_XDECREF(dtstr_clean); 5520 5521 return NULL; 5522} 5523 5524/* 5525 * Destructor. 5526 */ 5527 5528static void 5529datetime_dealloc(PyDateTime_DateTime *self) 5530{ 5531 if (HASTZINFO(self)) { 5532 Py_XDECREF(self->tzinfo); 5533 } 5534 Py_TYPE(self)->tp_free((PyObject *)self); 5535} 5536 5537/* 5538 * Indirect access to tzinfo methods. 5539 */ 5540 5541/* These are all METH_NOARGS, so don't need to check the arglist. */ 5542static PyObject * 5543datetime_utcoffset(PyObject *self, PyObject *unused) { 5544 return call_utcoffset(GET_DT_TZINFO(self), self); 5545} 5546 5547static PyObject * 5548datetime_dst(PyObject *self, PyObject *unused) { 5549 return call_dst(GET_DT_TZINFO(self), self); 5550} 5551 5552static PyObject * 5553datetime_tzname(PyObject *self, PyObject *unused) { 5554 return call_tzname(GET_DT_TZINFO(self), self); 5555} 5556 5557/* 5558 * datetime arithmetic. 5559 */ 5560 5561/* factor must be 1 (to add) or -1 (to subtract). The result inherits 5562 * the tzinfo state of date. 5563 */ 5564static PyObject * 5565add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta, 5566 int factor) 5567{ 5568 /* Note that the C-level additions can't overflow, because of 5569 * invariant bounds on the member values. 5570 */ 5571 int year = GET_YEAR(date); 5572 int month = GET_MONTH(date); 5573 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor; 5574 int hour = DATE_GET_HOUR(date); 5575 int minute = DATE_GET_MINUTE(date); 5576 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor; 5577 int microsecond = DATE_GET_MICROSECOND(date) + 5578 GET_TD_MICROSECONDS(delta) * factor; 5579 5580 assert(factor == 1 || factor == -1); 5581 if (normalize_datetime(&year, &month, &day, 5582 &hour, &minute, &second, µsecond) < 0) { 5583 return NULL; 5584 } 5585 5586 return new_datetime_subclass_ex(year, month, day, 5587 hour, minute, second, microsecond, 5588 HASTZINFO(date) ? date->tzinfo : Py_None, 5589 (PyObject *)Py_TYPE(date)); 5590} 5591 5592static PyObject * 5593datetime_add(PyObject *left, PyObject *right) 5594{ 5595 if (PyDateTime_Check(left)) { 5596 /* datetime + ??? */ 5597 if (PyDelta_Check(right)) 5598 /* datetime + delta */ 5599 return add_datetime_timedelta( 5600 (PyDateTime_DateTime *)left, 5601 (PyDateTime_Delta *)right, 5602 1); 5603 } 5604 else if (PyDelta_Check(left)) { 5605 /* delta + datetime */ 5606 return add_datetime_timedelta((PyDateTime_DateTime *) right, 5607 (PyDateTime_Delta *) left, 5608 1); 5609 } 5610 Py_RETURN_NOTIMPLEMENTED; 5611} 5612 5613static PyObject * 5614datetime_subtract(PyObject *left, PyObject *right) 5615{ 5616 PyObject *result = Py_NotImplemented; 5617 5618 if (PyDateTime_Check(left)) { 5619 /* datetime - ??? */ 5620 if (PyDateTime_Check(right)) { 5621 /* datetime - datetime */ 5622 PyObject *offset1, *offset2, *offdiff = NULL; 5623 int delta_d, delta_s, delta_us; 5624 5625 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) { 5626 offset2 = offset1 = Py_None; 5627 Py_INCREF(offset1); 5628 Py_INCREF(offset2); 5629 } 5630 else { 5631 offset1 = datetime_utcoffset(left, NULL); 5632 if (offset1 == NULL) 5633 return NULL; 5634 offset2 = datetime_utcoffset(right, NULL); 5635 if (offset2 == NULL) { 5636 Py_DECREF(offset1); 5637 return NULL; 5638 } 5639 if ((offset1 != Py_None) != (offset2 != Py_None)) { 5640 PyErr_SetString(PyExc_TypeError, 5641 "can't subtract offset-naive and " 5642 "offset-aware datetimes"); 5643 Py_DECREF(offset1); 5644 Py_DECREF(offset2); 5645 return NULL; 5646 } 5647 } 5648 if ((offset1 != offset2) && 5649 delta_cmp(offset1, offset2) != 0) { 5650 offdiff = delta_subtract(offset1, offset2); 5651 if (offdiff == NULL) { 5652 Py_DECREF(offset1); 5653 Py_DECREF(offset2); 5654 return NULL; 5655 } 5656 } 5657 Py_DECREF(offset1); 5658 Py_DECREF(offset2); 5659 delta_d = ymd_to_ord(GET_YEAR(left), 5660 GET_MONTH(left), 5661 GET_DAY(left)) - 5662 ymd_to_ord(GET_YEAR(right), 5663 GET_MONTH(right), 5664 GET_DAY(right)); 5665 /* These can't overflow, since the values are 5666 * normalized. At most this gives the number of 5667 * seconds in one day. 5668 */ 5669 delta_s = (DATE_GET_HOUR(left) - 5670 DATE_GET_HOUR(right)) * 3600 + 5671 (DATE_GET_MINUTE(left) - 5672 DATE_GET_MINUTE(right)) * 60 + 5673 (DATE_GET_SECOND(left) - 5674 DATE_GET_SECOND(right)); 5675 delta_us = DATE_GET_MICROSECOND(left) - 5676 DATE_GET_MICROSECOND(right); 5677 result = new_delta(delta_d, delta_s, delta_us, 1); 5678 if (result == NULL) 5679 return NULL; 5680 5681 if (offdiff != NULL) { 5682 Py_SETREF(result, delta_subtract(result, offdiff)); 5683 Py_DECREF(offdiff); 5684 } 5685 } 5686 else if (PyDelta_Check(right)) { 5687 /* datetime - delta */ 5688 result = add_datetime_timedelta( 5689 (PyDateTime_DateTime *)left, 5690 (PyDateTime_Delta *)right, 5691 -1); 5692 } 5693 } 5694 5695 if (result == Py_NotImplemented) 5696 Py_INCREF(result); 5697 return result; 5698} 5699 5700/* Various ways to turn a datetime into a string. */ 5701 5702static PyObject * 5703datetime_repr(PyDateTime_DateTime *self) 5704{ 5705 const char *type_name = Py_TYPE(self)->tp_name; 5706 PyObject *baserepr; 5707 5708 if (DATE_GET_MICROSECOND(self)) { 5709 baserepr = PyUnicode_FromFormat( 5710 "%s(%d, %d, %d, %d, %d, %d, %d)", 5711 type_name, 5712 GET_YEAR(self), GET_MONTH(self), GET_DAY(self), 5713 DATE_GET_HOUR(self), DATE_GET_MINUTE(self), 5714 DATE_GET_SECOND(self), 5715 DATE_GET_MICROSECOND(self)); 5716 } 5717 else if (DATE_GET_SECOND(self)) { 5718 baserepr = PyUnicode_FromFormat( 5719 "%s(%d, %d, %d, %d, %d, %d)", 5720 type_name, 5721 GET_YEAR(self), GET_MONTH(self), GET_DAY(self), 5722 DATE_GET_HOUR(self), DATE_GET_MINUTE(self), 5723 DATE_GET_SECOND(self)); 5724 } 5725 else { 5726 baserepr = PyUnicode_FromFormat( 5727 "%s(%d, %d, %d, %d, %d)", 5728 type_name, 5729 GET_YEAR(self), GET_MONTH(self), GET_DAY(self), 5730 DATE_GET_HOUR(self), DATE_GET_MINUTE(self)); 5731 } 5732 if (baserepr != NULL && DATE_GET_FOLD(self) != 0) 5733 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self)); 5734 if (baserepr == NULL || ! HASTZINFO(self)) 5735 return baserepr; 5736 return append_keyword_tzinfo(baserepr, self->tzinfo); 5737} 5738 5739static PyObject * 5740datetime_str(PyDateTime_DateTime *self) 5741{ 5742 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " "); 5743} 5744 5745static PyObject * 5746datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) 5747{ 5748 int sep = 'T'; 5749 char *timespec = NULL; 5750 static char *keywords[] = {"sep", "timespec", NULL}; 5751 char buffer[100]; 5752 PyObject *result = NULL; 5753 int us = DATE_GET_MICROSECOND(self); 5754 static const char *specs[][2] = { 5755 {"hours", "%04d-%02d-%02d%c%02d"}, 5756 {"minutes", "%04d-%02d-%02d%c%02d:%02d"}, 5757 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"}, 5758 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"}, 5759 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"}, 5760 }; 5761 size_t given_spec; 5762 5763 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, ×pec)) 5764 return NULL; 5765 5766 if (timespec == NULL || strcmp(timespec, "auto") == 0) { 5767 if (us == 0) { 5768 /* seconds */ 5769 given_spec = 2; 5770 } 5771 else { 5772 /* microseconds */ 5773 given_spec = 4; 5774 } 5775 } 5776 else { 5777 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) { 5778 if (strcmp(timespec, specs[given_spec][0]) == 0) { 5779 if (given_spec == 3) { 5780 us = us / 1000; 5781 } 5782 break; 5783 } 5784 } 5785 } 5786 5787 if (given_spec == Py_ARRAY_LENGTH(specs)) { 5788 PyErr_Format(PyExc_ValueError, "Unknown timespec value"); 5789 return NULL; 5790 } 5791 else { 5792 result = PyUnicode_FromFormat(specs[given_spec][1], 5793 GET_YEAR(self), GET_MONTH(self), 5794 GET_DAY(self), (int)sep, 5795 DATE_GET_HOUR(self), DATE_GET_MINUTE(self), 5796 DATE_GET_SECOND(self), us); 5797 } 5798 5799 if (!result || !HASTZINFO(self)) 5800 return result; 5801 5802 /* We need to append the UTC offset. */ 5803 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo, 5804 (PyObject *)self) < 0) { 5805 Py_DECREF(result); 5806 return NULL; 5807 } 5808 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer)); 5809 return result; 5810} 5811 5812static PyObject * 5813datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) 5814{ 5815 return format_ctime((PyDateTime_Date *)self, 5816 DATE_GET_HOUR(self), 5817 DATE_GET_MINUTE(self), 5818 DATE_GET_SECOND(self)); 5819} 5820 5821/* Miscellaneous methods. */ 5822 5823static PyObject * 5824flip_fold(PyObject *dt) 5825{ 5826 return new_datetime_ex2(GET_YEAR(dt), 5827 GET_MONTH(dt), 5828 GET_DAY(dt), 5829 DATE_GET_HOUR(dt), 5830 DATE_GET_MINUTE(dt), 5831 DATE_GET_SECOND(dt), 5832 DATE_GET_MICROSECOND(dt), 5833 HASTZINFO(dt) ? 5834 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None, 5835 !DATE_GET_FOLD(dt), 5836 Py_TYPE(dt)); 5837} 5838 5839static PyObject * 5840get_flip_fold_offset(PyObject *dt) 5841{ 5842 PyObject *result, *flip_dt; 5843 5844 flip_dt = flip_fold(dt); 5845 if (flip_dt == NULL) 5846 return NULL; 5847 result = datetime_utcoffset(flip_dt, NULL); 5848 Py_DECREF(flip_dt); 5849 return result; 5850} 5851 5852/* PEP 495 exception: Whenever one or both of the operands in 5853 * inter-zone comparison is such that its utcoffset() depends 5854 * on the value of its fold attribute, the result is False. 5855 * 5856 * Return 1 if exception applies, 0 if not, and -1 on error. 5857 */ 5858static int 5859pep495_eq_exception(PyObject *self, PyObject *other, 5860 PyObject *offset_self, PyObject *offset_other) 5861{ 5862 int result = 0; 5863 PyObject *flip_offset; 5864 5865 flip_offset = get_flip_fold_offset(self); 5866 if (flip_offset == NULL) 5867 return -1; 5868 if (flip_offset != offset_self && 5869 delta_cmp(flip_offset, offset_self)) 5870 { 5871 result = 1; 5872 goto done; 5873 } 5874 Py_DECREF(flip_offset); 5875 5876 flip_offset = get_flip_fold_offset(other); 5877 if (flip_offset == NULL) 5878 return -1; 5879 if (flip_offset != offset_other && 5880 delta_cmp(flip_offset, offset_other)) 5881 result = 1; 5882 done: 5883 Py_DECREF(flip_offset); 5884 return result; 5885} 5886 5887static PyObject * 5888datetime_richcompare(PyObject *self, PyObject *other, int op) 5889{ 5890 PyObject *result = NULL; 5891 PyObject *offset1, *offset2; 5892 int diff; 5893 5894 if (! PyDateTime_Check(other)) { 5895 if (PyDate_Check(other)) { 5896 /* Prevent invocation of date_richcompare. We want to 5897 return NotImplemented here to give the other object 5898 a chance. But since DateTime is a subclass of 5899 Date, if the other object is a Date, it would 5900 compute an ordering based on the date part alone, 5901 and we don't want that. So force unequal or 5902 uncomparable here in that case. */ 5903 if (op == Py_EQ) 5904 Py_RETURN_FALSE; 5905 if (op == Py_NE) 5906 Py_RETURN_TRUE; 5907 return cmperror(self, other); 5908 } 5909 Py_RETURN_NOTIMPLEMENTED; 5910 } 5911 5912 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) { 5913 diff = memcmp(((PyDateTime_DateTime *)self)->data, 5914 ((PyDateTime_DateTime *)other)->data, 5915 _PyDateTime_DATETIME_DATASIZE); 5916 return diff_to_bool(diff, op); 5917 } 5918 offset1 = datetime_utcoffset(self, NULL); 5919 if (offset1 == NULL) 5920 return NULL; 5921 offset2 = datetime_utcoffset(other, NULL); 5922 if (offset2 == NULL) 5923 goto done; 5924 /* If they're both naive, or both aware and have the same offsets, 5925 * we get off cheap. Note that if they're both naive, offset1 == 5926 * offset2 == Py_None at this point. 5927 */ 5928 if ((offset1 == offset2) || 5929 (PyDelta_Check(offset1) && PyDelta_Check(offset2) && 5930 delta_cmp(offset1, offset2) == 0)) { 5931 diff = memcmp(((PyDateTime_DateTime *)self)->data, 5932 ((PyDateTime_DateTime *)other)->data, 5933 _PyDateTime_DATETIME_DATASIZE); 5934 if ((op == Py_EQ || op == Py_NE) && diff == 0) { 5935 int ex = pep495_eq_exception(self, other, offset1, offset2); 5936 if (ex == -1) 5937 goto done; 5938 if (ex) 5939 diff = 1; 5940 } 5941 result = diff_to_bool(diff, op); 5942 } 5943 else if (offset1 != Py_None && offset2 != Py_None) { 5944 PyDateTime_Delta *delta; 5945 5946 assert(offset1 != offset2); /* else last "if" handled it */ 5947 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self, 5948 other); 5949 if (delta == NULL) 5950 goto done; 5951 diff = GET_TD_DAYS(delta); 5952 if (diff == 0) 5953 diff = GET_TD_SECONDS(delta) | 5954 GET_TD_MICROSECONDS(delta); 5955 Py_DECREF(delta); 5956 if ((op == Py_EQ || op == Py_NE) && diff == 0) { 5957 int ex = pep495_eq_exception(self, other, offset1, offset2); 5958 if (ex == -1) 5959 goto done; 5960 if (ex) 5961 diff = 1; 5962 } 5963 result = diff_to_bool(diff, op); 5964 } 5965 else if (op == Py_EQ) { 5966 result = Py_False; 5967 Py_INCREF(result); 5968 } 5969 else if (op == Py_NE) { 5970 result = Py_True; 5971 Py_INCREF(result); 5972 } 5973 else { 5974 PyErr_SetString(PyExc_TypeError, 5975 "can't compare offset-naive and " 5976 "offset-aware datetimes"); 5977 } 5978 done: 5979 Py_DECREF(offset1); 5980 Py_XDECREF(offset2); 5981 return result; 5982} 5983 5984static Py_hash_t 5985datetime_hash(PyDateTime_DateTime *self) 5986{ 5987 if (self->hashcode == -1) { 5988 PyObject *offset, *self0; 5989 if (DATE_GET_FOLD(self)) { 5990 self0 = new_datetime_ex2(GET_YEAR(self), 5991 GET_MONTH(self), 5992 GET_DAY(self), 5993 DATE_GET_HOUR(self), 5994 DATE_GET_MINUTE(self), 5995 DATE_GET_SECOND(self), 5996 DATE_GET_MICROSECOND(self), 5997 HASTZINFO(self) ? self->tzinfo : Py_None, 5998 0, Py_TYPE(self)); 5999 if (self0 == NULL) 6000 return -1; 6001 } 6002 else { 6003 self0 = (PyObject *)self; 6004 Py_INCREF(self0); 6005 } 6006 offset = datetime_utcoffset(self0, NULL); 6007 Py_DECREF(self0); 6008 6009 if (offset == NULL) 6010 return -1; 6011 6012 /* Reduce this to a hash of another object. */ 6013 if (offset == Py_None) 6014 self->hashcode = generic_hash( 6015 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE); 6016 else { 6017 PyObject *temp1, *temp2; 6018 int days, seconds; 6019 6020 assert(HASTZINFO(self)); 6021 days = ymd_to_ord(GET_YEAR(self), 6022 GET_MONTH(self), 6023 GET_DAY(self)); 6024 seconds = DATE_GET_HOUR(self) * 3600 + 6025 DATE_GET_MINUTE(self) * 60 + 6026 DATE_GET_SECOND(self); 6027 temp1 = new_delta(days, seconds, 6028 DATE_GET_MICROSECOND(self), 6029 1); 6030 if (temp1 == NULL) { 6031 Py_DECREF(offset); 6032 return -1; 6033 } 6034 temp2 = delta_subtract(temp1, offset); 6035 Py_DECREF(temp1); 6036 if (temp2 == NULL) { 6037 Py_DECREF(offset); 6038 return -1; 6039 } 6040 self->hashcode = PyObject_Hash(temp2); 6041 Py_DECREF(temp2); 6042 } 6043 Py_DECREF(offset); 6044 } 6045 return self->hashcode; 6046} 6047 6048static PyObject * 6049datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) 6050{ 6051 PyObject *clone; 6052 PyObject *tuple; 6053 int y = GET_YEAR(self); 6054 int m = GET_MONTH(self); 6055 int d = GET_DAY(self); 6056 int hh = DATE_GET_HOUR(self); 6057 int mm = DATE_GET_MINUTE(self); 6058 int ss = DATE_GET_SECOND(self); 6059 int us = DATE_GET_MICROSECOND(self); 6060 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None; 6061 int fold = DATE_GET_FOLD(self); 6062 6063 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace", 6064 datetime_kws, 6065 &y, &m, &d, &hh, &mm, &ss, &us, 6066 &tzinfo, &fold)) 6067 return NULL; 6068 if (fold != 0 && fold != 1) { 6069 PyErr_SetString(PyExc_ValueError, 6070 "fold must be either 0 or 1"); 6071 return NULL; 6072 } 6073 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo); 6074 if (tuple == NULL) 6075 return NULL; 6076 clone = datetime_new(Py_TYPE(self), tuple, NULL); 6077 if (clone != NULL) { 6078 DATE_SET_FOLD(clone, fold); 6079 } 6080 Py_DECREF(tuple); 6081 return clone; 6082} 6083 6084static PyObject * 6085local_timezone_from_timestamp(time_t timestamp) 6086{ 6087 PyObject *result = NULL; 6088 PyObject *delta; 6089 struct tm local_time_tm; 6090 PyObject *nameo = NULL; 6091 const char *zone = NULL; 6092 6093 if (_PyTime_localtime(timestamp, &local_time_tm) != 0) 6094 return NULL; 6095#ifdef HAVE_STRUCT_TM_TM_ZONE 6096 zone = local_time_tm.tm_zone; 6097 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1); 6098#else /* HAVE_STRUCT_TM_TM_ZONE */ 6099 { 6100 PyObject *local_time, *utc_time; 6101 struct tm utc_time_tm; 6102 char buf[100]; 6103 strftime(buf, sizeof(buf), "%Z", &local_time_tm); 6104 zone = buf; 6105 local_time = new_datetime(local_time_tm.tm_year + 1900, 6106 local_time_tm.tm_mon + 1, 6107 local_time_tm.tm_mday, 6108 local_time_tm.tm_hour, 6109 local_time_tm.tm_min, 6110 local_time_tm.tm_sec, 0, Py_None, 0); 6111 if (local_time == NULL) { 6112 return NULL; 6113 } 6114 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0) 6115 return NULL; 6116 utc_time = new_datetime(utc_time_tm.tm_year + 1900, 6117 utc_time_tm.tm_mon + 1, 6118 utc_time_tm.tm_mday, 6119 utc_time_tm.tm_hour, 6120 utc_time_tm.tm_min, 6121 utc_time_tm.tm_sec, 0, Py_None, 0); 6122 if (utc_time == NULL) { 6123 Py_DECREF(local_time); 6124 return NULL; 6125 } 6126 delta = datetime_subtract(local_time, utc_time); 6127 Py_DECREF(local_time); 6128 Py_DECREF(utc_time); 6129 } 6130#endif /* HAVE_STRUCT_TM_TM_ZONE */ 6131 if (delta == NULL) { 6132 return NULL; 6133 } 6134 if (zone != NULL) { 6135 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape"); 6136 if (nameo == NULL) 6137 goto error; 6138 } 6139 result = new_timezone(delta, nameo); 6140 Py_XDECREF(nameo); 6141 error: 6142 Py_DECREF(delta); 6143 return result; 6144} 6145 6146static PyObject * 6147local_timezone(PyDateTime_DateTime *utc_time) 6148{ 6149 time_t timestamp; 6150 PyObject *delta; 6151 PyObject *one_second; 6152 PyObject *seconds; 6153 6154 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch); 6155 if (delta == NULL) 6156 return NULL; 6157 one_second = new_delta(0, 1, 0, 0); 6158 if (one_second == NULL) { 6159 Py_DECREF(delta); 6160 return NULL; 6161 } 6162 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta, 6163 (PyDateTime_Delta *)one_second); 6164 Py_DECREF(one_second); 6165 Py_DECREF(delta); 6166 if (seconds == NULL) 6167 return NULL; 6168 timestamp = _PyLong_AsTime_t(seconds); 6169 Py_DECREF(seconds); 6170 if (timestamp == -1 && PyErr_Occurred()) 6171 return NULL; 6172 return local_timezone_from_timestamp(timestamp); 6173} 6174 6175static long long 6176local_to_seconds(int year, int month, int day, 6177 int hour, int minute, int second, int fold); 6178 6179static PyObject * 6180local_timezone_from_local(PyDateTime_DateTime *local_dt) 6181{ 6182 long long seconds; 6183 time_t timestamp; 6184 seconds = local_to_seconds(GET_YEAR(local_dt), 6185 GET_MONTH(local_dt), 6186 GET_DAY(local_dt), 6187 DATE_GET_HOUR(local_dt), 6188 DATE_GET_MINUTE(local_dt), 6189 DATE_GET_SECOND(local_dt), 6190 DATE_GET_FOLD(local_dt)); 6191 if (seconds == -1) 6192 return NULL; 6193 /* XXX: add bounds check */ 6194 timestamp = seconds - epoch; 6195 return local_timezone_from_timestamp(timestamp); 6196} 6197 6198static PyDateTime_DateTime * 6199datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) 6200{ 6201 PyDateTime_DateTime *result; 6202 PyObject *offset; 6203 PyObject *temp; 6204 PyObject *self_tzinfo; 6205 PyObject *tzinfo = Py_None; 6206 static char *keywords[] = {"tz", NULL}; 6207 6208 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords, 6209 &tzinfo)) 6210 return NULL; 6211 6212 if (check_tzinfo_subclass(tzinfo) == -1) 6213 return NULL; 6214 6215 if (!HASTZINFO(self) || self->tzinfo == Py_None) { 6216 naive: 6217 self_tzinfo = local_timezone_from_local(self); 6218 if (self_tzinfo == NULL) 6219 return NULL; 6220 } else { 6221 self_tzinfo = self->tzinfo; 6222 Py_INCREF(self_tzinfo); 6223 } 6224 6225 /* Conversion to self's own time zone is a NOP. */ 6226 if (self_tzinfo == tzinfo) { 6227 Py_DECREF(self_tzinfo); 6228 Py_INCREF(self); 6229 return self; 6230 } 6231 6232 /* Convert self to UTC. */ 6233 offset = call_utcoffset(self_tzinfo, (PyObject *)self); 6234 Py_DECREF(self_tzinfo); 6235 if (offset == NULL) 6236 return NULL; 6237 else if(offset == Py_None) { 6238 Py_DECREF(offset); 6239 goto naive; 6240 } 6241 else if (!PyDelta_Check(offset)) { 6242 Py_DECREF(offset); 6243 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s," 6244 " expected timedelta or None", Py_TYPE(offset)->tp_name); 6245 return NULL; 6246 } 6247 /* result = self - offset */ 6248 result = (PyDateTime_DateTime *)add_datetime_timedelta(self, 6249 (PyDateTime_Delta *)offset, -1); 6250 Py_DECREF(offset); 6251 if (result == NULL) 6252 return NULL; 6253 6254 /* Make sure result is aware and UTC. */ 6255 if (!HASTZINFO(result)) { 6256 temp = (PyObject *)result; 6257 result = (PyDateTime_DateTime *) 6258 new_datetime_ex2(GET_YEAR(result), 6259 GET_MONTH(result), 6260 GET_DAY(result), 6261 DATE_GET_HOUR(result), 6262 DATE_GET_MINUTE(result), 6263 DATE_GET_SECOND(result), 6264 DATE_GET_MICROSECOND(result), 6265 PyDateTime_TimeZone_UTC, 6266 DATE_GET_FOLD(result), 6267 Py_TYPE(result)); 6268 Py_DECREF(temp); 6269 if (result == NULL) 6270 return NULL; 6271 } 6272 else { 6273 /* Result is already aware - just replace tzinfo. */ 6274 temp = result->tzinfo; 6275 result->tzinfo = PyDateTime_TimeZone_UTC; 6276 Py_INCREF(result->tzinfo); 6277 Py_DECREF(temp); 6278 } 6279 6280 /* Attach new tzinfo and let fromutc() do the rest. */ 6281 temp = result->tzinfo; 6282 if (tzinfo == Py_None) { 6283 tzinfo = local_timezone(result); 6284 if (tzinfo == NULL) { 6285 Py_DECREF(result); 6286 return NULL; 6287 } 6288 } 6289 else 6290 Py_INCREF(tzinfo); 6291 result->tzinfo = tzinfo; 6292 Py_DECREF(temp); 6293 6294 temp = (PyObject *)result; 6295 result = (PyDateTime_DateTime *) 6296 _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp); 6297 Py_DECREF(temp); 6298 6299 return result; 6300} 6301 6302static PyObject * 6303datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) 6304{ 6305 int dstflag = -1; 6306 6307 if (HASTZINFO(self) && self->tzinfo != Py_None) { 6308 PyObject * dst; 6309 6310 dst = call_dst(self->tzinfo, (PyObject *)self); 6311 if (dst == NULL) 6312 return NULL; 6313 6314 if (dst != Py_None) 6315 dstflag = delta_bool((PyDateTime_Delta *)dst); 6316 Py_DECREF(dst); 6317 } 6318 return build_struct_time(GET_YEAR(self), 6319 GET_MONTH(self), 6320 GET_DAY(self), 6321 DATE_GET_HOUR(self), 6322 DATE_GET_MINUTE(self), 6323 DATE_GET_SECOND(self), 6324 dstflag); 6325} 6326 6327static long long 6328local_to_seconds(int year, int month, int day, 6329 int hour, int minute, int second, int fold) 6330{ 6331 long long t, a, b, u1, u2, t1, t2, lt; 6332 t = utc_to_seconds(year, month, day, hour, minute, second); 6333 /* Our goal is to solve t = local(u) for u. */ 6334 lt = local(t); 6335 if (lt == -1) 6336 return -1; 6337 a = lt - t; 6338 u1 = t - a; 6339 t1 = local(u1); 6340 if (t1 == -1) 6341 return -1; 6342 if (t1 == t) { 6343 /* We found one solution, but it may not be the one we need. 6344 * Look for an earlier solution (if `fold` is 0), or a 6345 * later one (if `fold` is 1). */ 6346 if (fold) 6347 u2 = u1 + max_fold_seconds; 6348 else 6349 u2 = u1 - max_fold_seconds; 6350 lt = local(u2); 6351 if (lt == -1) 6352 return -1; 6353 b = lt - u2; 6354 if (a == b) 6355 return u1; 6356 } 6357 else { 6358 b = t1 - u1; 6359 assert(a != b); 6360 } 6361 u2 = t - b; 6362 t2 = local(u2); 6363 if (t2 == -1) 6364 return -1; 6365 if (t2 == t) 6366 return u2; 6367 if (t1 == t) 6368 return u1; 6369 /* We have found both offsets a and b, but neither t - a nor t - b is 6370 * a solution. This means t is in the gap. */ 6371 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2); 6372} 6373 6374/* date(1970,1,1).toordinal() == 719163 */ 6375#define EPOCH_SECONDS (719163LL * 24 * 60 * 60) 6376 6377static PyObject * 6378datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) 6379{ 6380 PyObject *result; 6381 6382 if (HASTZINFO(self) && self->tzinfo != Py_None) { 6383 PyObject *delta; 6384 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch); 6385 if (delta == NULL) 6386 return NULL; 6387 result = delta_total_seconds(delta, NULL); 6388 Py_DECREF(delta); 6389 } 6390 else { 6391 long long seconds; 6392 seconds = local_to_seconds(GET_YEAR(self), 6393 GET_MONTH(self), 6394 GET_DAY(self), 6395 DATE_GET_HOUR(self), 6396 DATE_GET_MINUTE(self), 6397 DATE_GET_SECOND(self), 6398 DATE_GET_FOLD(self)); 6399 if (seconds == -1) 6400 return NULL; 6401 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS + 6402 DATE_GET_MICROSECOND(self) / 1e6); 6403 } 6404 return result; 6405} 6406 6407static PyObject * 6408datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) 6409{ 6410 return new_date(GET_YEAR(self), 6411 GET_MONTH(self), 6412 GET_DAY(self)); 6413} 6414 6415static PyObject * 6416datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) 6417{ 6418 return new_time(DATE_GET_HOUR(self), 6419 DATE_GET_MINUTE(self), 6420 DATE_GET_SECOND(self), 6421 DATE_GET_MICROSECOND(self), 6422 Py_None, 6423 DATE_GET_FOLD(self)); 6424} 6425 6426static PyObject * 6427datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) 6428{ 6429 return new_time(DATE_GET_HOUR(self), 6430 DATE_GET_MINUTE(self), 6431 DATE_GET_SECOND(self), 6432 DATE_GET_MICROSECOND(self), 6433 GET_DT_TZINFO(self), 6434 DATE_GET_FOLD(self)); 6435} 6436 6437static PyObject * 6438datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) 6439{ 6440 int y, m, d, hh, mm, ss; 6441 PyObject *tzinfo; 6442 PyDateTime_DateTime *utcself; 6443 6444 tzinfo = GET_DT_TZINFO(self); 6445 if (tzinfo == Py_None) { 6446 utcself = self; 6447 Py_INCREF(utcself); 6448 } 6449 else { 6450 PyObject *offset; 6451 offset = call_utcoffset(tzinfo, (PyObject *)self); 6452 if (offset == NULL) 6453 return NULL; 6454 if (offset == Py_None) { 6455 Py_DECREF(offset); 6456 utcself = self; 6457 Py_INCREF(utcself); 6458 } 6459 else { 6460 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self, 6461 (PyDateTime_Delta *)offset, -1); 6462 Py_DECREF(offset); 6463 if (utcself == NULL) 6464 return NULL; 6465 } 6466 } 6467 y = GET_YEAR(utcself); 6468 m = GET_MONTH(utcself); 6469 d = GET_DAY(utcself); 6470 hh = DATE_GET_HOUR(utcself); 6471 mm = DATE_GET_MINUTE(utcself); 6472 ss = DATE_GET_SECOND(utcself); 6473 6474 Py_DECREF(utcself); 6475 return build_struct_time(y, m, d, hh, mm, ss, 0); 6476} 6477 6478/* Pickle support, a simple use of __reduce__. */ 6479 6480/* Let basestate be the non-tzinfo data string. 6481 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). 6482 * So it's a tuple in any (non-error) case. 6483 * __getstate__ isn't exposed. 6484 */ 6485static PyObject * 6486datetime_getstate(PyDateTime_DateTime *self, int proto) 6487{ 6488 PyObject *basestate; 6489 PyObject *result = NULL; 6490 6491 basestate = PyBytes_FromStringAndSize((char *)self->data, 6492 _PyDateTime_DATETIME_DATASIZE); 6493 if (basestate != NULL) { 6494 if (proto > 3 && DATE_GET_FOLD(self)) 6495 /* Set the first bit of the third byte */ 6496 PyBytes_AS_STRING(basestate)[2] |= (1 << 7); 6497 if (! HASTZINFO(self) || self->tzinfo == Py_None) 6498 result = PyTuple_Pack(1, basestate); 6499 else 6500 result = PyTuple_Pack(2, basestate, self->tzinfo); 6501 Py_DECREF(basestate); 6502 } 6503 return result; 6504} 6505 6506static PyObject * 6507datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args) 6508{ 6509 int proto; 6510 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto)) 6511 return NULL; 6512 6513 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto)); 6514} 6515 6516static PyObject * 6517datetime_reduce(PyDateTime_DateTime *self, PyObject *arg) 6518{ 6519 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2)); 6520} 6521 6522static PyMethodDef datetime_methods[] = { 6523 6524 /* Class methods: */ 6525 6526 DATETIME_DATETIME_NOW_METHODDEF 6527 6528 {"utcnow", (PyCFunction)datetime_utcnow, 6529 METH_NOARGS | METH_CLASS, 6530 PyDoc_STR("Return a new datetime representing UTC day and time.")}, 6531 6532 {"fromtimestamp", _PyCFunction_CAST(datetime_fromtimestamp), 6533 METH_VARARGS | METH_KEYWORDS | METH_CLASS, 6534 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")}, 6535 6536 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp, 6537 METH_VARARGS | METH_CLASS, 6538 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")}, 6539 6540 {"strptime", (PyCFunction)datetime_strptime, 6541 METH_VARARGS | METH_CLASS, 6542 PyDoc_STR("string, format -> new datetime parsed from a string " 6543 "(like time.strptime()).")}, 6544 6545 {"combine", _PyCFunction_CAST(datetime_combine), 6546 METH_VARARGS | METH_KEYWORDS | METH_CLASS, 6547 PyDoc_STR("date, time -> datetime with same date and time fields")}, 6548 6549 {"fromisoformat", (PyCFunction)datetime_fromisoformat, 6550 METH_O | METH_CLASS, 6551 PyDoc_STR("string -> datetime from a string in most ISO 8601 formats")}, 6552 6553 /* Instance methods: */ 6554 6555 {"date", (PyCFunction)datetime_getdate, METH_NOARGS, 6556 PyDoc_STR("Return date object with same year, month and day.")}, 6557 6558 {"time", (PyCFunction)datetime_gettime, METH_NOARGS, 6559 PyDoc_STR("Return time object with same time but with tzinfo=None.")}, 6560 6561 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS, 6562 PyDoc_STR("Return time object with same time and tzinfo.")}, 6563 6564 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS, 6565 PyDoc_STR("Return ctime() style string.")}, 6566 6567 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS, 6568 PyDoc_STR("Return time tuple, compatible with time.localtime().")}, 6569 6570 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS, 6571 PyDoc_STR("Return POSIX timestamp as float.")}, 6572 6573 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS, 6574 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")}, 6575 6576 {"isoformat", _PyCFunction_CAST(datetime_isoformat), METH_VARARGS | METH_KEYWORDS, 6577 PyDoc_STR("[sep] -> string in ISO 8601 format, " 6578 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n" 6579 "sep is used to separate the year from the time, and " 6580 "defaults to 'T'.\n" 6581 "The optional argument timespec specifies the number " 6582 "of additional terms\nof the time to include. Valid " 6583 "options are 'auto', 'hours', 'minutes',\n'seconds', " 6584 "'milliseconds' and 'microseconds'.\n")}, 6585 6586 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS, 6587 PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, 6588 6589 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS, 6590 PyDoc_STR("Return self.tzinfo.tzname(self).")}, 6591 6592 {"dst", (PyCFunction)datetime_dst, METH_NOARGS, 6593 PyDoc_STR("Return self.tzinfo.dst(self).")}, 6594 6595 {"replace", _PyCFunction_CAST(datetime_replace), METH_VARARGS | METH_KEYWORDS, 6596 PyDoc_STR("Return datetime with new specified fields.")}, 6597 6598 {"astimezone", _PyCFunction_CAST(datetime_astimezone), METH_VARARGS | METH_KEYWORDS, 6599 PyDoc_STR("tz -> convert to local time in new timezone tz\n")}, 6600 6601 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS, 6602 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")}, 6603 6604 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS, 6605 PyDoc_STR("__reduce__() -> (cls, state)")}, 6606 6607 {NULL, NULL} 6608}; 6609 6610static const char datetime_doc[] = 6611PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\ 6612\n\ 6613The year, month and day arguments are required. tzinfo may be None, or an\n\ 6614instance of a tzinfo subclass. The remaining arguments may be ints.\n"); 6615 6616static PyNumberMethods datetime_as_number = { 6617 datetime_add, /* nb_add */ 6618 datetime_subtract, /* nb_subtract */ 6619 0, /* nb_multiply */ 6620 0, /* nb_remainder */ 6621 0, /* nb_divmod */ 6622 0, /* nb_power */ 6623 0, /* nb_negative */ 6624 0, /* nb_positive */ 6625 0, /* nb_absolute */ 6626 0, /* nb_bool */ 6627}; 6628 6629static PyTypeObject PyDateTime_DateTimeType = { 6630 PyVarObject_HEAD_INIT(NULL, 0) 6631 "datetime.datetime", /* tp_name */ 6632 sizeof(PyDateTime_DateTime), /* tp_basicsize */ 6633 0, /* tp_itemsize */ 6634 (destructor)datetime_dealloc, /* tp_dealloc */ 6635 0, /* tp_vectorcall_offset */ 6636 0, /* tp_getattr */ 6637 0, /* tp_setattr */ 6638 0, /* tp_as_async */ 6639 (reprfunc)datetime_repr, /* tp_repr */ 6640 &datetime_as_number, /* tp_as_number */ 6641 0, /* tp_as_sequence */ 6642 0, /* tp_as_mapping */ 6643 (hashfunc)datetime_hash, /* tp_hash */ 6644 0, /* tp_call */ 6645 (reprfunc)datetime_str, /* tp_str */ 6646 PyObject_GenericGetAttr, /* tp_getattro */ 6647 0, /* tp_setattro */ 6648 0, /* tp_as_buffer */ 6649 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 6650 datetime_doc, /* tp_doc */ 6651 0, /* tp_traverse */ 6652 0, /* tp_clear */ 6653 datetime_richcompare, /* tp_richcompare */ 6654 0, /* tp_weaklistoffset */ 6655 0, /* tp_iter */ 6656 0, /* tp_iternext */ 6657 datetime_methods, /* tp_methods */ 6658 0, /* tp_members */ 6659 datetime_getset, /* tp_getset */ 6660 0, /* tp_base; filled in 6661 PyInit__datetime */ 6662 0, /* tp_dict */ 6663 0, /* tp_descr_get */ 6664 0, /* tp_descr_set */ 6665 0, /* tp_dictoffset */ 6666 0, /* tp_init */ 6667 datetime_alloc, /* tp_alloc */ 6668 datetime_new, /* tp_new */ 6669 0, /* tp_free */ 6670}; 6671 6672/* --------------------------------------------------------------------------- 6673 * Module methods and initialization. 6674 */ 6675 6676static PyMethodDef module_methods[] = { 6677 {NULL, NULL} 6678}; 6679 6680/* Get a new C API by calling this function. 6681 * Clients get at C API via PyDateTime_IMPORT, defined in datetime.h. 6682 */ 6683static inline PyDateTime_CAPI * 6684get_datetime_capi(void) 6685{ 6686 PyDateTime_CAPI *capi = PyMem_Malloc(sizeof(PyDateTime_CAPI)); 6687 if (capi == NULL) { 6688 PyErr_NoMemory(); 6689 return NULL; 6690 } 6691 capi->DateType = &PyDateTime_DateType; 6692 capi->DateTimeType = &PyDateTime_DateTimeType; 6693 capi->TimeType = &PyDateTime_TimeType; 6694 capi->DeltaType = &PyDateTime_DeltaType; 6695 capi->TZInfoType = &PyDateTime_TZInfoType; 6696 capi->Date_FromDate = new_date_ex; 6697 capi->DateTime_FromDateAndTime = new_datetime_ex; 6698 capi->Time_FromTime = new_time_ex; 6699 capi->Delta_FromDelta = new_delta_ex; 6700 capi->TimeZone_FromTimeZone = new_timezone; 6701 capi->DateTime_FromTimestamp = datetime_fromtimestamp; 6702 capi->Date_FromTimestamp = datetime_date_fromtimestamp_capi; 6703 capi->DateTime_FromDateAndTimeAndFold = new_datetime_ex2; 6704 capi->Time_FromTimeAndFold = new_time_ex2; 6705 // Make sure this function is called after PyDateTime_TimeZone_UTC has 6706 // been initialized. 6707 assert(PyDateTime_TimeZone_UTC != NULL); 6708 capi->TimeZone_UTC = PyDateTime_TimeZone_UTC; // borrowed ref 6709 return capi; 6710} 6711 6712static void 6713datetime_destructor(PyObject *op) 6714{ 6715 void *ptr = PyCapsule_GetPointer(op, PyDateTime_CAPSULE_NAME); 6716 PyMem_Free(ptr); 6717} 6718 6719static int 6720_datetime_exec(PyObject *module) 6721{ 6722 // `&...` is not a constant expression according to a strict reading 6723 // of C standards. Fill tp_base at run-time rather than statically. 6724 // See https://bugs.python.org/issue40777 6725 PyDateTime_IsoCalendarDateType.tp_base = &PyTuple_Type; 6726 PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType; 6727 PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType; 6728 6729 PyTypeObject *types[] = { 6730 &PyDateTime_DateType, 6731 &PyDateTime_DateTimeType, 6732 &PyDateTime_TimeType, 6733 &PyDateTime_DeltaType, 6734 &PyDateTime_TZInfoType, 6735 &PyDateTime_TimeZoneType, 6736 }; 6737 6738 for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { 6739 if (PyModule_AddType(module, types[i]) < 0) { 6740 return -1; 6741 } 6742 } 6743 6744 if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) { 6745 return -1; 6746 } 6747 6748#define DATETIME_ADD_MACRO(dict, c, value_expr) \ 6749 do { \ 6750 PyObject *value = (value_expr); \ 6751 if (value == NULL) { \ 6752 return -1; \ 6753 } \ 6754 if (PyDict_SetItemString(dict, c, value) < 0) { \ 6755 Py_DECREF(value); \ 6756 return -1; \ 6757 } \ 6758 Py_DECREF(value); \ 6759 } while(0) 6760 6761 /* timedelta values */ 6762 PyObject *d = PyDateTime_DeltaType.tp_dict; 6763 DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); 6764 DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0)); 6765 DATETIME_ADD_MACRO(d, "max", 6766 new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0)); 6767 6768 /* date values */ 6769 d = PyDateTime_DateType.tp_dict; 6770 DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1)); 6771 DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31)); 6772 DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0)); 6773 6774 /* time values */ 6775 d = PyDateTime_TimeType.tp_dict; 6776 DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0)); 6777 DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0)); 6778 DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); 6779 6780 /* datetime values */ 6781 d = PyDateTime_DateTimeType.tp_dict; 6782 DATETIME_ADD_MACRO(d, "min", 6783 new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0)); 6784 DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 6785 999999, Py_None, 0)); 6786 DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); 6787 6788 /* timezone values */ 6789 d = PyDateTime_TimeZoneType.tp_dict; 6790 PyObject *delta = new_delta(0, 0, 0, 0); 6791 if (delta == NULL) { 6792 return -1; 6793 } 6794 6795 PyObject *x = create_timezone(delta, NULL); 6796 Py_DECREF(delta); 6797 if (x == NULL) { 6798 return -1; 6799 } 6800 if (PyDict_SetItemString(d, "utc", x) < 0) { 6801 Py_DECREF(x); 6802 return -1; 6803 } 6804 6805 PyDateTime_TimeZone_UTC = x; 6806 6807 /* bpo-37642: These attributes are rounded to the nearest minute for backwards 6808 * compatibility, even though the constructor will accept a wider range of 6809 * values. This may change in the future.*/ 6810 delta = new_delta(-1, 60, 0, 1); /* -23:59 */ 6811 if (delta == NULL) { 6812 return -1; 6813 } 6814 6815 x = create_timezone(delta, NULL); 6816 Py_DECREF(delta); 6817 DATETIME_ADD_MACRO(d, "min", x); 6818 6819 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */ 6820 if (delta == NULL) { 6821 return -1; 6822 } 6823 6824 x = create_timezone(delta, NULL); 6825 Py_DECREF(delta); 6826 DATETIME_ADD_MACRO(d, "max", x); 6827 6828 /* Epoch */ 6829 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0, 6830 PyDateTime_TimeZone_UTC, 0); 6831 if (PyDateTime_Epoch == NULL) { 6832 return -1; 6833 } 6834 6835 /* module initialization */ 6836 if (PyModule_AddIntMacro(module, MINYEAR) < 0) { 6837 return -1; 6838 } 6839 if (PyModule_AddIntMacro(module, MAXYEAR) < 0) { 6840 return -1; 6841 } 6842 6843 PyDateTime_CAPI *capi = get_datetime_capi(); 6844 if (capi == NULL) { 6845 return -1; 6846 } 6847 x = PyCapsule_New(capi, PyDateTime_CAPSULE_NAME, datetime_destructor); 6848 if (x == NULL) { 6849 PyMem_Free(capi); 6850 return -1; 6851 } 6852 6853 if (PyModule_AddObject(module, "datetime_CAPI", x) < 0) { 6854 Py_DECREF(x); 6855 return -1; 6856 } 6857 6858 if (PyModule_AddObjectRef(module, "UTC", PyDateTime_TimeZone_UTC) < 0) { 6859 return -1; 6860 } 6861 6862 /* A 4-year cycle has an extra leap day over what we'd get from 6863 * pasting together 4 single years. 6864 */ 6865 static_assert(DI4Y == 4 * 365 + 1, "DI4Y"); 6866 assert(DI4Y == days_before_year(4+1)); 6867 6868 /* Similarly, a 400-year cycle has an extra leap day over what we'd 6869 * get from pasting together 4 100-year cycles. 6870 */ 6871 static_assert(DI400Y == 4 * DI100Y + 1, "DI400Y"); 6872 assert(DI400Y == days_before_year(400+1)); 6873 6874 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from 6875 * pasting together 25 4-year cycles. 6876 */ 6877 static_assert(DI100Y == 25 * DI4Y - 1, "DI100Y"); 6878 assert(DI100Y == days_before_year(100+1)); 6879 6880 us_per_ms = PyLong_FromLong(1000); 6881 us_per_second = PyLong_FromLong(1000000); 6882 us_per_minute = PyLong_FromLong(60000000); 6883 seconds_per_day = PyLong_FromLong(24 * 3600); 6884 if (us_per_ms == NULL || us_per_second == NULL || 6885 us_per_minute == NULL || seconds_per_day == NULL) { 6886 return -1; 6887 } 6888 6889 /* The rest are too big for 32-bit ints, but even 6890 * us_per_week fits in 40 bits, so doubles should be exact. 6891 */ 6892 us_per_hour = PyLong_FromDouble(3600000000.0); 6893 us_per_day = PyLong_FromDouble(86400000000.0); 6894 us_per_week = PyLong_FromDouble(604800000000.0); 6895 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) { 6896 return -1; 6897 } 6898 return 0; 6899} 6900 6901static struct PyModuleDef datetimemodule = { 6902 PyModuleDef_HEAD_INIT, 6903 .m_name = "_datetime", 6904 .m_doc = "Fast implementation of the datetime type.", 6905 .m_size = -1, 6906 .m_methods = module_methods, 6907}; 6908 6909PyMODINIT_FUNC 6910PyInit__datetime(void) 6911{ 6912 PyObject *mod = PyModule_Create(&datetimemodule); 6913 if (mod == NULL) 6914 return NULL; 6915 6916 if (_datetime_exec(mod) < 0) { 6917 Py_DECREF(mod); 6918 return NULL; 6919 } 6920 6921 return mod; 6922} 6923 6924/* --------------------------------------------------------------------------- 6925Some time zone algebra. For a datetime x, let 6926 x.n = x stripped of its timezone -- its naive time. 6927 x.o = x.utcoffset(), and assuming that doesn't raise an exception or 6928 return None 6929 x.d = x.dst(), and assuming that doesn't raise an exception or 6930 return None 6931 x.s = x's standard offset, x.o - x.d 6932 6933Now some derived rules, where k is a duration (timedelta). 6934 69351. x.o = x.s + x.d 6936 This follows from the definition of x.s. 6937 69382. If x and y have the same tzinfo member, x.s = y.s. 6939 This is actually a requirement, an assumption we need to make about 6940 sane tzinfo classes. 6941 69423. The naive UTC time corresponding to x is x.n - x.o. 6943 This is again a requirement for a sane tzinfo class. 6944 69454. (x+k).s = x.s 6946 This follows from #2, and that datimetimetz+timedelta preserves tzinfo. 6947 69485. (x+k).n = x.n + k 6949 Again follows from how arithmetic is defined. 6950 6951Now we can explain tz.fromutc(x). Let's assume it's an interesting case 6952(meaning that the various tzinfo methods exist, and don't blow up or return 6953None when called). 6954 6955The function wants to return a datetime y with timezone tz, equivalent to x. 6956x is already in UTC. 6957 6958By #3, we want 6959 6960 y.n - y.o = x.n [1] 6961 6962The algorithm starts by attaching tz to x.n, and calling that y. So 6963x.n = y.n at the start. Then it wants to add a duration k to y, so that [1] 6964becomes true; in effect, we want to solve [2] for k: 6965 6966 (y+k).n - (y+k).o = x.n [2] 6967 6968By #1, this is the same as 6969 6970 (y+k).n - ((y+k).s + (y+k).d) = x.n [3] 6971 6972By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. 6973Substituting that into [3], 6974 6975 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving 6976 k - (y+k).s - (y+k).d = 0; rearranging, 6977 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so 6978 k = y.s - (y+k).d 6979 6980On the RHS, (y+k).d can't be computed directly, but y.s can be, and we 6981approximate k by ignoring the (y+k).d term at first. Note that k can't be 6982very large, since all offset-returning methods return a duration of magnitude 6983less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must 6984be 0, so ignoring it has no consequence then. 6985 6986In any case, the new value is 6987 6988 z = y + y.s [4] 6989 6990It's helpful to step back at look at [4] from a higher level: it's simply 6991mapping from UTC to tz's standard time. 6992 6993At this point, if 6994 6995 z.n - z.o = x.n [5] 6996 6997we have an equivalent time, and are almost done. The insecurity here is 6998at the start of daylight time. Picture US Eastern for concreteness. The wall 6999time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good 7000sense then. The docs ask that an Eastern tzinfo class consider such a time to 7001be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST 7002on the day DST starts. We want to return the 1:MM EST spelling because that's 7003the only spelling that makes sense on the local wall clock. 7004 7005In fact, if [5] holds at this point, we do have the standard-time spelling, 7006but that takes a bit of proof. We first prove a stronger result. What's the 7007difference between the LHS and RHS of [5]? Let 7008 7009 diff = x.n - (z.n - z.o) [6] 7010 7011Now 7012 z.n = by [4] 7013 (y + y.s).n = by #5 7014 y.n + y.s = since y.n = x.n 7015 x.n + y.s = since z and y are have the same tzinfo member, 7016 y.s = z.s by #2 7017 x.n + z.s 7018 7019Plugging that back into [6] gives 7020 7021 diff = 7022 x.n - ((x.n + z.s) - z.o) = expanding 7023 x.n - x.n - z.s + z.o = cancelling 7024 - z.s + z.o = by #2 7025 z.d 7026 7027So diff = z.d. 7028 7029If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time 7030spelling we wanted in the endcase described above. We're done. Contrarily, 7031if z.d = 0, then we have a UTC equivalent, and are also done. 7032 7033If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to 7034add to z (in effect, z is in tz's standard time, and we need to shift the 7035local clock into tz's daylight time). 7036 7037Let 7038 7039 z' = z + z.d = z + diff [7] 7040 7041and we can again ask whether 7042 7043 z'.n - z'.o = x.n [8] 7044 7045If so, we're done. If not, the tzinfo class is insane, according to the 7046assumptions we've made. This also requires a bit of proof. As before, let's 7047compute the difference between the LHS and RHS of [8] (and skipping some of 7048the justifications for the kinds of substitutions we've done several times 7049already): 7050 7051 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7] 7052 x.n - (z.n + diff - z'.o) = replacing diff via [6] 7053 x.n - (z.n + x.n - (z.n - z.o) - z'.o) = 7054 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n 7055 - z.n + z.n - z.o + z'.o = cancel z.n 7056 - z.o + z'.o = #1 twice 7057 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo 7058 z'.d - z.d 7059 7060So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, 7061we've found the UTC-equivalent so are done. In fact, we stop with [7] and 7062return z', not bothering to compute z'.d. 7063 7064How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by 7065a dst() offset, and starting *from* a time already in DST (we know z.d != 0), 7066would have to change the result dst() returns: we start in DST, and moving 7067a little further into it takes us out of DST. 7068 7069There isn't a sane case where this can happen. The closest it gets is at 7070the end of DST, where there's an hour in UTC with no spelling in a hybrid 7071tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During 7072that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM 7073UTC) because the docs insist on that, but 0:MM is taken as being in daylight 7074time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local 7075clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in 7076standard time. Since that's what the local clock *does*, we want to map both 7077UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous 7078in local time, but so it goes -- it's the way the local clock works. 7079 7080When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, 7081so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. 7082z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] 7083(correctly) concludes that z' is not UTC-equivalent to x. 7084 7085Because we know z.d said z was in daylight time (else [5] would have held and 7086we would have stopped then), and we know z.d != z'.d (else [8] would have held 7087and we would have stopped then), and there are only 2 possible values dst() can 7088return in Eastern, it follows that z'.d must be 0 (which it is in the example, 7089but the reasoning doesn't depend on the example -- it depends on there being 7090two possible dst() outcomes, one zero and the other non-zero). Therefore 7091z' must be in standard time, and is the spelling we want in this case. 7092 7093Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is 7094concerned (because it takes z' as being in standard time rather than the 7095daylight time we intend here), but returning it gives the real-life "local 7096clock repeats an hour" behavior when mapping the "unspellable" UTC hour into 7097tz. 7098 7099When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with 7100the 1:MM standard time spelling we want. 7101 7102So how can this break? One of the assumptions must be violated. Two 7103possibilities: 7104 71051) [2] effectively says that y.s is invariant across all y belong to a given 7106 time zone. This isn't true if, for political reasons or continental drift, 7107 a region decides to change its base offset from UTC. 7108 71092) There may be versions of "double daylight" time where the tail end of 7110 the analysis gives up a step too early. I haven't thought about that 7111 enough to say. 7112 7113In any case, it's clear that the default fromutc() is strong enough to handle 7114"almost all" time zones: so long as the standard offset is invariant, it 7115doesn't matter if daylight time transition points change from year to year, or 7116if daylight time is skipped in some years; it doesn't matter how large or 7117small dst() may get within its bounds; and it doesn't even matter if some 7118perverse time zone returns a negative dst()). So a breaking case must be 7119pretty bizarre, and a tzinfo subclass can override fromutc() if it is. 7120--------------------------------------------------------------------------- */ 7121