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