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, µseconds);
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", ×tamp))
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, ×pec))
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, µsecond,
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, ×tamp, &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", ×tamp))
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 µsecond, &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, µsecond) < 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, ×pec))
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