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