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