blob: 41c3f34269ddc67427d7758b8161cf66d38d5d22 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
Paul Ganssle0d126722018-11-13 03:02:25 -05005/* 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
Tim Peters2a799bf2002-12-16 20:18:38 +000010#include "Python.h"
Paul Ganssle0d126722018-11-13 03:02:25 -050011#include "datetime.h"
Tim Peters2a799bf2002-12-16 20:18:38 +000012#include "structmember.h"
13
14#include <time.h>
15
Victor Stinner09e5cf22015-03-30 00:09:18 +020016#ifdef MS_WINDOWS
17# include <winsock2.h> /* struct timeval */
18#endif
19
Paul Ganssle0d126722018-11-13 03:02:25 -050020#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
Miss Islington (bot)5c777302019-08-23 01:48:40 -070035#define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType)
Tim Peters2a799bf2002-12-16 20:18:38 +000036
Larry Hastings61272b72014-01-07 12:41:53 -080037/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080038module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080039class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +020040class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType"
Larry Hastings61272b72014-01-07 12:41:53 -080041[clinic start generated code]*/
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +020042/*[clinic end generated code: output=da39a3ee5e6b4b0d input=25138ad6a696b785]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080043
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030044#include "clinic/_datetimemodule.c.h"
45
Tim Peters2a799bf2002-12-16 20:18:38 +000046/* 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
Alexander Belopolskycf86e362010-07-23 19:25:47 +000052# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000053#endif
54
55#define MINYEAR 1
56#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000057#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000058
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. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067#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
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040074#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000075
76/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077#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))
Tim Peters2a799bf2002-12-16 20:18:38 +000081
82/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083#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)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040090#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000091
92/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093#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
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040097#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098#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)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400105#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000106
107/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108#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)
Tim Peters2a799bf2002-12-16 20:18:38 +0000111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112#define SET_TD_DAYS(o, v) ((o)->days = (v))
113#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000114#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
115
Tim Petersa032d2e2003-01-11 00:15:54 +0000116/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
117 * p->hastzinfo.
118 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000119#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)
Tim Peters3f606292004-03-21 23:38:41 +0000124/* M is a char or int claiming to be a valid month. The macro is equivalent
125 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000127 */
128#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
129
Tim Peters2a799bf2002-12-16 20:18:38 +0000130/* Forward declarations. */
131static PyTypeObject PyDateTime_DateType;
132static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000133static PyTypeObject PyDateTime_DeltaType;
134static PyTypeObject PyDateTime_TimeType;
135static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000136static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000137
Victor Stinnerb67f0962017-02-10 10:34:02 +0100138static int check_tzinfo_subclass(PyObject *p);
139
Martin v. Löwise75fc142013-11-07 18:46:53 +0100140_Py_IDENTIFIER(as_integer_ratio);
141_Py_IDENTIFIER(fromutc);
142_Py_IDENTIFIER(isoformat);
143_Py_IDENTIFIER(strftime);
144
Tim Peters2a799bf2002-12-16 20:18:38 +0000145/* ---------------------------------------------------------------------------
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) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000155
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 */
165static int
166divmod(int x, int y, int *r)
167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 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;
Tim Peters2a799bf2002-12-16 20:18:38 +0000179}
180
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000181/* Nearest integer to m / n for integers m and n. Half-integer results
182 * are rounded to even.
183 */
184static PyObject *
185divide_nearest(PyObject *m, PyObject *n)
186{
187 PyObject *result;
188 PyObject *temp;
189
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000190 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000191 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
Tim Peters2a799bf2002-12-16 20:18:38 +0000200/* ---------------------------------------------------------------------------
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 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200208static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 0, /* unused; this vector uses 1-based indexing */
210 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000211};
212
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200213static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 0, /* unused; this vector uses 1-based indexing */
215 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000216};
217
218/* year -> 1 if leap year, else 0. */
219static int
220is_leap(int year)
221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 /* 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);
Tim Peters2a799bf2002-12-16 20:18:38 +0000229}
230
231/* year, month -> number of days in that month in that year */
232static int
233days_in_month(int year, int month)
234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 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];
Tim Peters2a799bf2002-12-16 20:18:38 +0000241}
242
Martin Panter46f50722016-05-26 05:35:26 +0000243/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000244static int
245days_before_month(int year, int month)
246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 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;
Tim Peters2a799bf2002-12-16 20:18:38 +0000255}
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 */
260static int
261days_before_year(int year)
262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 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
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000266 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000268 assert (year >= 1);
269 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000270}
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 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275#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 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000278
279/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
280static void
281ord_to_ymd(int ordinal, int *year, int *month, int *day)
282{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +0000322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 /* Now compute how many 4-year cycles precede it. */
324 n4 = n / DI4Y;
325 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +0000333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 *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 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 /* 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));
Tim Peters2a799bf2002-12-16 20:18:38 +0000359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000361}
362
363/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
364static int
365ymd_to_ord(int year, int month, int day)
366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000368}
369
370/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
371static int
372weekday(int year, int month, int day)
373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000375}
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 */
380static int
381iso_week1_monday(int year)
382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000383 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;
Tim Peters2a799bf2002-12-16 20:18:38 +0000388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
390 week1_monday += 7;
391 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000392}
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 */
401static int
402check_delta_day_range(int days)
403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 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;
Tim Peters2a799bf2002-12-16 20:18:38 +0000410}
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 */
415static int
416check_date_args(int year, int month, int day)
417{
418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 if (year < MINYEAR || year > MAXYEAR) {
Victor Stinnerb67f0962017-02-10 10:34:02 +0100420 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 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;
Tim Peters2a799bf2002-12-16 20:18:38 +0000434}
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 */
439static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400440check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000441{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 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 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400462 if (fold != 0 && fold != 1) {
463 PyErr_SetString(PyExc_ValueError,
464 "fold must be either 0 or 1");
465 return -1;
466 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000468}
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 */
480static void
481normalize_pair(int *hi, int *lo, int factor)
482{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 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);
Tim Peters2a799bf2002-12-16 20:18:38 +0000492}
493
494/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 * 0 <= *s < 24*3600
496 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000497 * 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 */
500static void
501normalize_d_s_us(int *d, int *s, int *us)
502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 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 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 }
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);
Tim Peters2a799bf2002-12-16 20:18:38 +0000519}
520
521/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 * 1 <= *m <= 12
523 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000524 * 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 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000527static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000528normalize_y_m_d(int *y, int *m, int *d)
529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000531
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000532 /* In actual use, m is always the month component extracted from a
533 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 /* 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;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000571 if (ordinal < 1 || ordinal > MAXORDINAL) {
572 goto error;
573 } else {
574 ord_to_ymd(ordinal, y, m, d);
575 return 0;
576 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 }
578 }
579 assert(*m > 0);
580 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000581 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
Tim Peters2a799bf2002-12-16 20:18:38 +0000588}
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 */
594static int
595normalize_date(int *year, int *month, int *day)
596{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000597 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000598}
599
600/* Force all the datetime fields into range. The parameters are both
601 * inputs and outputs. Returns < 0 on error.
602 */
603static int
604normalize_datetime(int *year, int *month, int *day,
605 int *hour, int *minute, int *second,
606 int *microsecond)
607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 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);
Tim Peters2a799bf2002-12-16 20:18:38 +0000613}
614
615/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000616 * 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
Tim Peters03eaf8b2003-05-18 02:24:46 +0000622 * 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).
Tim Petersb0c854d2003-05-17 15:57:00 +0000634 */
635
636static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000637time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 self = (PyObject *)
642 PyObject_MALLOC(aware ?
643 sizeof(PyDateTime_Time) :
644 sizeof(_PyDateTime_BaseTime));
645 if (self == NULL)
646 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100647 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000649}
650
651static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000652datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 self = (PyObject *)
657 PyObject_MALLOC(aware ?
658 sizeof(PyDateTime_DateTime) :
659 sizeof(_PyDateTime_BaseDateTime));
660 if (self == NULL)
661 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100662 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000664}
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. */
672static void
673set_date_fields(PyDateTime_Date *self, int y, int m, int d)
674{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 self->hashcode = -1;
676 SET_YEAR(self, y);
677 SET_MONTH(self, m);
678 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000679}
680
681/* ---------------------------------------------------------------------------
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500682 * String parsing utilities and helper functions
683 */
684
Paul Ganssle3df85402018-10-22 12:32:52 -0400685static const char *
686parse_digits(const char *ptr, int *var, size_t num_digits)
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500687{
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
Paul Ganssle3df85402018-10-22 12:32:52 -0400700static int
701parse_isoformat_date(const char *dtstr, int *year, int *month, int *day)
702{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500703 /* Parse the date components of the result of date.isoformat()
Paul Ganssle3df85402018-10-22 12:32:52 -0400704 *
705 * Return codes:
706 * 0: Success
707 * -1: Failed to parse date component
708 * -2: Failed to parse dateseparator
709 */
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500710 const char *p = dtstr;
711 p = parse_digits(p, year, 4);
712 if (NULL == p) {
713 return -1;
714 }
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100715
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500716 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
737static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400738parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
739 int *minute, int *second, int *microsecond)
740{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500741 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';
Paul Ganssle3df85402018-10-22 12:32:52 -0400755 }
756 else if (c == ':') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500757 continue;
Paul Ganssle3df85402018-10-22 12:32:52 -0400758 }
759 else if (c == '.') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500760 break;
Paul Ganssle3df85402018-10-22 12:32:52 -0400761 }
762 else {
763 return -4; // Malformed time separator
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500764 }
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
786static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400787parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
788 int *second, int *microsecond, int *tzoffset,
789 int *tzmicrosecond)
790{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500791 // 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 }
Paul Ganssle3df85402018-10-22 12:32:52 -0400808 } while (++tzinfo_pos < p_end);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500809
Paul Ganssle3df85402018-10-22 12:32:52 -0400810 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second,
811 microsecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500812
813 if (rv < 0) {
814 return rv;
Paul Ganssle3df85402018-10-22 12:32:52 -0400815 }
816 else if (tzinfo_pos == p_end) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500817 // 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;
Paul Ganssle3df85402018-10-22 12:32:52 -0400821 }
822 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500823 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
Paul Ganssle3df85402018-10-22 12:32:52 -0400837 int tzsign = (*tzinfo_pos == '-') ? -1 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500838 tzinfo_pos++;
839 int tzhour = 0, tzminute = 0, tzsecond = 0;
Paul Ganssle3df85402018-10-22 12:32:52 -0400840 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond,
841 tzmicrosecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500842
843 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
844 *tzmicrosecond *= tzsign;
845
Paul Ganssle3df85402018-10-22 12:32:52 -0400846 return rv ? -5 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500847}
848
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500849/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000850 * Create various objects, mostly without range checking.
851 */
852
853/* Create a date instance with no range checking. */
854static PyObject *
855new_date_ex(int year, int month, int day, PyTypeObject *type)
856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000858
Victor Stinnerb67f0962017-02-10 10:34:02 +0100859 if (check_date_args(year, month, day) < 0) {
860 return NULL;
861 }
862
Paul Ganssle3df85402018-10-22 12:32:52 -0400863 self = (PyDateTime_Date *)(type->tp_alloc(type, 0));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 if (self != NULL)
865 set_date_fields(self, year, month, day);
Paul Ganssle3df85402018-10-22 12:32:52 -0400866 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000867}
868
869#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000871
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500872// Forward declaration
Paul Ganssle3df85402018-10-22 12:32:52 -0400873static PyObject *
874new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500875
876/* Create date instance with no range checking, or call subclass constructor */
877static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -0400878new_date_subclass_ex(int year, int month, int day, PyObject *cls)
879{
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500880 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);
Paul Ganssle3df85402018-10-22 12:32:52 -0400884 }
885 else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500886 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
887 (PyTypeObject *)cls);
Paul Ganssle3df85402018-10-22 12:32:52 -0400888 }
889 else {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500890 result = PyObject_CallFunction(cls, "iii", year, month, day);
891 }
892
893 return result;
894}
895
Tim Petersb0c854d2003-05-17 15:57:00 +0000896/* Create a datetime instance with no range checking. */
897static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400898new_datetime_ex2(int year, int month, int day, int hour, int minute,
899 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000900{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 PyDateTime_DateTime *self;
902 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000903
Victor Stinnerb67f0962017-02-10 10:34:02 +0100904 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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 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 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400926 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 }
928 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000929}
930
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400931static PyObject *
932new_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, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000942
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500943static PyObject *
944new_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
968static PyObject *
969new_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
Tim Petersb0c854d2003-05-17 15:57:00 +0000977/* Create a time instance with no range checking. */
978static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400979new_time_ex2(int hour, int minute, int second, int usecond,
980 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 PyDateTime_Time *self;
983 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000984
Victor Stinnerb67f0962017-02-10 10:34:02 +0100985 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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 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 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001004 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 }
1006 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001007}
1008
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001009static PyObject *
1010new_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)
Tim Petersb0c854d2003-05-17 15:57:00 +00001018
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 */
1025static PyObject *
1026new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +00001028{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 if (normalize)
1032 normalize_d_s_us(&days, &seconds, &microseconds);
1033 assert(0 <= seconds && seconds < 24*3600);
1034 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +00001035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 if (check_delta_day_range(days) < 0)
1037 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 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;
Tim Petersb0c854d2003-05-17 15:57:00 +00001047}
1048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049#define new_delta(d, s, us, normalize) \
1050 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001051
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001052
1053typedef struct
1054{
1055 PyObject_HEAD
1056 PyObject *offset;
1057 PyObject *name;
1058} PyDateTime_TimeZone;
1059
Victor Stinner6ced7c42011-03-21 18:15:42 +01001060/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001061static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -04001062/* The interned Epoch datetime instance */
1063static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00001064
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001065/* 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. */
1069static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001070create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001071{
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
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001079 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
1090static int delta_bool(PyDateTime_Delta *self);
1091
1092static PyObject *
1093new_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 }
Paul Ganssle27b38b92019-08-15 15:08:57 -04001103 if ((GET_TD_DAYS(offset) == -1 &&
1104 GET_TD_SECONDS(offset) == 0 &&
1105 GET_TD_MICROSECONDS(offset) < 1) ||
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001106 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"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04001109 " timedelta(hours=24),"
1110 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001111 return NULL;
1112 }
1113
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001114 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001115}
1116
Tim Petersb0c854d2003-05-17 15:57:00 +00001117/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001118 * tzinfo helpers.
1119 */
1120
Tim Peters855fe882002-12-22 03:43:39 +00001121/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
1122 * raise TypeError and return -1.
1123 */
1124static int
1125check_tzinfo_subclass(PyObject *p)
1126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 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;
Tim Peters855fe882002-12-22 03:43:39 +00001134}
1135
Tim Peters2a799bf2002-12-16 20:18:38 +00001136/* 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 */
1140static PyObject *
1141get_tzinfo_member(PyObject *self)
1142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00001149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001151}
1152
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001153/* 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.
Tim Peters2a799bf2002-12-16 20:18:38 +00001159 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001160static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001161call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001162{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001163 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001166 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001168
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001169 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)) {
Paul Ganssle27b38b92019-08-15 15:08:57 -04001175 if ((GET_TD_DAYS(offset) == -1 &&
1176 GET_TD_SECONDS(offset) == 0 &&
1177 GET_TD_MICROSECONDS(offset) < 1) ||
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001178 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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 }
1185 }
1186 else {
1187 PyErr_Format(PyExc_TypeError,
1188 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001189 "timedelta, not '%.200s'",
1190 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07001191 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001192 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001194
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001195 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001196}
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()
Tim Peters397301e2003-01-02 21:28:08 +00001201 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001202 * 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).
Tim Peters2a799bf2002-12-16 20:18:38 +00001205 */
Tim Peters855fe882002-12-22 03:43:39 +00001206static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001207call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1208{
1209 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001210}
1211
Tim Peters2a799bf2002-12-16 20:18:38 +00001212/* 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()
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001215 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00001216 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +00001217 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001218 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001219 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001220static PyObject *
1221call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001222{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001223 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001224}
1225
Tim Petersbad8ff02002-12-30 20:52:32 +00001226/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +00001227 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001228 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001229 * returns NULL. If the result is a string, we ensure it is a Unicode
1230 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001231 */
1232static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001233call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001236 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 assert(tzinfo != NULL);
1239 assert(check_tzinfo_subclass(tzinfo) >= 0);
1240 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001243 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001244
Victor Stinner20401de2016-12-09 15:24:31 +01001245 result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname,
1246 tzinfoarg, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001247
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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001258
1259 return result;
Tim Peters00237032002-12-27 02:21:51 +00001260}
1261
Tim Peters2a799bf2002-12-16 20:18:38 +00001262/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1263 * stuff
1264 * ", tzinfo=" + repr(tzinfo)
1265 * before the closing ")".
1266 */
1267static PyObject *
1268append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1269{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 assert(PyUnicode_Check(repr));
1273 assert(tzinfo);
1274 if (tzinfo == Py_None)
1275 return repr;
1276 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001277 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1278 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00001285}
1286
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001287/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1288 * stuff
1289 * ", fold=" + repr(tzinfo)
1290 * before the closing ")".
1291 */
1292static PyObject *
1293append_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
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001311static inline PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04001312tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
1313{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001314 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);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001323 if (delta == NULL) {
1324 return NULL;
1325 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001326 tzinfo = new_timezone(delta, NULL);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001327 Py_DECREF(delta);
Paul Ganssle3df85402018-10-22 12:32:52 -04001328 }
1329 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001330 tzinfo = Py_None;
1331 Py_INCREF(Py_None);
1332 }
1333
1334 return tzinfo;
1335}
1336
Tim Peters2a799bf2002-12-16 20:18:38 +00001337/* ---------------------------------------------------------------------------
1338 * String format helpers.
1339 */
1340
1341static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001342format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001343{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001344 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1346 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001347 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1349 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1350 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 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));
Tim Peters2a799bf2002-12-16 20:18:38 +00001358}
1359
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001360static PyObject *delta_negative(PyDateTime_Delta *self);
1361
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001362/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001363 * 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
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001368 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001369 * 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 */
1372static int
Tim Peters328fff72002-12-20 01:31:27 +00001373format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001375{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001376 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001377 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001381
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001382 offset = call_utcoffset(tzinfo, tzinfoarg);
1383 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001385 if (offset == Py_None) {
1386 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 *buf = '\0';
1388 return 0;
1389 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001390 /* Offset is normalized, so it is negative if days < 0 */
1391 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001393 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001394 if (offset == NULL)
1395 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001397 else {
1398 sign = '+';
1399 }
1400 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001401 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001402 seconds = GET_TD_SECONDS(offset);
1403 Py_DECREF(offset);
1404 minutes = divmod(seconds, 60, &seconds);
1405 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001406 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) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001412 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1413 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001414 return 0;
1415 }
1416 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001418}
1419
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001420static PyObject *
1421make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 PyObject *temp;
1424 PyObject *tzinfo = get_tzinfo_member(object);
1425 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001426 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 if (Zreplacement == NULL)
1429 return NULL;
1430 if (tzinfo == Py_None || tzinfo == NULL)
1431 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 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 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 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);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001448 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 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;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001458
1459 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 Py_DECREF(Zreplacement);
1461 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001462}
1463
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001464static PyObject *
1465make_freplacement(PyObject *object)
1466{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 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);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001476}
1477
Tim Peters2a799bf2002-12-16 20:18:38 +00001478/* 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
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001480 * giving special meanings to the %z, %Z and %f format codes via a
1481 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001482 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1483 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001484 */
1485static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001486wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00001494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00001504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 const char *ptoappend; /* ptr to string to append to output buffer */
1506 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 assert(object && format && timetuple);
1509 assert(PyUnicode_Check(format));
1510 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001511 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 if (!pin)
1513 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 /* 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 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00001529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 while ((ch = *pin++) != '\0') {
1531 if (ch != '%') {
1532 ptoappend = pin - 1;
1533 ntoappend = 1;
1534 }
1535 else if ((ch = *pin++) == '\0') {
MichaelSaah454b3d42019-01-14 05:23:39 -05001536 /* 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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 }
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));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001582 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001584 if (ptoappend == NULL)
1585 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 }
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 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 /* 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) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001613 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 PyErr_NoMemory();
1615 goto Done;
1616 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001617 totalnew <<= 1;
1618 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 pnew = PyBytes_AsString(newfmt) + usednew;
1621 }
1622 memcpy(pnew, ptoappend, ntoappend);
1623 pnew += ntoappend;
1624 usednew += ntoappend;
1625 assert(usednew <= totalnew);
1626 } /* end while() */
MichaelSaah454b3d42019-01-14 05:23:39 -05001627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1629 goto Done;
1630 {
1631 PyObject *format;
1632 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 if (time == NULL)
1635 goto Done;
1636 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1637 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001638 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1639 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 Py_DECREF(format);
1641 }
1642 Py_DECREF(time);
1643 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001644 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 Py_XDECREF(freplacement);
1646 Py_XDECREF(zreplacement);
1647 Py_XDECREF(Zreplacement);
1648 Py_XDECREF(newfmt);
1649 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001650}
1651
Tim Peters2a799bf2002-12-16 20:18:38 +00001652/* ---------------------------------------------------------------------------
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). */
1658static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001659time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001660{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 PyObject *result = NULL;
1662 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001665 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001666
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001667 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 Py_DECREF(time);
1669 }
1670 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001671}
1672
1673/* Build a time.struct_time. The weekday and day number are automatically
1674 * computed from the y,m,d args.
1675 */
1676static PyObject *
1677build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1678{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001680 PyObject *result;
1681 _Py_IDENTIFIER(struct_time);
1682 PyObject *args;
1683
Tim Peters2a799bf2002-12-16 20:18:38 +00001684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001686 if (time == NULL) {
1687 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 }
Victor Stinner2b635972016-12-09 00:38:16 +01001689
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);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001704 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001705 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001706}
1707
1708/* ---------------------------------------------------------------------------
1709 * Miscellaneous helpers.
1710 */
1711
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001712/* The comparisons here all most naturally compute a cmp()-like result.
Tim Peters2a799bf2002-12-16 20:18:38 +00001713 * This little helper turns that into a bool result for rich comparisons.
1714 */
1715static PyObject *
1716diff_to_bool(int diff, int op)
1717{
stratakise8b19652017-11-02 11:32:54 +01001718 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001719}
1720
Tim Peters07534a62003-02-07 22:50:28 +00001721/* Raises a "can't compare" TypeError and returns NULL. */
1722static PyObject *
1723cmperror(PyObject *a, PyObject *b)
1724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 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;
Tim Peters07534a62003-02-07 22:50:28 +00001729}
1730
Tim Peters2a799bf2002-12-16 20:18:38 +00001731/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001732 * Cached Python objects; these are set by the module init function.
1733 */
1734
1735/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736static PyObject *us_per_ms = NULL; /* 1000 */
1737static PyObject *us_per_second = NULL; /* 1000000 */
1738static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001739static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1740static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1741static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001742static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1743
Tim Peters2a799bf2002-12-16 20:18:38 +00001744/* ---------------------------------------------------------------------------
1745 * Class implementations.
1746 */
1747
1748/*
1749 * PyDateTime_Delta implementation.
1750 */
1751
1752/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001754 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001755 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1756 * due to ubiquitous overflow possibilities.
1757 */
1758static PyObject *
1759delta_to_microseconds(PyDateTime_Delta *self)
1760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 PyObject *x1 = NULL;
1762 PyObject *x2 = NULL;
1763 PyObject *x3 = NULL;
1764 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 /* 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);
Brett Cannonb94767f2011-02-22 20:15:44 +00001784 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00001792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 /* 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);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001798 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001799
1800Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 Py_XDECREF(x1);
1802 Py_XDECREF(x2);
1803 Py_XDECREF(x3);
1804 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001805}
1806
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001807static PyObject *
1808checked_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
Serhiy Storchaka95949422013-08-27 19:40:23 +03001830/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001831 */
1832static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001833microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 int us;
1836 int s;
1837 int d;
Tim Peters2a799bf2002-12-16 20:18:38 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 PyObject *tuple = NULL;
1840 PyObject *num = NULL;
1841 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001842
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001843 tuple = checked_divmod(pyus, us_per_second);
1844 if (tuple == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 goto Done;
1846 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001847
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001848 num = PyTuple_GET_ITEM(tuple, 1); /* us */
1849 us = _PyLong_AsInt(num);
1850 num = NULL;
1851 if (us == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 goto Done;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001853 }
1854 if (!(0 <= us && us < 1000000)) {
1855 goto BadDivmod;
1856 }
1857
1858 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 Py_INCREF(num);
1860 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001861
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001862 tuple = checked_divmod(num, seconds_per_day);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 if (tuple == NULL)
1864 goto Done;
1865 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001866
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001867 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */
1868 s = _PyLong_AsInt(num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 num = NULL;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001870 if (s == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 goto Done;
1872 }
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001873 if (!(0 <= s && s < 24*3600)) {
1874 goto BadDivmod;
1875 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001876
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001877 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 Py_INCREF(num);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001879 d = _PyLong_AsInt(num);
1880 if (d == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 goto Done;
1882 }
1883 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001884
1885Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 Py_XDECREF(tuple);
1887 Py_XDECREF(num);
1888 return result;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001889
1890BadDivmod:
1891 PyErr_SetString(PyExc_TypeError,
1892 "divmod() returned a value out of range");
1893 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001894}
1895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896#define microseconds_to_delta(pymicros) \
1897 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001898
Tim Peters2a799bf2002-12-16 20:18:38 +00001899static PyObject *
1900multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 PyObject *pyus_in;
1903 PyObject *pyus_out;
1904 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 pyus_in = delta_to_microseconds(delta);
1907 if (pyus_in == NULL)
1908 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001909
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001910 pyus_out = PyNumber_Multiply(intobj, pyus_in);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 Py_DECREF(pyus_in);
1912 if (pyus_out == NULL)
1913 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 result = microseconds_to_delta(pyus_out);
1916 Py_DECREF(pyus_out);
1917 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001918}
1919
1920static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001921get_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
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001947/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001948static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001949multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001950{
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;
Oren Milman865e4b42017-09-19 15:58:11 +03001958 ratio = get_float_as_integer_ratio(floatobj);
1959 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001960 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001961 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001962 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001963 Py_DECREF(pyus_in);
1964 pyus_in = NULL;
1965 if (temp == NULL)
1966 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001967 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001968 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
1980static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001981divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 PyObject *pyus_in;
1984 PyObject *pyus_out;
1985 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 pyus_in = delta_to_microseconds(delta);
1988 if (pyus_in == NULL)
1989 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1992 Py_DECREF(pyus_in);
1993 if (pyus_out == NULL)
1994 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 result = microseconds_to_delta(pyus_out);
1997 Py_DECREF(pyus_out);
1998 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001999}
2000
2001static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 PyObject *pyus_left;
2005 PyObject *pyus_right;
2006 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 pyus_left = delta_to_microseconds(left);
2009 if (pyus_left == NULL)
2010 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 pyus_right = delta_to_microseconds(right);
2013 if (pyus_right == NULL) {
2014 Py_DECREF(pyus_left);
2015 return NULL;
2016 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 result = PyNumber_FloorDivide(pyus_left, pyus_right);
2019 Py_DECREF(pyus_left);
2020 Py_DECREF(pyus_right);
2021 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002022}
2023
2024static PyObject *
2025truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2026{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 PyObject *pyus_left;
2028 PyObject *pyus_right;
2029 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 pyus_left = delta_to_microseconds(left);
2032 if (pyus_left == NULL)
2033 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 pyus_right = delta_to_microseconds(right);
2036 if (pyus_right == NULL) {
2037 Py_DECREF(pyus_left);
2038 return NULL;
2039 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2042 Py_DECREF(pyus_left);
2043 Py_DECREF(pyus_right);
2044 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002045}
2046
2047static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002048truedivide_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
2065static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002066delta_add(PyObject *left, PyObject *right)
2067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 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 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 if (result == Py_NotImplemented)
2083 Py_INCREF(result);
2084 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002085}
2086
2087static PyObject *
2088delta_negative(PyDateTime_Delta *self)
2089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 return new_delta(-GET_TD_DAYS(self),
2091 -GET_TD_SECONDS(self),
2092 -GET_TD_MICROSECONDS(self),
2093 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002094}
2095
2096static PyObject *
2097delta_positive(PyDateTime_Delta *self)
2098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 /* 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);
Tim Peters2a799bf2002-12-16 20:18:38 +00002106}
2107
2108static PyObject *
2109delta_abs(PyDateTime_Delta *self)
2110{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 assert(GET_TD_MICROSECONDS(self) >= 0);
2114 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 if (GET_TD_DAYS(self) < 0)
2117 result = delta_negative(self);
2118 else
2119 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002122}
2123
2124static PyObject *
2125delta_subtract(PyObject *left, PyObject *right)
2126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2130 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002131 /* 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 if (result == Py_NotImplemented)
2142 Py_INCREF(result);
2143 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002144}
2145
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002146static int
2147delta_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
Tim Peters2a799bf2002-12-16 20:18:38 +00002159static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002160delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002161{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002163 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 return diff_to_bool(diff, op);
2165 }
2166 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002167 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002169}
2170
2171static PyObject *delta_getstate(PyDateTime_Delta *self);
2172
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002173static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002174delta_hash(PyDateTime_Delta *self)
2175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00002184}
2185
2186static PyObject *
2187delta_multiply(PyObject *left, PyObject *right)
2188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 if (PyDelta_Check(left)) {
2192 /* delta * ??? */
2193 if (PyLong_Check(right))
2194 result = multiply_int_timedelta(right,
2195 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002196 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002197 result = multiply_truedivide_timedelta_float(
2198 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 }
2200 else if (PyLong_Check(left))
2201 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002202 (PyDateTime_Delta *) right);
2203 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002204 result = multiply_truedivide_timedelta_float(
2205 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002207 if (result == Py_NotImplemented)
2208 Py_INCREF(result);
2209 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002210}
2211
2212static PyObject *
2213delta_divide(PyObject *left, PyObject *right)
2214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002215 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 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 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 if (result == Py_NotImplemented)
2230 Py_INCREF(result);
2231 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002232}
2233
Mark Dickinson7c186e22010-04-20 22:32:49 +00002234static PyObject *
2235delta_truedivide(PyObject *left, PyObject *right)
2236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 if (PyDelta_Check(left)) {
2240 if (PyDelta_Check(right))
2241 result = truedivide_timedelta_timedelta(
2242 (PyDateTime_Delta *)left,
2243 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002244 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002245 result = multiply_truedivide_timedelta_float(
2246 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002247 else if (PyLong_Check(right))
2248 result = truedivide_timedelta_int(
2249 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002252 if (result == Py_NotImplemented)
2253 Py_INCREF(result);
2254 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002255}
2256
2257static PyObject *
2258delta_remainder(PyObject *left, PyObject *right)
2259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 PyObject *pyus_left;
2261 PyObject *pyus_right;
2262 PyObject *pyus_remainder;
2263 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002264
Brian Curtindfc80e32011-08-10 20:28:54 -05002265 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2266 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2269 if (pyus_left == NULL)
2270 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2273 if (pyus_right == NULL) {
2274 Py_DECREF(pyus_left);
2275 return NULL;
2276 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 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;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 remainder = microseconds_to_delta(pyus_remainder);
2285 Py_DECREF(pyus_remainder);
2286 if (remainder == NULL)
2287 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002290}
2291
2292static PyObject *
2293delta_divmod(PyObject *left, PyObject *right)
2294{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 PyObject *pyus_left;
2296 PyObject *pyus_right;
2297 PyObject *divmod;
2298 PyObject *delta;
2299 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002300
Brian Curtindfc80e32011-08-10 20:28:54 -05002301 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2302 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2305 if (pyus_left == NULL)
2306 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2309 if (pyus_right == NULL) {
2310 Py_DECREF(pyus_left);
2311 return NULL;
2312 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002313
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002314 divmod = checked_divmod(pyus_left, pyus_right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 Py_DECREF(pyus_left);
2316 Py_DECREF(pyus_right);
2317 if (divmod == NULL)
2318 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002320 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;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002329}
2330
Tim Peters2a799bf2002-12-16 20:18:38 +00002331/* 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 */
2340static PyObject *
2341accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2342 double *leftover)
2343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 PyObject *prod;
2345 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 if (PyLong_Check(num)) {
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002350 prod = PyNumber_Multiply(num, factor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 if (prod == NULL)
2352 return NULL;
2353 sum = PyNumber_Add(sofar, prod);
2354 Py_DECREF(prod);
2355 return sum;
2356 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002358 if (PyFloat_Check(num)) {
2359 double dnum;
2360 double fracpart;
2361 double intpart;
2362 PyObject *x;
2363 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002365 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00002380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 prod = PyNumber_Multiply(x, factor);
2382 Py_DECREF(x);
2383 if (prod == NULL)
2384 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 sum = PyNumber_Add(sofar, prod);
2387 Py_DECREF(prod);
2388 if (sum == NULL)
2389 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 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 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002397 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 dnum *= fracpart;
2401 fracpart = modf(dnum, &intpart);
2402 x = PyLong_FromDouble(intpart);
2403 if (x == NULL) {
2404 Py_DECREF(sum);
2405 return NULL;
2406 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 y = PyNumber_Add(sum, x);
2409 Py_DECREF(sum);
2410 Py_DECREF(x);
2411 *leftover += fracpart;
2412 return y;
2413 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 PyErr_Format(PyExc_TypeError,
2416 "unsupported type for timedelta %s component: %s",
2417 tag, Py_TYPE(num)->tp_name);
2418 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002419}
2420
2421static PyObject *
2422delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 PyObject *x = NULL; /* running sum of microseconds */
2436 PyObject *y = NULL; /* temp sum of microseconds */
2437 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 static char *keywords[] = {
2440 "days", "seconds", "microseconds", "milliseconds",
2441 "minutes", "hours", "weeks", NULL
2442 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2445 keywords,
2446 &day, &second, &us,
2447 &ms, &minute, &hour, &week) == 0)
2448 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 x = PyLong_FromLong(0);
2451 if (x == NULL)
2452 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002454#define CLEANUP \
2455 Py_DECREF(x); \
2456 x = y; \
2457 if (x == NULL) \
2458 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002461 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 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. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002490 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002491 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002492 PyObject *temp;
2493
Victor Stinner69cc4872015-09-08 23:58:54 +02002494 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. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002501 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002502 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 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002514
Victor Stinner36a5a062013-08-28 01:53:39 +02002515 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 if (temp == NULL) {
2518 Py_DECREF(x);
2519 goto Done;
2520 }
2521 y = PyNumber_Add(x, temp);
2522 Py_DECREF(temp);
2523 CLEANUP;
2524 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002526 self = microseconds_to_delta_ex(x, type);
2527 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002528Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002530
2531#undef CLEANUP
2532}
2533
2534static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002535delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002536{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002537 return (GET_TD_DAYS(self) != 0
2538 || GET_TD_SECONDS(self) != 0
2539 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002540}
2541
2542static PyObject *
2543delta_repr(PyDateTime_Delta *self)
2544{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002545 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002546
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002547 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00002589}
2590
2591static PyObject *
2592delta_str(PyDateTime_Delta *self)
2593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 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);
Tim Peters2a799bf2002-12-16 20:18:38 +00002599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 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 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002617
Tim Peters2a799bf2002-12-16 20:18:38 +00002618}
2619
Tim Peters371935f2003-02-01 01:52:50 +00002620/* Pickle support, a simple use of __reduce__. */
2621
Tim Petersb57f8f02003-02-01 02:54:15 +00002622/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002623static PyObject *
2624delta_getstate(PyDateTime_Delta *self)
2625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002626 return Py_BuildValue("iii", GET_TD_DAYS(self),
2627 GET_TD_SECONDS(self),
2628 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002629}
2630
Tim Peters2a799bf2002-12-16 20:18:38 +00002631static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302632delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitroube6859d2009-11-25 23:02:32 +00002633{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002634 PyObject *total_seconds;
2635 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002637 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2638 if (total_microseconds == NULL)
2639 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002640
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002641 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002644 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002645}
2646
2647static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302648delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00002649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002651}
2652
2653#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2654
2655static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002657 {"days", T_INT, OFFSET(days), READONLY,
2658 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002660 {"seconds", T_INT, OFFSET(seconds), READONLY,
2661 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002663 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2664 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2665 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002666};
2667
2668static PyMethodDef delta_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302669 {"total_seconds", delta_total_seconds, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002672 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2673 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002675 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002676};
2677
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002678static const char delta_doc[] =
Chris Barkerd6a61f22018-10-19 15:43:24 -07002679PyDoc_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.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002684
2685static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002686 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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00002719};
2720
2721static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002722 PyVarObject_HEAD_INIT(NULL, 0)
2723 "datetime.timedelta", /* tp_name */
2724 sizeof(PyDateTime_Delta), /* tp_basicsize */
2725 0, /* tp_itemsize */
2726 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002727 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002728 0, /* tp_getattr */
2729 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002730 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002731 (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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00002761};
2762
2763/*
2764 * PyDateTime_Date implementation.
2765 */
2766
2767/* Accessor properties. */
2768
2769static PyObject *
2770date_year(PyDateTime_Date *self, void *unused)
2771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002773}
2774
2775static PyObject *
2776date_month(PyDateTime_Date *self, void *unused)
2777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002778 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002779}
2780
2781static PyObject *
2782date_day(PyDateTime_Date *self, void *unused)
2783{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002784 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002785}
2786
2787static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002788 {"year", (getter)date_year},
2789 {"month", (getter)date_month},
2790 {"day", (getter)date_day},
2791 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002792};
2793
2794/* Constructors. */
2795
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002796static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002797
Tim Peters2a799bf2002-12-16 20:18:38 +00002798static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002799date_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
2812static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002813date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002816 int year;
2817 int month;
2818 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002820 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka1133a8c2018-12-07 16:48:21 +02002821 if (PyTuple_GET_SIZE(args) == 1) {
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002822 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);
Victor Stinnerb37672d2018-11-22 03:37:50 +01002828 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002829 }
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 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002852 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002855 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2856 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002857 self = new_date_ex(year, month, day, type);
2858 }
2859 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002860}
2861
Tim Peters2a799bf2002-12-16 20:18:38 +00002862static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002863date_fromtimestamp(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002864{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002865 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002866 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002867
Victor Stinnere4a994d2015-03-30 01:10:14 +02002868 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002869 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002870
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002871 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002872 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002873
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002874 return new_date_subclass_ex(tm.tm_year + 1900,
2875 tm.tm_mon + 1,
2876 tm.tm_mday,
2877 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002878}
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 */
2885static PyObject *
2886date_today(PyObject *cls, PyObject *dummy)
2887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002888 PyObject *time;
2889 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002890 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002892 time = time_time();
2893 if (time == NULL)
2894 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002896 /* 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 */
Victor Stinner20401de2016-12-09 15:24:31 +01002902 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2903 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002904 Py_DECREF(time);
2905 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002906}
2907
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002908/*[clinic input]
2909@classmethod
2910datetime.date.fromtimestamp
2911
2912 timestamp: object
2913 /
2914
2915Create a date from a POSIX timestamp.
2916
2917The timestamp is a number, e.g. created via time.time(), that is interpreted
2918as local time.
2919[clinic start generated code]*/
2920
Tim Peters2a799bf2002-12-16 20:18:38 +00002921static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002922datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp)
2923/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00002924{
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002925 return date_fromtimestamp((PyObject *) type, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002926}
2927
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04002928/* 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 */
2932static PyObject *
2933datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args)
2934{
2935 PyObject *timestamp;
2936 PyObject *result = NULL;
2937
2938 if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, &timestamp)) {
2939 result = date_fromtimestamp(cls, timestamp);
2940 }
2941
2942 return result;
2943}
2944
Tim Peters2a799bf2002-12-16 20:18:38 +00002945/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2946 * the ordinal is out of range.
2947 */
2948static PyObject *
2949date_fromordinal(PyObject *cls, PyObject *args)
2950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002951 PyObject *result = NULL;
2952 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002954 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2955 int year;
2956 int month;
2957 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002959 if (ordinal < 1)
2960 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2961 ">= 1");
2962 else {
2963 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002964 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002965 }
2966 }
2967 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002968}
2969
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002970/* Return the new date from a string as generated by date.isoformat() */
2971static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04002972date_fromisoformat(PyObject *cls, PyObject *dtstr)
2973{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002974 assert(dtstr != NULL);
2975
2976 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04002977 PyErr_SetString(PyExc_TypeError,
2978 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002979 return NULL;
2980 }
2981
2982 Py_ssize_t len;
2983
Paul Ganssle3df85402018-10-22 12:32:52 -04002984 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04002985 if (dt_ptr == NULL) {
2986 goto invalid_string_error;
2987 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002988
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);
Paul Ganssle3df85402018-10-22 12:32:52 -04002994 }
2995 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002996 rv = -1;
2997 }
2998
2999 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04003000 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003001 }
3002
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05003003 return new_date_subclass_ex(year, month, day, cls);
Paul Ganssle096329f2018-08-23 11:06:20 -04003004
3005invalid_string_error:
Paul Ganssle3df85402018-10-22 12:32:52 -04003006 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04003007 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003008}
3009
Paul Ganssle88c09372019-04-29 09:22:03 -04003010
3011static PyObject *
3012date_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
Tim Peters2a799bf2002-12-16 20:18:38 +00003071/*
3072 * Date arithmetic.
3073 */
3074
3075/* date + timedelta -> date. If arg negate is true, subtract the timedelta
3076 * instead.
3077 */
3078static PyObject *
3079add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
3080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003081 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);
Tim Peters2a799bf2002-12-16 20:18:38 +00003087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003088 if (normalize_date(&year, &month, &day) >= 0)
Paul Ganssle89427cd2019-02-04 14:42:04 -05003089 result = new_date_subclass_ex(year, month, day,
3090 (PyObject* )Py_TYPE(date));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003091 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003092}
3093
3094static PyObject *
3095date_add(PyObject *left, PyObject *right)
3096{
Brian Curtindfc80e32011-08-10 20:28:54 -05003097 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3098 Py_RETURN_NOTIMPLEMENTED;
3099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003100 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 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003118 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003119}
3120
3121static PyObject *
3122date_subtract(PyObject *left, PyObject *right)
3123{
Brian Curtindfc80e32011-08-10 20:28:54 -05003124 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3125 Py_RETURN_NOTIMPLEMENTED;
3126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003127 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 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003145 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003146}
3147
3148
3149/* Various ways to turn a date into a string. */
3150
3151static PyObject *
3152date_repr(PyDateTime_Date *self)
3153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003154 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3155 Py_TYPE(self)->tp_name,
3156 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003157}
3158
3159static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303160date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003161{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003162 return PyUnicode_FromFormat("%04d-%02d-%02d",
3163 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003164}
3165
Tim Peterse2df5ff2003-05-02 18:39:55 +00003166/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003167static PyObject *
3168date_str(PyDateTime_Date *self)
3169{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003170 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003171}
3172
3173
3174static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303175date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003177 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003178}
3179
3180static PyObject *
3181date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003183 /* 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;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003189 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003190 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003192 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3193 &format))
3194 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003195
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003196 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003197 if (tuple == NULL)
3198 return NULL;
3199 result = wrap_strftime((PyObject *)self, format, tuple,
3200 (PyObject *)self);
3201 Py_DECREF(tuple);
3202 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003203}
3204
Eric Smith1ba31142007-09-11 18:06:02 +00003205static PyObject *
3206date_format(PyDateTime_Date *self, PyObject *args)
3207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003210 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3211 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003213 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003214 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003216
Victor Stinner20401de2016-12-09 15:24:31 +01003217 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3218 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003219}
3220
Tim Peters2a799bf2002-12-16 20:18:38 +00003221/* ISO methods. */
3222
3223static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303224date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003226 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003228 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003229}
3230
3231static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303232date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003234 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00003239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003240 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);
Tim Peters2a799bf2002-12-16 20:18:38 +00003251}
3252
3253/* Miscellaneous methods. */
3254
Tim Peters2a799bf2002-12-16 20:18:38 +00003255static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003256date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003258 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 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003264 else
3265 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003266}
3267
3268static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303269date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003271 return build_struct_time(GET_YEAR(self),
3272 GET_MONTH(self),
3273 GET_DAY(self),
3274 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003275}
3276
Tim Peters12bf3392002-12-24 05:41:27 +00003277static PyObject *
3278date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003280 PyObject *clone;
3281 PyObject *tuple;
3282 int year = GET_YEAR(self);
3283 int month = GET_MONTH(self);
3284 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003286 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;
Tim Peters12bf3392002-12-24 05:41:27 +00003295}
3296
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003297static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003298generic_hash(unsigned char *data, int len)
3299{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003300 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003301}
3302
3303
3304static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003305
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003306static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003307date_hash(PyDateTime_Date *self)
3308{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003309 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003310 self->hashcode = generic_hash(
3311 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003312 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003314 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003315}
3316
3317static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303318date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003320 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3321 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003322}
3323
3324static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303325date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003327 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003329 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003330}
3331
Tim Peters371935f2003-02-01 01:52:50 +00003332/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003333
Tim Petersb57f8f02003-02-01 02:54:15 +00003334/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003335static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003336date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003338 PyObject* field;
3339 field = PyBytes_FromStringAndSize((char*)self->data,
3340 _PyDateTime_DATE_DATASIZE);
3341 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003342}
3343
3344static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003345date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003346{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003347 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003348}
3349
3350static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003352 /* Class methods: */
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02003353 DATETIME_DATE_FROMTIMESTAMP_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00003354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003355 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3356 METH_CLASS,
3357 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3358 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003359
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003360 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3361 METH_CLASS,
3362 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3363
Paul Ganssle88c09372019-04-29 09:22:03 -04003364 {"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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003370 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3371 PyDoc_STR("Current date or datetime: same as "
3372 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003374 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003376 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3377 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003378
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003379 {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003380 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003382 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3383 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003385 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3386 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003388 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3389 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3390 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003392 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3393 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003395 {"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")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003399 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3400 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3401 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003403 {"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")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003406
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003407 {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003408 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003410 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3411 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003413 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003414};
3415
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003416static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003417PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003418
3419static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003420 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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00003430};
3431
3432static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003433 PyVarObject_HEAD_INIT(NULL, 0)
3434 "datetime.date", /* tp_name */
3435 sizeof(PyDateTime_Date), /* tp_basicsize */
3436 0, /* tp_itemsize */
3437 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003438 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003439 0, /* tp_getattr */
3440 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003441 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003442 (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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00003472};
3473
3474/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003475 * 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
Tim Petersa9bc1682003-01-11 03:39:11 +00003481 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003482 * 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
3491static PyObject *
3492tzinfo_nogo(const char* methodname)
3493{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003494 PyErr_Format(PyExc_NotImplementedError,
3495 "a tzinfo subclass must implement %s()",
3496 methodname);
3497 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003498}
3499
3500/* Methods. A subclass must implement these. */
3501
Tim Peters52dcce22003-01-23 16:36:11 +00003502static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003503tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003505 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003506}
3507
Tim Peters52dcce22003-01-23 16:36:11 +00003508static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003509tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3510{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003511 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003512}
3513
Tim Peters52dcce22003-01-23 16:36:11 +00003514static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003515tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003517 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003518}
3519
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003520
3521static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3522 PyDateTime_Delta *delta,
3523 int factor);
3524static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3525static PyObject *datetime_dst(PyObject *self, PyObject *);
3526
Tim Peters52dcce22003-01-23 16:36:11 +00003527static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003528tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003529{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003530 PyObject *result = NULL;
3531 PyObject *off = NULL, *dst = NULL;
3532 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003533
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003534 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003535 PyErr_SetString(PyExc_TypeError,
3536 "fromutc: argument must be a datetime");
3537 return NULL;
3538 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003539 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003540 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3541 "is not self");
3542 return NULL;
3543 }
Tim Peters52dcce22003-01-23 16:36:11 +00003544
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003545 off = datetime_utcoffset(dt, NULL);
3546 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003547 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003548 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003549 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3550 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003551 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003552 }
Tim Peters52dcce22003-01-23 16:36:11 +00003553
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003554 dst = datetime_dst(dt, NULL);
3555 if (dst == NULL)
3556 goto Fail;
3557 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003558 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3559 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003560 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003561 }
Tim Peters52dcce22003-01-23 16:36:11 +00003562
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003563 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3564 if (delta == NULL)
3565 goto Fail;
3566 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003567 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003569
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)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003575 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003576 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003577 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003578 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003579 if (result == NULL)
3580 goto Fail;
3581 }
3582 Py_DECREF(delta);
3583 Py_DECREF(dst);
3584 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003585 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003586
3587Inconsistent:
Serhiy Storchaka34fd4c22018-11-05 16:20:25 +02003588 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003589 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003590
Leo Ariasc3d95082018-02-03 18:36:10 -06003591 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003592Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003593 Py_XDECREF(off);
3594 Py_XDECREF(dst);
3595 Py_XDECREF(delta);
3596 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003597 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003598}
3599
Tim Peters2a799bf2002-12-16 20:18:38 +00003600/*
3601 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003602 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003603 */
3604
Guido van Rossum177e41a2003-01-30 22:06:23 +00003605static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303606tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003607{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003608 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003609 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003610 _Py_IDENTIFIER(__getinitargs__);
3611 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003612
Serhiy Storchaka353053d2019-09-01 14:01:05 +03003613 if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) {
3614 return NULL;
3615 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003616 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003617 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003618 Py_DECREF(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003619 }
3620 else {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003621 args = PyTuple_New(0);
Serhiy Storchaka353053d2019-09-01 14:01:05 +03003622 }
3623 if (args == NULL) {
3624 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003625 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003626
Serhiy Storchaka353053d2019-09-01 14:01:05 +03003627 if (_PyObject_LookupAttrId(self, &PyId___getstate__, &getstate) < 0) {
3628 Py_DECREF(args);
3629 return NULL;
3630 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003631 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003632 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003633 Py_DECREF(getstate);
3634 if (state == NULL) {
3635 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003636 return NULL;
3637 }
3638 }
3639 else {
3640 PyObject **dictptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003641 state = Py_None;
3642 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003643 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003644 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003645 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003646 Py_INCREF(state);
3647 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003649 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);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003655}
Tim Peters2a799bf2002-12-16 20:18:38 +00003656
3657static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003659 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3660 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003662 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003663 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3664 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003666 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003667 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003669 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003670 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003671
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303672 {"__reduce__", tzinfo_reduce, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003673 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003675 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003676};
3677
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003678static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003679PyDoc_STR("Abstract base class for time zone info objects.");
3680
Neal Norwitz227b5332006-03-22 09:28:35 +00003681static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003682 PyVarObject_HEAD_INIT(NULL, 0)
3683 "datetime.tzinfo", /* tp_name */
3684 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3685 0, /* tp_itemsize */
3686 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003687 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003688 0, /* tp_getattr */
3689 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003690 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003691 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 */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003701 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003702 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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00003721};
3722
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003723static char *timezone_kws[] = {"offset", "name", NULL};
3724
3725static PyObject *
3726timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3727{
3728 PyObject *offset;
3729 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003730 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3731 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003732 return new_timezone(offset, name);
3733
3734 return NULL;
3735}
3736
3737static void
3738timezone_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
3745static PyObject *
3746timezone_richcompare(PyDateTime_TimeZone *self,
3747 PyDateTime_TimeZone *other, int op)
3748{
Brian Curtindfc80e32011-08-10 20:28:54 -05003749 if (op != Py_EQ && op != Py_NE)
3750 Py_RETURN_NOTIMPLEMENTED;
Miss Islington (bot)5c777302019-08-23 01:48:40 -07003751 if (!PyTimezone_Check(other)) {
Miss Islington (bot)dde944f2019-08-04 03:01:55 -07003752 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003753 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003754 return delta_richcompare(self->offset, other->offset, op);
3755}
3756
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003757static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003758timezone_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 */
3767static int
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
3777static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003778timezone_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
3795static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003796timezone_str(PyDateTime_TimeZone *self)
3797{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003798 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003799 PyObject *offset;
3800 char sign;
3801
3802 if (self->name != NULL) {
3803 Py_INCREF(self->name);
3804 return self->name;
3805 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003806 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003807 (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");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003811 /* 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. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003824 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003825 seconds = GET_TD_SECONDS(offset);
3826 Py_DECREF(offset);
3827 minutes = divmod(seconds, 60, &seconds);
3828 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003829 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 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003838 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003839}
3840
3841static PyObject *
3842timezone_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
3850static PyObject *
3851timezone_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
3860static PyObject *
3861timezone_dst(PyObject *self, PyObject *dt)
3862{
3863 if (_timezone_check_argument(dt, "dst") == -1)
3864 return NULL;
3865
3866 Py_RETURN_NONE;
3867}
3868
3869static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003870timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3871{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003872 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003873 PyErr_SetString(PyExc_TypeError,
3874 "fromutc: argument must be a datetime");
3875 return NULL;
3876 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003877 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003878 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
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003886static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303887timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003888{
3889 if (self->name == NULL)
3890 return Py_BuildValue("(O)", self->offset);
3891 return Py_BuildValue("(OO)", self->offset, self->name);
3892}
3893
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003894static PyMethodDef timezone_methods[] = {
3895 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3896 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003897 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003898
3899 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003900 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003901
3902 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003903 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003904
3905 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3906 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3907
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003908 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3909 PyDoc_STR("pickle support")},
3910
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003911 {NULL, NULL}
3912};
3913
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003914static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003915PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3916
3917static 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 */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003923 0, /* tp_vectorcall_offset */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003924 0, /* tp_getattr */
3925 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003926 0, /* tp_as_async */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003927 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003928 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
Tim Peters2a799bf2002-12-16 20:18:38 +00003958/*
Tim Peters37f39822003-01-10 03:49:02 +00003959 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003960 */
3961
Tim Peters37f39822003-01-10 03:49:02 +00003962/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003963 */
3964
3965static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003966time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003968 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003969}
3970
Tim Peters37f39822003-01-10 03:49:02 +00003971static PyObject *
3972time_minute(PyDateTime_Time *self, void *unused)
3973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003974 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003975}
3976
3977/* The name time_second conflicted with some platform header file. */
3978static PyObject *
3979py_time_second(PyDateTime_Time *self, void *unused)
3980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003981 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003982}
3983
3984static PyObject *
3985time_microsecond(PyDateTime_Time *self, void *unused)
3986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003987 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003988}
3989
3990static PyObject *
3991time_tzinfo(PyDateTime_Time *self, void *unused)
3992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003993 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3994 Py_INCREF(result);
3995 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003996}
3997
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003998static PyObject *
3999time_fold(PyDateTime_Time *self, void *unused)
4000{
4001 return PyLong_FromLong(TIME_GET_FOLD(self));
4002}
4003
Tim Peters37f39822003-01-10 03:49:02 +00004004static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004005 {"hour", (getter)time_hour},
4006 {"minute", (getter)time_minute},
4007 {"second", (getter)py_time_second},
4008 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004009 {"tzinfo", (getter)time_tzinfo},
4010 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004011 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004012};
4013
4014/*
4015 * Constructors.
4016 */
4017
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004018static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004019 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00004020
Tim Peters2a799bf2002-12-16 20:18:38 +00004021static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004022time_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
4054static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004055time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004056{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004057 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004058 int hour = 0;
4059 int minute = 0;
4060 int second = 0;
4061 int usecond = 0;
4062 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004063 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004065 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004066 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 &&
Miss Islington (bot)d1d42bf2019-08-29 00:56:04 -07004083 (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24)
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004084 {
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 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004094 return NULL;
4095 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004096 self = time_from_pickle(type, state, tzinfo);
4097 Py_DECREF(state);
4098 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004100 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004101 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004103
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004104 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004105 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004106 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004107 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4108 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004109 }
4110 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004111}
4112
4113/*
4114 * Destructor.
4115 */
4116
4117static void
Tim Peters37f39822003-01-10 03:49:02 +00004118time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004120 if (HASTZINFO(self)) {
4121 Py_XDECREF(self->tzinfo);
4122 }
4123 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004124}
4125
4126/*
Tim Peters855fe882002-12-22 03:43:39 +00004127 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004128 */
4129
Tim Peters2a799bf2002-12-16 20:18:38 +00004130/* These are all METH_NOARGS, so don't need to check the arglist. */
4131static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004132time_utcoffset(PyObject *self, PyObject *unused) {
4133 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004134}
4135
4136static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004137time_dst(PyObject *self, PyObject *unused) {
4138 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004139}
4140
4141static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004142time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004143 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004144}
4145
4146/*
Tim Peters37f39822003-01-10 03:49:02 +00004147 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004148 */
4149
4150static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004151time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004153 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);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004158 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004159 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004161 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);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004171 if (result != NULL && fold)
4172 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004173 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004174}
4175
Tim Peters37f39822003-01-10 03:49:02 +00004176static PyObject *
4177time_str(PyDateTime_Time *self)
4178{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07004179 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00004180}
Tim Peters2a799bf2002-12-16 20:18:38 +00004181
4182static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004183time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004185 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004186 char *timespec = NULL;
4187 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004188 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004189 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004190 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00004198
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004199 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4200 return NULL;
4201
4202 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4203 if (us == 0) {
4204 /* seconds */
4205 given_spec = 2;
4206 }
4207 else {
4208 /* microseconds */
4209 given_spec = 4;
4210 }
4211 }
4212 else {
4213 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4214 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4215 if (given_spec == 3) {
4216 /* milliseconds */
4217 us = us / 1000;
4218 }
4219 break;
4220 }
4221 }
4222 }
4223
4224 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4225 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4226 return NULL;
4227 }
4228 else {
4229 result = PyUnicode_FromFormat(specs[given_spec][1],
4230 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4231 TIME_GET_SECOND(self), us);
4232 }
Tim Peters37f39822003-01-10 03:49:02 +00004233
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004234 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004235 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004237 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00004245}
4246
Tim Peters37f39822003-01-10 03:49:02 +00004247static PyObject *
4248time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004250 PyObject *result;
4251 PyObject *tuple;
4252 PyObject *format;
4253 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004255 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4256 &format))
4257 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004259 /* Python's strftime does insane things with the year part of the
4260 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004261 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004262 */
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;
Tim Peters37f39822003-01-10 03:49:02 +00004276}
Tim Peters2a799bf2002-12-16 20:18:38 +00004277
4278/*
4279 * Miscellaneous methods.
4280 */
4281
Tim Peters37f39822003-01-10 03:49:02 +00004282static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004283time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004284{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004285 PyObject *result = NULL;
4286 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004287 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004288
Brian Curtindfc80e32011-08-10 20:28:54 -05004289 if (! PyTime_Check(other))
4290 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004291
4292 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004293 diff = memcmp(((PyDateTime_Time *)self)->data,
4294 ((PyDateTime_Time *)other)->data,
4295 _PyDateTime_TIME_DATASIZE);
4296 return diff_to_bool(diff, op);
4297 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004298 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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004331 if (diff == 0)
4332 diff = TIME_GET_MICROSECOND(self) -
4333 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004334 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004335 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004336 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 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004344 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;
Tim Peters37f39822003-01-10 03:49:02 +00004353}
4354
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004355static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004356time_hash(PyDateTime_Time *self)
4357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004358 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004359 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004360 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),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004365 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);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004376
4377 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004378 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004380 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004381 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004382 self->hashcode = generic_hash(
4383 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004385 PyObject *temp1, *temp2;
4386 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004387 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004388 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004405 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004406 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004407 }
4408 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004409}
Tim Peters2a799bf2002-12-16 20:18:38 +00004410
Tim Peters12bf3392002-12-24 05:41:27 +00004411static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004412time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004414 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;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004421 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004422
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004423 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004424 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004425 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004426 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004427 if (fold != 0 && fold != 1) {
4428 PyErr_SetString(PyExc_ValueError,
4429 "fold must be either 0 or 1");
4430 return NULL;
4431 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004432 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);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004436 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004437 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004438 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004439 Py_DECREF(tuple);
4440 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004441}
4442
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004443static PyObject *
4444time_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
Paul Ganssle096329f2018-08-23 11:06:20 -04004455 if (p == NULL) {
4456 goto invalid_string_error;
4457 }
4458
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004459 int hour = 0, minute = 0, second = 0, microsecond = 0;
4460 int tzoffset, tzimicrosecond = 0;
4461 int rv = parse_isoformat_time(p, len,
4462 &hour, &minute, &second, &microsecond,
4463 &tzoffset, &tzimicrosecond);
4464
4465 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04004466 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004467 }
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;
Paul Ganssle096329f2018-08-23 11:06:20 -04004486
4487invalid_string_error:
4488 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4489 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004490}
4491
4492
Tim Peters371935f2003-02-01 01:52:50 +00004493/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004494
Tim Peters33e0f382003-01-10 02:05:14 +00004495/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004496 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4497 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004498 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004499 */
4500static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004501time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004503 PyObject *basestate;
4504 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004506 basestate = PyBytes_FromStringAndSize((char *)self->data,
4507 _PyDateTime_TIME_DATASIZE);
4508 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004509 if (proto > 3 && TIME_GET_FOLD(self))
4510 /* Set the first bit of the first byte */
4511 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004512 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00004519}
4520
4521static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004522time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004523{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004524 int proto;
4525 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004526 return NULL;
4527
4528 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004529}
4530
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004531static PyObject *
4532time_reduce(PyDateTime_Time *self, PyObject *arg)
4533{
4534 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4535}
4536
Tim Peters37f39822003-01-10 03:49:02 +00004537static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004538
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004539 {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS,
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004540 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")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004543
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004544 {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004545 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004547 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4548 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004550 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4551 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004553 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4554 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004556 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4557 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004558
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004559 {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004560 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004561
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004562 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4563 PyDoc_STR("string -> time from time.isoformat() output")},
4564
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004565 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004566 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004567
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004568 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4569 PyDoc_STR("__reduce__() -> (cls, state)")},
4570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004571 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004572};
4573
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004574static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004575PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4576\n\
4577All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004578a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004579
Neal Norwitz227b5332006-03-22 09:28:35 +00004580static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004581 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 */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004586 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004587 0, /* tp_getattr */
4588 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004589 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004590 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004591 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004592 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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00004620};
4621
4622/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004623 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004624 */
4625
Tim Petersa9bc1682003-01-11 03:39:11 +00004626/* Accessor properties. Properties for day, month, and year are inherited
4627 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004628 */
4629
4630static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004631datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004633 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004634}
4635
Tim Petersa9bc1682003-01-11 03:39:11 +00004636static PyObject *
4637datetime_minute(PyDateTime_DateTime *self, void *unused)
4638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004640}
4641
4642static PyObject *
4643datetime_second(PyDateTime_DateTime *self, void *unused)
4644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004645 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004646}
4647
4648static PyObject *
4649datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4650{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004651 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004652}
4653
4654static PyObject *
4655datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4656{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004657 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4658 Py_INCREF(result);
4659 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004660}
4661
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004662static PyObject *
4663datetime_fold(PyDateTime_DateTime *self, void *unused)
4664{
4665 return PyLong_FromLong(DATE_GET_FOLD(self));
4666}
4667
Tim Petersa9bc1682003-01-11 03:39:11 +00004668static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004669 {"hour", (getter)datetime_hour},
4670 {"minute", (getter)datetime_minute},
4671 {"second", (getter)datetime_second},
4672 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004673 {"tzinfo", (getter)datetime_tzinfo},
4674 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004675 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004676};
4677
4678/*
4679 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004680 */
4681
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004682static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004684 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004685};
4686
Tim Peters2a799bf2002-12-16 20:18:38 +00004687static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004688datetime_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
4720static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004721datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004722{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004723 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004724 int year;
4725 int month;
4726 int day;
4727 int hour = 0;
4728 int minute = 0;
4729 int second = 0;
4730 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004731 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004732 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004734 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004735 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 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004763 return NULL;
4764 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004765 self = datetime_from_pickle(type, state, tzinfo);
4766 Py_DECREF(state);
4767 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004768 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004769 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004770 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004771 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004772
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004773 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004774 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004775 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004776 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004777 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004778 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004779 }
4780 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004781}
4782
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004783/* TM_FUNC is the shared type of _PyTime_localtime() and
4784 * _PyTime_gmtime(). */
4785typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004786
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004787/* As of version 2015f max fold in IANA database is
4788 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004789static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004790/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004791static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004792
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004793static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004794utc_to_seconds(int year, int month, int day,
4795 int hour, int minute, int second)
4796{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004797 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);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004806 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4807}
4808
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004809static long long
4810local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004811{
4812 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004813 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 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004821 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004822 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004823 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
Tim Petersa9bc1682003-01-11 03:39:11 +00004831/* 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 */
4835static PyObject *
4836datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004837 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004838{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004839 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004840 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004841
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004842 if (f(timet, &tm) != 0)
4843 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004844
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004845 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;
Victor Stinner21f58932012-03-14 00:15:40 +01004850 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004851 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004852 * 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 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004856 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004857
Victor Stinnerb67f0962017-02-10 10:34:02 +01004858 /* local timezone requires to compute fold */
Ammar Askar96d1e692018-07-25 09:54:58 -07004859 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 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004875 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004876
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 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004892 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4893 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004894}
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 */
4903static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004904datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004905 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004906{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004907 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004908 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004909
Victor Stinnere4a994d2015-03-30 01:10:14 +02004910 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004911 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004912 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004913
Victor Stinner21f58932012-03-14 00:15:40 +01004914 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004915}
4916
4917/* Internal helper.
4918 * Build most accurate possible datetime for current time. Pass localtime or
4919 * gmtime for f as appropriate.
4920 */
4921static PyObject *
4922datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4923{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004924 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004925 time_t secs;
4926 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004927
Victor Stinner1e2b6882015-09-18 13:23:02 +02004928 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004929 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004930 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004931
Victor Stinner1e2b6882015-09-18 13:23:02 +02004932 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004933}
4934
Larry Hastings61272b72014-01-07 12:41:53 -08004935/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004936
4937@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004938datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004939
4940 tz: object = None
4941 Timezone object.
4942
4943Returns new datetime object representing current time local to tz.
4944
4945If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004946[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004947
Larry Hastings31826802013-10-19 00:09:25 -07004948static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004949datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004950/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004952 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004953
Larry Hastings31826802013-10-19 00:09:25 -07004954 /* Return best possible local time -- this isn't constrained by the
4955 * precision of a timestamp.
4956 */
4957 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004958 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004959
Larry Hastings5c661892014-01-24 06:17:25 -08004960 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004961 tz == Py_None ? _PyTime_localtime :
4962 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004963 tz);
4964 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004965 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004966 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004967 }
4968 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004969}
4970
Tim Petersa9bc1682003-01-11 03:39:11 +00004971/* Return best possible UTC time -- this isn't constrained by the
4972 * precision of a timestamp.
4973 */
4974static PyObject *
4975datetime_utcnow(PyObject *cls, PyObject *dummy)
4976{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004977 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004978}
4979
Tim Peters2a799bf2002-12-16 20:18:38 +00004980/* Return new local datetime from timestamp (Python timestamp -- a double). */
4981static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004982datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004984 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004985 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004986 PyObject *tzinfo = Py_None;
4987 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004988
Victor Stinner5d272cc2012-03-13 13:35:55 +01004989 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004990 keywords, &timestamp, &tzinfo))
4991 return NULL;
4992 if (check_tzinfo_subclass(tzinfo) < 0)
4993 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004995 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004996 tzinfo == Py_None ? _PyTime_localtime :
4997 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004998 timestamp,
4999 tzinfo);
5000 if (self != NULL && tzinfo != Py_None) {
5001 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02005002 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005003 }
5004 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005005}
5006
Tim Petersa9bc1682003-01-11 03:39:11 +00005007/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
5008static PyObject *
5009datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
5010{
Victor Stinner5d272cc2012-03-13 13:35:55 +01005011 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005012 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005013
Victor Stinner5d272cc2012-03-13 13:35:55 +01005014 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005015 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005016 Py_None);
5017 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005018}
5019
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005020/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005021static PyObject *
5022datetime_strptime(PyObject *cls, PyObject *args)
5023{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005024 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005025 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02005026 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005027
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005028 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005029 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005030
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005031 if (module == NULL) {
5032 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00005033 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005034 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 }
Victor Stinner20401de2016-12-09 15:24:31 +01005036 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
5037 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005038}
5039
Tim Petersa9bc1682003-01-11 03:39:11 +00005040/* Return new datetime from date/datetime and time arguments. */
5041static PyObject *
5042datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
5043{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005044 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005045 PyObject *date;
5046 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005047 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005048 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00005049
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005050 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005051 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005052 &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 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005059 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005069 }
5070 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005071}
Tim Peters2a799bf2002-12-16 20:18:38 +00005072
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005073static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005074_sanitize_isoformat_str(PyObject *dtstr)
5075{
Paul Ganssle096329f2018-08-23 11:06:20 -04005076 // `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`.
Paul Ganssle3df85402018-10-22 12:32:52 -04005080 //
5081 // The result of this, if not NULL, returns a new reference
Paul Ganssle096329f2018-08-23 11:06:20 -04005082 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005083 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);
Paul Ganssle096329f2018-08-23 11:06:20 -04005090 return dtstr;
5091 }
5092
Paul Ganssle3df85402018-10-22 12:32:52 -04005093 PyObject *str_out = _PyUnicode_Copy(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005094 if (str_out == NULL) {
5095 return NULL;
5096 }
5097
Paul Ganssle3df85402018-10-22 12:32:52 -04005098 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005099 Py_DECREF(str_out);
5100 return NULL;
5101 }
5102
Paul Ganssle096329f2018-08-23 11:06:20 -04005103 return str_out;
5104}
5105
5106static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005107datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5108{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005109 assert(dtstr != NULL);
5110
5111 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005112 PyErr_SetString(PyExc_TypeError,
5113 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005114 return NULL;
5115 }
5116
Paul Ganssle3df85402018-10-22 12:32:52 -04005117 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5118 if (dtstr_clean == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005119 goto error;
5120 }
5121
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005122 Py_ssize_t len;
Paul Ganssle3df85402018-10-22 12:32:52 -04005123 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04005124
5125 if (dt_ptr == NULL) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005126 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 }
Paul Ganssle096329f2018-08-23 11:06:20 -04005133 }
5134
5135 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005136
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;
Paul Ganssle3df85402018-10-22 12:32:52 -04005148 }
5149 else {
5150 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005151 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);
Paul Ganssle3df85402018-10-22 12:32:52 -04005164 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5165 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005166 }
5167 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005168 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005169 }
5170
Paul Ganssle3df85402018-10-22 12:32:52 -04005171 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005172 if (tzinfo == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005173 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005174 }
5175
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005176 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5177 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005178
5179 Py_DECREF(tzinfo);
Paul Ganssle3df85402018-10-22 12:32:52 -04005180 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005181 return dt;
Paul Ganssle096329f2018-08-23 11:06:20 -04005182
5183invalid_string_error:
5184 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5185
5186error:
Paul Ganssle3df85402018-10-22 12:32:52 -04005187 Py_XDECREF(dtstr_clean);
Paul Ganssle096329f2018-08-23 11:06:20 -04005188
5189 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005190}
5191
Tim Peters2a799bf2002-12-16 20:18:38 +00005192/*
5193 * Destructor.
5194 */
5195
5196static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005197datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005199 if (HASTZINFO(self)) {
5200 Py_XDECREF(self->tzinfo);
5201 }
5202 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005203}
5204
5205/*
5206 * Indirect access to tzinfo methods.
5207 */
5208
Tim Peters2a799bf2002-12-16 20:18:38 +00005209/* These are all METH_NOARGS, so don't need to check the arglist. */
5210static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005211datetime_utcoffset(PyObject *self, PyObject *unused) {
5212 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005213}
5214
5215static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005216datetime_dst(PyObject *self, PyObject *unused) {
5217 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005218}
5219
5220static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005221datetime_tzname(PyObject *self, PyObject *unused) {
5222 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005223}
5224
5225/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005226 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005227 */
5228
Tim Petersa9bc1682003-01-11 03:39:11 +00005229/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5230 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005231 */
5232static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005233add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005234 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005235{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005236 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00005247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005248 assert(factor == 1 || factor == -1);
5249 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005250 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005251 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005252 }
5253
Paul Ganssle89427cd2019-02-04 14:42:04 -05005254 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));
Tim Peters2a799bf2002-12-16 20:18:38 +00005258}
5259
5260static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005261datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005263 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 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005278 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005279}
5280
5281static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005282datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005284 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005286 if (PyDateTime_Check(left)) {
5287 /* datetime - ??? */
5288 if (PyDateTime_Check(right)) {
5289 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005290 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005291 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005292
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005293 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5294 offset2 = offset1 = Py_None;
5295 Py_INCREF(offset1);
5296 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005297 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005298 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005327 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005345 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005346 if (result == NULL)
5347 return NULL;
5348
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005349 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005350 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005351 Py_DECREF(offdiff);
5352 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005353 }
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 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005363 if (result == Py_NotImplemented)
5364 Py_INCREF(result);
5365 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005366}
5367
5368/* Various ways to turn a datetime into a string. */
5369
5370static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005371datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005373 const char *type_name = Py_TYPE(self)->tp_name;
5374 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005376 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 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005400 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5401 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005402 if (baserepr == NULL || ! HASTZINFO(self))
5403 return baserepr;
5404 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005405}
5406
Tim Petersa9bc1682003-01-11 03:39:11 +00005407static PyObject *
5408datetime_str(PyDateTime_DateTime *self)
5409{
Victor Stinner4c381542016-12-09 00:33:39 +01005410 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005411}
Tim Peters2a799bf2002-12-16 20:18:38 +00005412
5413static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005414datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005416 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005417 char *timespec = NULL;
5418 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005419 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005420 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005421 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005422 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00005430
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005431 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005432 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005433
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],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005461 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);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005465 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005467 if (!result || !HASTZINFO(self))
5468 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005470 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00005478}
5479
Tim Petersa9bc1682003-01-11 03:39:11 +00005480static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305481datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005482{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005483 return format_ctime((PyDateTime_Date *)self,
5484 DATE_GET_HOUR(self),
5485 DATE_GET_MINUTE(self),
5486 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005487}
5488
Tim Peters2a799bf2002-12-16 20:18:38 +00005489/* Miscellaneous methods. */
5490
Tim Petersa9bc1682003-01-11 03:39:11 +00005491static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005492flip_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
5507static PyObject *
5508get_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
Serhiy Storchakabac2d5b2018-03-28 22:14:26 +03005522 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005523 *
5524 * Return 1 if exception applies, 0 if not, and -1 on error.
5525 */
5526static int
5527pep495_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
5555static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005556datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005557{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005558 PyObject *result = NULL;
5559 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005560 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005562 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 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005577 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005578 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005579
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005580 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005581 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5582 ((PyDateTime_DateTime *)other)->data,
5583 _PyDateTime_DATETIME_DATASIZE);
5584 return diff_to_bool(diff, op);
5585 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005586 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);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005602 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 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005609 result = diff_to_bool(diff, op);
5610 }
5611 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005612 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005613
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005614 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005615 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5616 other);
5617 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005618 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005619 diff = GET_TD_DAYS(delta);
5620 if (diff == 0)
5621 diff = GET_TD_SECONDS(delta) |
5622 GET_TD_MICROSECONDS(delta);
5623 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005624 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 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005631 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005632 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005633 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 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005641 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;
Tim Petersa9bc1682003-01-11 03:39:11 +00005650}
5651
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005652static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005653datetime_hash(PyDateTime_DateTime *self)
5654{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005655 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005656 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);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005676
5677 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005678 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005680 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005681 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005682 self->hashcode = generic_hash(
5683 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005684 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005685 PyObject *temp1, *temp2;
5686 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005688 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 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005693 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005694 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005695 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005710 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005711 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005712 }
5713 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005714}
Tim Peters2a799bf2002-12-16 20:18:38 +00005715
5716static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005717datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005719 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;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005729 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005730
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005731 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005732 datetime_kws,
5733 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005734 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005735 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005736 if (fold != 0 && fold != 1) {
5737 PyErr_SetString(PyExc_ValueError,
5738 "fold must be either 0 or 1");
5739 return NULL;
5740 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005741 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);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005745 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005746 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005747 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005748 Py_DECREF(tuple);
5749 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005750}
5751
5752static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005753local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005754{
5755 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005756 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005757 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005758 PyObject *nameo = NULL;
5759 const char *zone = NULL;
5760
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005761 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005762 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005763#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005764 zone = local_time_tm.tm_zone;
5765 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005766#else /* HAVE_STRUCT_TM_TM_ZONE */
5767 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005768 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005769 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005770 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005771 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005772 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005773 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);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005779 if (local_time == NULL) {
5780 return NULL;
5781 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005782 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005783 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005784 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);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005790 if (utc_time == NULL) {
5791 Py_DECREF(local_time);
5792 return NULL;
5793 }
5794 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005795 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005796 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005797 }
5798#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005799 if (delta == NULL) {
5800 return NULL;
5801 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005802 if (zone != NULL) {
5803 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5804 if (nameo == NULL)
5805 goto error;
5806 }
5807 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005808 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005809 error:
5810 Py_DECREF(delta);
5811 return result;
5812}
5813
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005814static PyObject *
5815local_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
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005843static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005844local_to_seconds(int year, int month, int day,
5845 int hour, int minute, int second, int fold);
5846
5847static PyObject *
5848local_timezone_from_local(PyDateTime_DateTime *local_dt)
5849{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005850 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005851 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
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005866static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005867datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005868{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005869 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005870 PyObject *offset;
5871 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005872 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005873 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005874 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005875
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005876 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005877 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005878 return NULL;
5879
5880 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005881 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005882
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005883 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005884 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005885 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 }
Tim Peters521fc152002-12-31 17:36:56 +00005892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005893 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005894 if (self_tzinfo == tzinfo) {
5895 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005896 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005897 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005898 }
Tim Peters521fc152002-12-31 17:36:56 +00005899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005900 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005901 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5902 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005903 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005904 return NULL;
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005905 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 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005915 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005916 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5917 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005918 Py_DECREF(offset);
5919 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005920 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005921
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005922 /* 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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005948 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005949 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005950 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);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005959 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005960 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005961
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005962 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005963 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005964 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005965 Py_DECREF(temp);
5966
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005967 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005968}
5969
5970static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305971datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00005972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005973 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005975 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005976 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005977
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005978 dst = call_dst(self->tzinfo, (PyObject *)self);
5979 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005980 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005981
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005982 if (dst != Py_None)
5983 dstflag = delta_bool((PyDateTime_Delta *)dst);
5984 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005985 }
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);
Tim Peters2a799bf2002-12-16 20:18:38 +00005993}
5994
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005995static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005996local_to_seconds(int year, int month, int day,
5997 int hour, int minute, int second, int fold)
5998{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005999 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006000 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
Tim Peters2a799bf2002-12-16 20:18:38 +00006045static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306046datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolskya4415142012-06-08 12:33:09 -04006047{
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;
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306055 result = delta_total_seconds(delta, NULL);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006056 Py_DECREF(delta);
6057 }
6058 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006059 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006060 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)
Alexander Belopolskya4415142012-06-08 12:33:09 -04006068 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006069 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
6070 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006071 }
6072 return result;
6073}
6074
6075static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306076datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006078 return new_date(GET_YEAR(self),
6079 GET_MONTH(self),
6080 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006081}
6082
6083static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306084datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006085{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006086 return new_time(DATE_GET_HOUR(self),
6087 DATE_GET_MINUTE(self),
6088 DATE_GET_SECOND(self),
6089 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006090 Py_None,
6091 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006092}
6093
6094static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306095datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006097 return new_time(DATE_GET_HOUR(self),
6098 DATE_GET_MINUTE(self),
6099 DATE_GET_SECOND(self),
6100 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006101 GET_DT_TZINFO(self),
6102 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006103}
6104
6105static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306106datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006107{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006108 int y, m, d, hh, mm, ss;
6109 PyObject *tzinfo;
6110 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006111
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006112 tzinfo = GET_DT_TZINFO(self);
6113 if (tzinfo == Py_None) {
6114 utcself = self;
6115 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006116 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006117 else {
6118 PyObject *offset;
6119 offset = call_utcoffset(tzinfo, (PyObject *)self);
6120 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006121 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006122 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 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006134 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006135 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006143 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006144}
6145
Tim Peters371935f2003-02-01 01:52:50 +00006146/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006147
Tim Petersa9bc1682003-01-11 03:39:11 +00006148/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006149 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6150 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006151 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006152 */
6153static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006154datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006155{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006156 PyObject *basestate;
6157 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006159 basestate = PyBytes_FromStringAndSize((char *)self->data,
6160 _PyDateTime_DATETIME_DATASIZE);
6161 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006162 if (proto > 3 && DATE_GET_FOLD(self))
6163 /* Set the first bit of the third byte */
6164 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006165 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00006172}
6173
6174static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006175datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006176{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006177 int proto;
6178 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006179 return NULL;
6180
6181 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006182}
6183
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006184static PyObject *
6185datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6186{
6187 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6188}
6189
Tim Petersa9bc1682003-01-11 03:39:11 +00006190static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006192 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006193
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006194 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006196 {"utcnow", (PyCFunction)datetime_utcnow,
6197 METH_NOARGS | METH_CLASS,
6198 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006199
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006200 {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006201 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6202 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006204 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6205 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006206 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006208 {"strptime", (PyCFunction)datetime_strptime,
6209 METH_VARARGS | METH_CLASS,
6210 PyDoc_STR("string, format -> new datetime parsed from a string "
6211 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006212
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006213 {"combine", (PyCFunction)(void(*)(void))datetime_combine,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006214 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6215 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006216
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006217 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6218 METH_O | METH_CLASS,
6219 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006221 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006223 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6224 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006226 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6227 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006229 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6230 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006232 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6233 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006235 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6236 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006237
Alexander Belopolskya4415142012-06-08 12:33:09 -04006238 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6239 PyDoc_STR("Return POSIX timestamp as float.")},
6240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006241 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6242 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006243
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006244 {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006245 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006246 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006247 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006248 "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")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006253 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6254 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006256 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6257 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006259 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6260 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006261
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006262 {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006263 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006264
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006265 {"astimezone", (PyCFunction)(void(*)(void))datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006266 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006267
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006268 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006269 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006270
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006271 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6272 PyDoc_STR("__reduce__() -> (cls, state)")},
6273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006274 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006275};
6276
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006277static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006278PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6279\n\
6280The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006281instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006282
Tim Petersa9bc1682003-01-11 03:39:11 +00006283static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006284 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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00006294};
6295
Neal Norwitz227b5332006-03-22 09:28:35 +00006296static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006297 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 */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006302 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006303 0, /* tp_getattr */
6304 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006305 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006306 (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 */
Tim Peters2a799bf2002-12-16 20:18:38 +00006336};
6337
6338/* ---------------------------------------------------------------------------
6339 * Module methods and initialization.
6340 */
6341
6342static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006343 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006344};
6345
Tim Peters9ddf40b2004-06-20 22:41:32 +00006346/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6347 * datetime.h.
6348 */
6349static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006350 &PyDateTime_DateType,
6351 &PyDateTime_DateTimeType,
6352 &PyDateTime_TimeType,
6353 &PyDateTime_DeltaType,
6354 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006355 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006356 new_date_ex,
6357 new_datetime_ex,
6358 new_time_ex,
6359 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006360 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006361 datetime_fromtimestamp,
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04006362 datetime_date_fromtimestamp_capi,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006363 new_datetime_ex2,
6364 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006365};
6366
6367
Martin v. Löwis1a214512008-06-11 05:26:20 +00006368
6369static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006370 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006371 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006372 "Fast implementation of the datetime type.",
6373 -1,
6374 module_methods,
6375 NULL,
6376 NULL,
6377 NULL,
6378 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006379};
6380
Tim Peters2a799bf2002-12-16 20:18:38 +00006381PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006382PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006384 PyObject *m; /* a module object */
6385 PyObject *d; /* its dict */
6386 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006387 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006389 m = PyModule_Create(&datetimemodule);
6390 if (m == NULL)
6391 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006393 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;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006403 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6404 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006406 /* timedelta values */
6407 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006409 x = new_delta(0, 0, 1, 0);
6410 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6411 return NULL;
6412 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006414 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);
Tim Peters2a799bf2002-12-16 20:18:38 +00006418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006419 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);
Tim Peters2a799bf2002-12-16 20:18:38 +00006423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006424 /* date values */
6425 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006427 x = new_date(1, 1, 1);
6428 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6429 return NULL;
6430 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006432 x = new_date(MAXYEAR, 12, 31);
6433 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6434 return NULL;
6435 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006437 x = new_delta(1, 0, 0, 0);
6438 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6439 return NULL;
6440 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006442 /* time values */
6443 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006444
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006445 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006446 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6447 return NULL;
6448 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006449
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006450 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006451 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6452 return NULL;
6453 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006455 x = new_delta(0, 0, 1, 0);
6456 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6457 return NULL;
6458 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006460 /* datetime values */
6461 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006462
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006463 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006464 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6465 return NULL;
6466 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006467
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006468 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006469 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6470 return NULL;
6471 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006473 x = new_delta(0, 0, 1, 0);
6474 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6475 return NULL;
6476 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006477
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006478 /* timezone values */
6479 d = PyDateTime_TimeZoneType.tp_dict;
6480
6481 delta = new_delta(0, 0, 0, 0);
6482 if (delta == NULL)
6483 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006484 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006485 Py_DECREF(delta);
6486 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6487 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006488 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006489 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006490
Paul Ganssle27b38b92019-08-15 15:08:57 -04006491 /* 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.*/
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006494 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6495 if (delta == NULL)
6496 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006497 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006498 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;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006506 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006507 Py_DECREF(delta);
6508 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6509 return NULL;
6510 Py_DECREF(x);
6511
Alexander Belopolskya4415142012-06-08 12:33:09 -04006512 /* Epoch */
6513 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006514 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006515 if (PyDateTime_Epoch == NULL)
6516 return NULL;
6517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006518 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006519 PyModule_AddIntMacro(m, MINYEAR);
6520 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006522 Py_INCREF(&PyDateTime_DateType);
6523 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006525 Py_INCREF(&PyDateTime_DateTimeType);
6526 PyModule_AddObject(m, "datetime",
6527 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006529 Py_INCREF(&PyDateTime_TimeType);
6530 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006532 Py_INCREF(&PyDateTime_DeltaType);
6533 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006535 Py_INCREF(&PyDateTime_TZInfoType);
6536 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006537
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006538 Py_INCREF(&PyDateTime_TimeZoneType);
6539 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006541 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6542 if (x == NULL)
6543 return NULL;
6544 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006546 /* A 4-year cycle has an extra leap day over what we'd get from
6547 * pasting together 4 single years.
6548 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006549 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006550 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006552 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6553 * get from pasting together 4 100-year cycles.
6554 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006555 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006556 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006558 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6559 * pasting together 25 4-year cycles.
6560 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006561 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006562 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006564 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);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006568 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006569 us_per_minute == NULL || seconds_per_day == NULL)
6570 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006572 /* 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;
Tim Peters2a799bf2002-12-16 20:18:38 +00006581}
Tim Petersf3615152003-01-01 21:51:37 +00006582
6583/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006584Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006585 x.n = x stripped of its timezone -- its naive time.
6586 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006587 return None
Tim Petersf3615152003-01-01 21:51:37 +00006588 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006589 return None
Tim Petersf3615152003-01-01 21:51:37 +00006590 x.s = x's standard offset, x.o - x.d
6591
6592Now some derived rules, where k is a duration (timedelta).
6593
65941. x.o = x.s + x.d
6595 This follows from the definition of x.s.
6596
Tim Petersc5dc4da2003-01-02 17:55:03 +000065972. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006598 This is actually a requirement, an assumption we need to make about
6599 sane tzinfo classes.
6600
66013. The naive UTC time corresponding to x is x.n - x.o.
6602 This is again a requirement for a sane tzinfo class.
6603
66044. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006605 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006606
Tim Petersc5dc4da2003-01-02 17:55:03 +000066075. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006608 Again follows from how arithmetic is defined.
6609
Tim Peters8bb5ad22003-01-24 02:44:45 +00006610Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006611(meaning that the various tzinfo methods exist, and don't blow up or return
6612None when called).
6613
Tim Petersa9bc1682003-01-11 03:39:11 +00006614The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006615x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006616
6617By #3, we want
6618
Tim Peters8bb5ad22003-01-24 02:44:45 +00006619 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006620
6621The algorithm starts by attaching tz to x.n, and calling that y. So
6622x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6623becomes true; in effect, we want to solve [2] for k:
6624
Tim Peters8bb5ad22003-01-24 02:44:45 +00006625 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006626
6627By #1, this is the same as
6628
Tim Peters8bb5ad22003-01-24 02:44:45 +00006629 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006630
6631By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6632Substituting that into [3],
6633
Tim Peters8bb5ad22003-01-24 02:44:45 +00006634 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
Tim Petersf3615152003-01-01 21:51:37 +00006638
Tim Peters8bb5ad22003-01-24 02:44:45 +00006639On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6640approximate k by ignoring the (y+k).d term at first. Note that k can't be
6641very large, since all offset-returning methods return a duration of magnitude
6642less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6643be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006644
6645In any case, the new value is
6646
Tim Peters8bb5ad22003-01-24 02:44:45 +00006647 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006648
Tim Peters8bb5ad22003-01-24 02:44:45 +00006649It's helpful to step back at look at [4] from a higher level: it's simply
6650mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006651
6652At this point, if
6653
Tim Peters8bb5ad22003-01-24 02:44:45 +00006654 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006655
6656we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006657at the start of daylight time. Picture US Eastern for concreteness. The wall
6658time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
Tim Peters8bb5ad22003-01-24 02:44:45 +00006659sense then. The docs ask that an Eastern tzinfo class consider such a time to
6660be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6661on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006662the only spelling that makes sense on the local wall clock.
6663
Tim Petersc5dc4da2003-01-02 17:55:03 +00006664In fact, if [5] holds at this point, we do have the standard-time spelling,
6665but that takes a bit of proof. We first prove a stronger result. What's the
6666difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006667
Tim Peters8bb5ad22003-01-24 02:44:45 +00006668 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006669
Tim Petersc5dc4da2003-01-02 17:55:03 +00006670Now
6671 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006672 (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
Tim Petersf3615152003-01-01 21:51:37 +00006677
Tim Petersc5dc4da2003-01-02 17:55:03 +00006678Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006679
Tim Petersc5dc4da2003-01-02 17:55:03 +00006680 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006681 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
Tim Petersc5dc4da2003-01-02 17:55:03 +00006684 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006685
Tim Petersc5dc4da2003-01-02 17:55:03 +00006686So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006687
Tim Petersc5dc4da2003-01-02 17:55:03 +00006688If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006689spelling we wanted in the endcase described above. We're done. Contrarily,
6690if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006691
Tim Petersc5dc4da2003-01-02 17:55:03 +00006692If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6693add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006694local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006695
Tim Petersc5dc4da2003-01-02 17:55:03 +00006696Let
Tim Petersf3615152003-01-01 21:51:37 +00006697
Tim Peters4fede1a2003-01-04 00:26:59 +00006698 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006699
Tim Peters4fede1a2003-01-04 00:26:59 +00006700and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006701
Tim Peters8bb5ad22003-01-24 02:44:45 +00006702 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006703
Tim Peters8bb5ad22003-01-24 02:44:45 +00006704If so, we're done. If not, the tzinfo class is insane, according to the
6705assumptions we've made. This also requires a bit of proof. As before, let's
6706compute the difference between the LHS and RHS of [8] (and skipping some of
6707the justifications for the kinds of substitutions we've done several times
6708already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006709
Tim Peters8bb5ad22003-01-24 02:44:45 +00006710 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006711 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
Tim Peters4fede1a2003-01-04 00:26:59 +00006718
6719So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
Tim Peters8bb5ad22003-01-24 02:44:45 +00006720we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6721return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006722
Tim Peters8bb5ad22003-01-24 02:44:45 +00006723How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6724a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6725would have to change the result dst() returns: we start in DST, and moving
6726a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006727
Tim Peters8bb5ad22003-01-24 02:44:45 +00006728There isn't a sane case where this can happen. The closest it gets is at
6729the end of DST, where there's an hour in UTC with no spelling in a hybrid
6730tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6731that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6732UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6733time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6734clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6735standard time. Since that's what the local clock *does*, we want to map both
6736UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006737in local time, but so it goes -- it's the way the local clock works.
6738
Tim Peters8bb5ad22003-01-24 02:44:45 +00006739When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6740so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6741z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
Tim Peters4fede1a2003-01-04 00:26:59 +00006742(correctly) concludes that z' is not UTC-equivalent to x.
6743
6744Because we know z.d said z was in daylight time (else [5] would have held and
6745we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006746and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006747return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6748but the reasoning doesn't depend on the example -- it depends on there being
6749two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006750z' must be in standard time, and is the spelling we want in this case.
6751
6752Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6753concerned (because it takes z' as being in standard time rather than the
6754daylight time we intend here), but returning it gives the real-life "local
6755clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6756tz.
6757
6758When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6759the 1:MM standard time spelling we want.
6760
6761So how can this break? One of the assumptions must be violated. Two
6762possibilities:
6763
67641) [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
67682) 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
6772In 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
6774doesn't matter if daylight time transition points change from year to year, or
6775if daylight time is skipped in some years; it doesn't matter how large or
6776small dst() may get within its bounds; and it doesn't even matter if some
6777perverse time zone returns a negative dst()). So a breaking case must be
6778pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006779--------------------------------------------------------------------------- */