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