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