blob: c1b24073436e63f6a0c516e60bd5b16e9c474527 [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
Pablo Galindo4be11c02019-08-22 20:24:25 +010035#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 }
Ngalim Siregar92c7e302019-08-09 21:22:16 +07001103 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)) {
Ngalim Siregar92c7e302019-08-09 21:22:16 +07001175 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
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001245 result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001246
1247 if (result == NULL || result == Py_None)
1248 return result;
1249
1250 if (!PyUnicode_Check(result)) {
1251 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1252 "return None or a string, not '%s'",
1253 Py_TYPE(result)->tp_name);
1254 Py_DECREF(result);
1255 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001257
1258 return result;
Tim Peters00237032002-12-27 02:21:51 +00001259}
1260
Tim Peters2a799bf2002-12-16 20:18:38 +00001261/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1262 * stuff
1263 * ", tzinfo=" + repr(tzinfo)
1264 * before the closing ")".
1265 */
1266static PyObject *
1267append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 assert(PyUnicode_Check(repr));
1272 assert(tzinfo);
1273 if (tzinfo == Py_None)
1274 return repr;
1275 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001276 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1277 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 Py_DECREF(repr);
1279 if (temp == NULL)
1280 return NULL;
1281 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1282 Py_DECREF(temp);
1283 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001284}
1285
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001286/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1287 * stuff
1288 * ", fold=" + repr(tzinfo)
1289 * before the closing ")".
1290 */
1291static PyObject *
1292append_keyword_fold(PyObject *repr, int fold)
1293{
1294 PyObject *temp;
1295
1296 assert(PyUnicode_Check(repr));
1297 if (fold == 0)
1298 return repr;
1299 /* Get rid of the trailing ')'. */
1300 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1301 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1302 Py_DECREF(repr);
1303 if (temp == NULL)
1304 return NULL;
1305 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1306 Py_DECREF(temp);
1307 return repr;
1308}
1309
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001310static inline PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04001311tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
1312{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001313 PyObject *tzinfo;
1314 if (rv == 1) {
1315 // Create a timezone from offset in seconds (0 returns UTC)
1316 if (tzoffset == 0) {
1317 Py_INCREF(PyDateTime_TimeZone_UTC);
1318 return PyDateTime_TimeZone_UTC;
1319 }
1320
1321 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001322 if (delta == NULL) {
1323 return NULL;
1324 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001325 tzinfo = new_timezone(delta, NULL);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001326 Py_DECREF(delta);
Paul Ganssle3df85402018-10-22 12:32:52 -04001327 }
1328 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001329 tzinfo = Py_None;
1330 Py_INCREF(Py_None);
1331 }
1332
1333 return tzinfo;
1334}
1335
Tim Peters2a799bf2002-12-16 20:18:38 +00001336/* ---------------------------------------------------------------------------
1337 * String format helpers.
1338 */
1339
1340static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001341format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001342{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001343 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1345 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001346 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1348 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1349 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1354 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1355 GET_DAY(date), hours, minutes, seconds,
1356 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001357}
1358
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001359static PyObject *delta_negative(PyDateTime_Delta *self);
1360
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001361/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001362 * buflen bytes remaining. The UTC offset is gotten by calling
1363 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1364 * *buf, and that's all. Else the returned value is checked for sanity (an
1365 * integer in range), and if that's OK it's converted to an hours & minutes
1366 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001367 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001368 * Returns 0 if everything is OK. If the return value from utcoffset() is
1369 * bogus, an appropriate exception is set and -1 is returned.
1370 */
1371static int
Tim Peters328fff72002-12-20 01:31:27 +00001372format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001374{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001375 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001376 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001380
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001381 offset = call_utcoffset(tzinfo, tzinfoarg);
1382 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001384 if (offset == Py_None) {
1385 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 *buf = '\0';
1387 return 0;
1388 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001389 /* Offset is normalized, so it is negative if days < 0 */
1390 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001392 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001393 if (offset == NULL)
1394 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001396 else {
1397 sign = '+';
1398 }
1399 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001400 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001401 seconds = GET_TD_SECONDS(offset);
1402 Py_DECREF(offset);
1403 minutes = divmod(seconds, 60, &seconds);
1404 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001405 if (microseconds) {
1406 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1407 hours, sep, minutes, sep, seconds, microseconds);
1408 return 0;
1409 }
1410 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001411 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1412 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001413 return 0;
1414 }
1415 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001417}
1418
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001419static PyObject *
1420make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 PyObject *temp;
1423 PyObject *tzinfo = get_tzinfo_member(object);
1424 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001425 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 if (Zreplacement == NULL)
1428 return NULL;
1429 if (tzinfo == Py_None || tzinfo == NULL)
1430 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 assert(tzinfoarg != NULL);
1433 temp = call_tzname(tzinfo, tzinfoarg);
1434 if (temp == NULL)
1435 goto Error;
1436 if (temp == Py_None) {
1437 Py_DECREF(temp);
1438 return Zreplacement;
1439 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 assert(PyUnicode_Check(temp));
1442 /* Since the tzname is getting stuffed into the
1443 * format, we have to double any % signs so that
1444 * strftime doesn't treat them as format codes.
1445 */
1446 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001447 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 Py_DECREF(temp);
1449 if (Zreplacement == NULL)
1450 return NULL;
1451 if (!PyUnicode_Check(Zreplacement)) {
1452 PyErr_SetString(PyExc_TypeError,
1453 "tzname.replace() did not return a string");
1454 goto Error;
1455 }
1456 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001457
1458 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 Py_DECREF(Zreplacement);
1460 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001461}
1462
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001463static PyObject *
1464make_freplacement(PyObject *object)
1465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 char freplacement[64];
1467 if (PyTime_Check(object))
1468 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1469 else if (PyDateTime_Check(object))
1470 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1471 else
1472 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001475}
1476
Tim Peters2a799bf2002-12-16 20:18:38 +00001477/* I sure don't want to reproduce the strftime code from the time module,
1478 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001479 * giving special meanings to the %z, %Z and %f format codes via a
1480 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001481 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1482 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001483 */
1484static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001485wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1491 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1492 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 const char *pin; /* pointer to next char in input format */
1495 Py_ssize_t flen; /* length of input format */
1496 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 PyObject *newfmt = NULL; /* py string, the output format */
1499 char *pnew; /* pointer to available byte in output format */
1500 size_t totalnew; /* number bytes total in output format buffer,
1501 exclusive of trailing \0 */
1502 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 const char *ptoappend; /* ptr to string to append to output buffer */
1505 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 assert(object && format && timetuple);
1508 assert(PyUnicode_Check(format));
1509 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001510 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 if (!pin)
1512 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 /* Scan the input format, looking for %z/%Z/%f escapes, building
1515 * a new format. Since computing the replacements for those codes
1516 * is expensive, don't unless they're actually used.
1517 */
1518 if (flen > INT_MAX - 1) {
1519 PyErr_NoMemory();
1520 goto Done;
1521 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 totalnew = flen + 1; /* realistic if no %z/%Z */
1524 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1525 if (newfmt == NULL) goto Done;
1526 pnew = PyBytes_AsString(newfmt);
1527 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 while ((ch = *pin++) != '\0') {
1530 if (ch != '%') {
1531 ptoappend = pin - 1;
1532 ntoappend = 1;
1533 }
1534 else if ((ch = *pin++) == '\0') {
Victor Stinner2ff58a22019-06-17 14:27:23 +02001535 /* Null byte follows %, copy only '%'.
1536 *
MichaelSaah454b3d42019-01-14 05:23:39 -05001537 * Back the pin up one char so that we catch the null check
1538 * the next time through the loop.*/
1539 pin--;
1540 ptoappend = pin - 1;
1541 ntoappend = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 }
1543 /* A % has been seen and ch is the character after it. */
1544 else if (ch == 'z') {
1545 if (zreplacement == NULL) {
1546 /* format utcoffset */
1547 char buf[100];
1548 PyObject *tzinfo = get_tzinfo_member(object);
1549 zreplacement = PyBytes_FromStringAndSize("", 0);
1550 if (zreplacement == NULL) goto Done;
1551 if (tzinfo != Py_None && tzinfo != NULL) {
1552 assert(tzinfoarg != NULL);
1553 if (format_utcoffset(buf,
1554 sizeof(buf),
1555 "",
1556 tzinfo,
1557 tzinfoarg) < 0)
1558 goto Done;
1559 Py_DECREF(zreplacement);
1560 zreplacement =
1561 PyBytes_FromStringAndSize(buf,
1562 strlen(buf));
1563 if (zreplacement == NULL)
1564 goto Done;
1565 }
1566 }
1567 assert(zreplacement != NULL);
1568 ptoappend = PyBytes_AS_STRING(zreplacement);
1569 ntoappend = PyBytes_GET_SIZE(zreplacement);
1570 }
1571 else if (ch == 'Z') {
1572 /* format tzname */
1573 if (Zreplacement == NULL) {
1574 Zreplacement = make_Zreplacement(object,
1575 tzinfoarg);
1576 if (Zreplacement == NULL)
1577 goto Done;
1578 }
1579 assert(Zreplacement != NULL);
1580 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001581 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001583 if (ptoappend == NULL)
1584 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 }
1586 else if (ch == 'f') {
1587 /* format microseconds */
1588 if (freplacement == NULL) {
1589 freplacement = make_freplacement(object);
1590 if (freplacement == NULL)
1591 goto Done;
1592 }
1593 assert(freplacement != NULL);
1594 assert(PyBytes_Check(freplacement));
1595 ptoappend = PyBytes_AS_STRING(freplacement);
1596 ntoappend = PyBytes_GET_SIZE(freplacement);
1597 }
1598 else {
1599 /* percent followed by neither z nor Z */
1600 ptoappend = pin - 2;
1601 ntoappend = 2;
1602 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 /* Append the ntoappend chars starting at ptoappend to
1605 * the new format.
1606 */
1607 if (ntoappend == 0)
1608 continue;
1609 assert(ptoappend != NULL);
1610 assert(ntoappend > 0);
1611 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001612 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 PyErr_NoMemory();
1614 goto Done;
1615 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001616 totalnew <<= 1;
1617 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 pnew = PyBytes_AsString(newfmt) + usednew;
1620 }
1621 memcpy(pnew, ptoappend, ntoappend);
1622 pnew += ntoappend;
1623 usednew += ntoappend;
1624 assert(usednew <= totalnew);
1625 } /* end while() */
Victor Stinner2ff58a22019-06-17 14:27:23 +02001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1628 goto Done;
1629 {
1630 PyObject *format;
1631 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 if (time == NULL)
1634 goto Done;
1635 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1636 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001637 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1638 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 Py_DECREF(format);
1640 }
1641 Py_DECREF(time);
1642 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001643 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 Py_XDECREF(freplacement);
1645 Py_XDECREF(zreplacement);
1646 Py_XDECREF(Zreplacement);
1647 Py_XDECREF(newfmt);
1648 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001649}
1650
Tim Peters2a799bf2002-12-16 20:18:38 +00001651/* ---------------------------------------------------------------------------
1652 * Wrap functions from the time module. These aren't directly available
1653 * from C. Perhaps they should be.
1654 */
1655
1656/* Call time.time() and return its result (a Python float). */
1657static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001658time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 PyObject *result = NULL;
1661 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001664 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001665
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001666 result = _PyObject_CallMethodIdNoArgs(time, &PyId_time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 Py_DECREF(time);
1668 }
1669 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001670}
1671
1672/* Build a time.struct_time. The weekday and day number are automatically
1673 * computed from the y,m,d args.
1674 */
1675static PyObject *
1676build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001679 PyObject *result;
1680 _Py_IDENTIFIER(struct_time);
1681 PyObject *args;
1682
Tim Peters2a799bf2002-12-16 20:18:38 +00001683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001685 if (time == NULL) {
1686 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 }
Victor Stinner2b635972016-12-09 00:38:16 +01001688
1689 args = Py_BuildValue("iiiiiiiii",
1690 y, m, d,
1691 hh, mm, ss,
1692 weekday(y, m, d),
1693 days_before_month(y, m) + d,
1694 dstflag);
1695 if (args == NULL) {
1696 Py_DECREF(time);
1697 return NULL;
1698 }
1699
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001700 result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args);
Victor Stinner2b635972016-12-09 00:38:16 +01001701 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001702 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001704}
1705
1706/* ---------------------------------------------------------------------------
1707 * Miscellaneous helpers.
1708 */
1709
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001710/* The comparisons here all most naturally compute a cmp()-like result.
Tim Peters2a799bf2002-12-16 20:18:38 +00001711 * This little helper turns that into a bool result for rich comparisons.
1712 */
1713static PyObject *
1714diff_to_bool(int diff, int op)
1715{
stratakise8b19652017-11-02 11:32:54 +01001716 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001717}
1718
Tim Peters07534a62003-02-07 22:50:28 +00001719/* Raises a "can't compare" TypeError and returns NULL. */
1720static PyObject *
1721cmperror(PyObject *a, PyObject *b)
1722{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001723 PyErr_Format(PyExc_TypeError,
1724 "can't compare %s to %s",
1725 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1726 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001727}
1728
Tim Peters2a799bf2002-12-16 20:18:38 +00001729/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001730 * Cached Python objects; these are set by the module init function.
1731 */
1732
1733/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001734static PyObject *us_per_ms = NULL; /* 1000 */
1735static PyObject *us_per_second = NULL; /* 1000000 */
1736static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001737static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1738static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1739static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001740static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1741
Tim Peters2a799bf2002-12-16 20:18:38 +00001742/* ---------------------------------------------------------------------------
1743 * Class implementations.
1744 */
1745
1746/*
1747 * PyDateTime_Delta implementation.
1748 */
1749
1750/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001752 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001753 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1754 * due to ubiquitous overflow possibilities.
1755 */
1756static PyObject *
1757delta_to_microseconds(PyDateTime_Delta *self)
1758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 PyObject *x1 = NULL;
1760 PyObject *x2 = NULL;
1761 PyObject *x3 = NULL;
1762 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1765 if (x1 == NULL)
1766 goto Done;
1767 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1768 if (x2 == NULL)
1769 goto Done;
1770 Py_DECREF(x1);
1771 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 /* x2 has days in seconds */
1774 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1775 if (x1 == NULL)
1776 goto Done;
1777 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1778 if (x3 == NULL)
1779 goto Done;
1780 Py_DECREF(x1);
1781 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001782 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 /* x3 has days+seconds in seconds */
1785 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1786 if (x1 == NULL)
1787 goto Done;
1788 Py_DECREF(x3);
1789 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 /* x1 has days+seconds in us */
1792 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1793 if (x2 == NULL)
1794 goto Done;
1795 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001796 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001797
1798Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 Py_XDECREF(x1);
1800 Py_XDECREF(x2);
1801 Py_XDECREF(x3);
1802 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001803}
1804
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001805static PyObject *
1806checked_divmod(PyObject *a, PyObject *b)
1807{
1808 PyObject *result = PyNumber_Divmod(a, b);
1809 if (result != NULL) {
1810 if (!PyTuple_Check(result)) {
1811 PyErr_Format(PyExc_TypeError,
1812 "divmod() returned non-tuple (type %.200s)",
1813 result->ob_type->tp_name);
1814 Py_DECREF(result);
1815 return NULL;
1816 }
1817 if (PyTuple_GET_SIZE(result) != 2) {
1818 PyErr_Format(PyExc_TypeError,
1819 "divmod() returned a tuple of size %zd",
1820 PyTuple_GET_SIZE(result));
1821 Py_DECREF(result);
1822 return NULL;
1823 }
1824 }
1825 return result;
1826}
1827
Serhiy Storchaka95949422013-08-27 19:40:23 +03001828/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001829 */
1830static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001831microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 int us;
1834 int s;
1835 int d;
Tim Peters2a799bf2002-12-16 20:18:38 +00001836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 PyObject *tuple = NULL;
1838 PyObject *num = NULL;
1839 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001840
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001841 tuple = checked_divmod(pyus, us_per_second);
1842 if (tuple == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 goto Done;
1844 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001845
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001846 num = PyTuple_GET_ITEM(tuple, 1); /* us */
1847 us = _PyLong_AsInt(num);
1848 num = NULL;
1849 if (us == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 goto Done;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001851 }
1852 if (!(0 <= us && us < 1000000)) {
1853 goto BadDivmod;
1854 }
1855
1856 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 Py_INCREF(num);
1858 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001859
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001860 tuple = checked_divmod(num, seconds_per_day);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 if (tuple == NULL)
1862 goto Done;
1863 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001864
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001865 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */
1866 s = _PyLong_AsInt(num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 num = NULL;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001868 if (s == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 goto Done;
1870 }
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001871 if (!(0 <= s && s < 24*3600)) {
1872 goto BadDivmod;
1873 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001874
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001875 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 Py_INCREF(num);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001877 d = _PyLong_AsInt(num);
1878 if (d == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 goto Done;
1880 }
1881 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001882
1883Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 Py_XDECREF(tuple);
1885 Py_XDECREF(num);
1886 return result;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001887
1888BadDivmod:
1889 PyErr_SetString(PyExc_TypeError,
1890 "divmod() returned a value out of range");
1891 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001892}
1893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894#define microseconds_to_delta(pymicros) \
1895 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001896
Tim Peters2a799bf2002-12-16 20:18:38 +00001897static PyObject *
1898multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 PyObject *pyus_in;
1901 PyObject *pyus_out;
1902 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 pyus_in = delta_to_microseconds(delta);
1905 if (pyus_in == NULL)
1906 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001907
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001908 pyus_out = PyNumber_Multiply(intobj, pyus_in);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 Py_DECREF(pyus_in);
1910 if (pyus_out == NULL)
1911 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 result = microseconds_to_delta(pyus_out);
1914 Py_DECREF(pyus_out);
1915 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001916}
1917
1918static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001919get_float_as_integer_ratio(PyObject *floatobj)
1920{
1921 PyObject *ratio;
1922
1923 assert(floatobj && PyFloat_Check(floatobj));
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001924 ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio);
Oren Milman865e4b42017-09-19 15:58:11 +03001925 if (ratio == NULL) {
1926 return NULL;
1927 }
1928 if (!PyTuple_Check(ratio)) {
1929 PyErr_Format(PyExc_TypeError,
1930 "unexpected return type from as_integer_ratio(): "
1931 "expected tuple, got '%.200s'",
1932 Py_TYPE(ratio)->tp_name);
1933 Py_DECREF(ratio);
1934 return NULL;
1935 }
1936 if (PyTuple_Size(ratio) != 2) {
1937 PyErr_SetString(PyExc_ValueError,
1938 "as_integer_ratio() must return a 2-tuple");
1939 Py_DECREF(ratio);
1940 return NULL;
1941 }
1942 return ratio;
1943}
1944
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001945/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001946static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001947multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001948{
1949 PyObject *result = NULL;
1950 PyObject *pyus_in = NULL, *temp, *pyus_out;
1951 PyObject *ratio = NULL;
1952
1953 pyus_in = delta_to_microseconds(delta);
1954 if (pyus_in == NULL)
1955 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001956 ratio = get_float_as_integer_ratio(floatobj);
1957 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001958 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001959 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001960 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001961 Py_DECREF(pyus_in);
1962 pyus_in = NULL;
1963 if (temp == NULL)
1964 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001965 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001966 Py_DECREF(temp);
1967 if (pyus_out == NULL)
1968 goto error;
1969 result = microseconds_to_delta(pyus_out);
1970 Py_DECREF(pyus_out);
1971 error:
1972 Py_XDECREF(pyus_in);
1973 Py_XDECREF(ratio);
1974
1975 return result;
1976}
1977
1978static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001979divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 PyObject *pyus_in;
1982 PyObject *pyus_out;
1983 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 pyus_in = delta_to_microseconds(delta);
1986 if (pyus_in == NULL)
1987 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1990 Py_DECREF(pyus_in);
1991 if (pyus_out == NULL)
1992 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 result = microseconds_to_delta(pyus_out);
1995 Py_DECREF(pyus_out);
1996 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001997}
1998
1999static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00002000divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 PyObject *pyus_left;
2003 PyObject *pyus_right;
2004 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 pyus_left = delta_to_microseconds(left);
2007 if (pyus_left == NULL)
2008 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 pyus_right = delta_to_microseconds(right);
2011 if (pyus_right == NULL) {
2012 Py_DECREF(pyus_left);
2013 return NULL;
2014 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 result = PyNumber_FloorDivide(pyus_left, pyus_right);
2017 Py_DECREF(pyus_left);
2018 Py_DECREF(pyus_right);
2019 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002020}
2021
2022static PyObject *
2023truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 PyObject *pyus_left;
2026 PyObject *pyus_right;
2027 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 pyus_left = delta_to_microseconds(left);
2030 if (pyus_left == NULL)
2031 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002033 pyus_right = delta_to_microseconds(right);
2034 if (pyus_right == NULL) {
2035 Py_DECREF(pyus_left);
2036 return NULL;
2037 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2040 Py_DECREF(pyus_left);
2041 Py_DECREF(pyus_right);
2042 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002043}
2044
2045static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002046truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2047{
2048 PyObject *result;
2049 PyObject *pyus_in, *pyus_out;
2050 pyus_in = delta_to_microseconds(delta);
2051 if (pyus_in == NULL)
2052 return NULL;
2053 pyus_out = divide_nearest(pyus_in, i);
2054 Py_DECREF(pyus_in);
2055 if (pyus_out == NULL)
2056 return NULL;
2057 result = microseconds_to_delta(pyus_out);
2058 Py_DECREF(pyus_out);
2059
2060 return result;
2061}
2062
2063static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002064delta_add(PyObject *left, PyObject *right)
2065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2069 /* delta + delta */
2070 /* The C-level additions can't overflow because of the
2071 * invariant bounds.
2072 */
2073 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2074 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2075 int microseconds = GET_TD_MICROSECONDS(left) +
2076 GET_TD_MICROSECONDS(right);
2077 result = new_delta(days, seconds, microseconds, 1);
2078 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002080 if (result == Py_NotImplemented)
2081 Py_INCREF(result);
2082 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002083}
2084
2085static PyObject *
2086delta_negative(PyDateTime_Delta *self)
2087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 return new_delta(-GET_TD_DAYS(self),
2089 -GET_TD_SECONDS(self),
2090 -GET_TD_MICROSECONDS(self),
2091 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002092}
2093
2094static PyObject *
2095delta_positive(PyDateTime_Delta *self)
2096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 /* Could optimize this (by returning self) if this isn't a
2098 * subclass -- but who uses unary + ? Approximately nobody.
2099 */
2100 return new_delta(GET_TD_DAYS(self),
2101 GET_TD_SECONDS(self),
2102 GET_TD_MICROSECONDS(self),
2103 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002104}
2105
2106static PyObject *
2107delta_abs(PyDateTime_Delta *self)
2108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 assert(GET_TD_MICROSECONDS(self) >= 0);
2112 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 if (GET_TD_DAYS(self) < 0)
2115 result = delta_negative(self);
2116 else
2117 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002120}
2121
2122static PyObject *
2123delta_subtract(PyObject *left, PyObject *right)
2124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002125 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2128 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002129 /* The C-level additions can't overflow because of the
2130 * invariant bounds.
2131 */
2132 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2133 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2134 int microseconds = GET_TD_MICROSECONDS(left) -
2135 GET_TD_MICROSECONDS(right);
2136 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 if (result == Py_NotImplemented)
2140 Py_INCREF(result);
2141 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002142}
2143
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002144static int
2145delta_cmp(PyObject *self, PyObject *other)
2146{
2147 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2148 if (diff == 0) {
2149 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2150 if (diff == 0)
2151 diff = GET_TD_MICROSECONDS(self) -
2152 GET_TD_MICROSECONDS(other);
2153 }
2154 return diff;
2155}
2156
Tim Peters2a799bf2002-12-16 20:18:38 +00002157static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002158delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002161 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 return diff_to_bool(diff, op);
2163 }
2164 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002165 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002167}
2168
2169static PyObject *delta_getstate(PyDateTime_Delta *self);
2170
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002171static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002172delta_hash(PyDateTime_Delta *self)
2173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 if (self->hashcode == -1) {
2175 PyObject *temp = delta_getstate(self);
2176 if (temp != NULL) {
2177 self->hashcode = PyObject_Hash(temp);
2178 Py_DECREF(temp);
2179 }
2180 }
2181 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002182}
2183
2184static PyObject *
2185delta_multiply(PyObject *left, PyObject *right)
2186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 if (PyDelta_Check(left)) {
2190 /* delta * ??? */
2191 if (PyLong_Check(right))
2192 result = multiply_int_timedelta(right,
2193 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002194 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002195 result = multiply_truedivide_timedelta_float(
2196 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 }
2198 else if (PyLong_Check(left))
2199 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002200 (PyDateTime_Delta *) right);
2201 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002202 result = multiply_truedivide_timedelta_float(
2203 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002205 if (result == Py_NotImplemented)
2206 Py_INCREF(result);
2207 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002208}
2209
2210static PyObject *
2211delta_divide(PyObject *left, PyObject *right)
2212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002215 if (PyDelta_Check(left)) {
2216 /* delta * ??? */
2217 if (PyLong_Check(right))
2218 result = divide_timedelta_int(
2219 (PyDateTime_Delta *)left,
2220 right);
2221 else if (PyDelta_Check(right))
2222 result = divide_timedelta_timedelta(
2223 (PyDateTime_Delta *)left,
2224 (PyDateTime_Delta *)right);
2225 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 if (result == Py_NotImplemented)
2228 Py_INCREF(result);
2229 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002230}
2231
Mark Dickinson7c186e22010-04-20 22:32:49 +00002232static PyObject *
2233delta_truedivide(PyObject *left, PyObject *right)
2234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 if (PyDelta_Check(left)) {
2238 if (PyDelta_Check(right))
2239 result = truedivide_timedelta_timedelta(
2240 (PyDateTime_Delta *)left,
2241 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002242 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002243 result = multiply_truedivide_timedelta_float(
2244 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002245 else if (PyLong_Check(right))
2246 result = truedivide_timedelta_int(
2247 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250 if (result == Py_NotImplemented)
2251 Py_INCREF(result);
2252 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002253}
2254
2255static PyObject *
2256delta_remainder(PyObject *left, PyObject *right)
2257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 PyObject *pyus_left;
2259 PyObject *pyus_right;
2260 PyObject *pyus_remainder;
2261 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002262
Brian Curtindfc80e32011-08-10 20:28:54 -05002263 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2264 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2267 if (pyus_left == NULL)
2268 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2271 if (pyus_right == NULL) {
2272 Py_DECREF(pyus_left);
2273 return NULL;
2274 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2277 Py_DECREF(pyus_left);
2278 Py_DECREF(pyus_right);
2279 if (pyus_remainder == NULL)
2280 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 remainder = microseconds_to_delta(pyus_remainder);
2283 Py_DECREF(pyus_remainder);
2284 if (remainder == NULL)
2285 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002288}
2289
2290static PyObject *
2291delta_divmod(PyObject *left, PyObject *right)
2292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 PyObject *pyus_left;
2294 PyObject *pyus_right;
2295 PyObject *divmod;
2296 PyObject *delta;
2297 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002298
Brian Curtindfc80e32011-08-10 20:28:54 -05002299 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2300 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2303 if (pyus_left == NULL)
2304 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2307 if (pyus_right == NULL) {
2308 Py_DECREF(pyus_left);
2309 return NULL;
2310 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002311
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002312 divmod = checked_divmod(pyus_left, pyus_right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002313 Py_DECREF(pyus_left);
2314 Py_DECREF(pyus_right);
2315 if (divmod == NULL)
2316 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2319 if (delta == NULL) {
2320 Py_DECREF(divmod);
2321 return NULL;
2322 }
2323 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2324 Py_DECREF(delta);
2325 Py_DECREF(divmod);
2326 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002327}
2328
Tim Peters2a799bf2002-12-16 20:18:38 +00002329/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2330 * timedelta constructor. sofar is the # of microseconds accounted for
2331 * so far, and there are factor microseconds per current unit, the number
2332 * of which is given by num. num * factor is added to sofar in a
2333 * numerically careful way, and that's the result. Any fractional
2334 * microseconds left over (this can happen if num is a float type) are
2335 * added into *leftover.
2336 * Note that there are many ways this can give an error (NULL) return.
2337 */
2338static PyObject *
2339accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2340 double *leftover)
2341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002342 PyObject *prod;
2343 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 if (PyLong_Check(num)) {
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002348 prod = PyNumber_Multiply(num, factor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 if (prod == NULL)
2350 return NULL;
2351 sum = PyNumber_Add(sofar, prod);
2352 Py_DECREF(prod);
2353 return sum;
2354 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356 if (PyFloat_Check(num)) {
2357 double dnum;
2358 double fracpart;
2359 double intpart;
2360 PyObject *x;
2361 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 /* The Plan: decompose num into an integer part and a
2364 * fractional part, num = intpart + fracpart.
2365 * Then num * factor ==
2366 * intpart * factor + fracpart * factor
2367 * and the LHS can be computed exactly in long arithmetic.
2368 * The RHS is again broken into an int part and frac part.
2369 * and the frac part is added into *leftover.
2370 */
2371 dnum = PyFloat_AsDouble(num);
2372 if (dnum == -1.0 && PyErr_Occurred())
2373 return NULL;
2374 fracpart = modf(dnum, &intpart);
2375 x = PyLong_FromDouble(intpart);
2376 if (x == NULL)
2377 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 prod = PyNumber_Multiply(x, factor);
2380 Py_DECREF(x);
2381 if (prod == NULL)
2382 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 sum = PyNumber_Add(sofar, prod);
2385 Py_DECREF(prod);
2386 if (sum == NULL)
2387 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 if (fracpart == 0.0)
2390 return sum;
2391 /* So far we've lost no information. Dealing with the
2392 * fractional part requires float arithmetic, and may
2393 * lose a little info.
2394 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002395 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 dnum *= fracpart;
2399 fracpart = modf(dnum, &intpart);
2400 x = PyLong_FromDouble(intpart);
2401 if (x == NULL) {
2402 Py_DECREF(sum);
2403 return NULL;
2404 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 y = PyNumber_Add(sum, x);
2407 Py_DECREF(sum);
2408 Py_DECREF(x);
2409 *leftover += fracpart;
2410 return y;
2411 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 PyErr_Format(PyExc_TypeError,
2414 "unsupported type for timedelta %s component: %s",
2415 tag, Py_TYPE(num)->tp_name);
2416 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002417}
2418
2419static PyObject *
2420delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 /* Argument objects. */
2425 PyObject *day = NULL;
2426 PyObject *second = NULL;
2427 PyObject *us = NULL;
2428 PyObject *ms = NULL;
2429 PyObject *minute = NULL;
2430 PyObject *hour = NULL;
2431 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 PyObject *x = NULL; /* running sum of microseconds */
2434 PyObject *y = NULL; /* temp sum of microseconds */
2435 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 static char *keywords[] = {
2438 "days", "seconds", "microseconds", "milliseconds",
2439 "minutes", "hours", "weeks", NULL
2440 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2443 keywords,
2444 &day, &second, &us,
2445 &ms, &minute, &hour, &week) == 0)
2446 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002448 x = PyLong_FromLong(0);
2449 if (x == NULL)
2450 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452#define CLEANUP \
2453 Py_DECREF(x); \
2454 x = y; \
2455 if (x == NULL) \
2456 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002458 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002459 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 CLEANUP;
2461 }
2462 if (ms) {
2463 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2464 CLEANUP;
2465 }
2466 if (second) {
2467 y = accum("seconds", x, second, us_per_second, &leftover_us);
2468 CLEANUP;
2469 }
2470 if (minute) {
2471 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2472 CLEANUP;
2473 }
2474 if (hour) {
2475 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2476 CLEANUP;
2477 }
2478 if (day) {
2479 y = accum("days", x, day, us_per_day, &leftover_us);
2480 CLEANUP;
2481 }
2482 if (week) {
2483 y = accum("weeks", x, week, us_per_week, &leftover_us);
2484 CLEANUP;
2485 }
2486 if (leftover_us) {
2487 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002488 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002489 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002490 PyObject *temp;
2491
Victor Stinner69cc4872015-09-08 23:58:54 +02002492 whole_us = round(leftover_us);
2493 if (fabs(whole_us - leftover_us) == 0.5) {
2494 /* We're exactly halfway between two integers. In order
2495 * to do round-half-to-even, we must determine whether x
2496 * is odd. Note that x is odd when it's last bit is 1. The
2497 * code below uses bitwise and operation to check the last
2498 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002499 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002500 if (temp == NULL) {
2501 Py_DECREF(x);
2502 goto Done;
2503 }
2504 x_is_odd = PyObject_IsTrue(temp);
2505 Py_DECREF(temp);
2506 if (x_is_odd == -1) {
2507 Py_DECREF(x);
2508 goto Done;
2509 }
2510 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2511 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002512
Victor Stinner36a5a062013-08-28 01:53:39 +02002513 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002515 if (temp == NULL) {
2516 Py_DECREF(x);
2517 goto Done;
2518 }
2519 y = PyNumber_Add(x, temp);
2520 Py_DECREF(temp);
2521 CLEANUP;
2522 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 self = microseconds_to_delta_ex(x, type);
2525 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002526Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002527 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002528
2529#undef CLEANUP
2530}
2531
2532static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002533delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002534{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002535 return (GET_TD_DAYS(self) != 0
2536 || GET_TD_SECONDS(self) != 0
2537 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002538}
2539
2540static PyObject *
2541delta_repr(PyDateTime_Delta *self)
2542{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002543 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002544
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002545 if (args == NULL) {
2546 return NULL;
2547 }
2548
2549 const char *sep = "";
2550
2551 if (GET_TD_DAYS(self) != 0) {
2552 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2553 if (args == NULL) {
2554 return NULL;
2555 }
2556 sep = ", ";
2557 }
2558
2559 if (GET_TD_SECONDS(self) != 0) {
2560 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2561 GET_TD_SECONDS(self)));
2562 if (args == NULL) {
2563 return NULL;
2564 }
2565 sep = ", ";
2566 }
2567
2568 if (GET_TD_MICROSECONDS(self) != 0) {
2569 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2570 GET_TD_MICROSECONDS(self)));
2571 if (args == NULL) {
2572 return NULL;
2573 }
2574 }
2575
2576 if (PyUnicode_GET_LENGTH(args) == 0) {
2577 Py_SETREF(args, PyUnicode_FromString("0"));
2578 if (args == NULL) {
2579 return NULL;
2580 }
2581 }
2582
2583 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2584 args);
2585 Py_DECREF(args);
2586 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002587}
2588
2589static PyObject *
2590delta_str(PyDateTime_Delta *self)
2591{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002592 int us = GET_TD_MICROSECONDS(self);
2593 int seconds = GET_TD_SECONDS(self);
2594 int minutes = divmod(seconds, 60, &seconds);
2595 int hours = divmod(minutes, 60, &minutes);
2596 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 if (days) {
2599 if (us)
2600 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2601 days, (days == 1 || days == -1) ? "" : "s",
2602 hours, minutes, seconds, us);
2603 else
2604 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2605 days, (days == 1 || days == -1) ? "" : "s",
2606 hours, minutes, seconds);
2607 } else {
2608 if (us)
2609 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2610 hours, minutes, seconds, us);
2611 else
2612 return PyUnicode_FromFormat("%d:%02d:%02d",
2613 hours, minutes, seconds);
2614 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002615
Tim Peters2a799bf2002-12-16 20:18:38 +00002616}
2617
Tim Peters371935f2003-02-01 01:52:50 +00002618/* Pickle support, a simple use of __reduce__. */
2619
Tim Petersb57f8f02003-02-01 02:54:15 +00002620/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002621static PyObject *
2622delta_getstate(PyDateTime_Delta *self)
2623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 return Py_BuildValue("iii", GET_TD_DAYS(self),
2625 GET_TD_SECONDS(self),
2626 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002627}
2628
Tim Peters2a799bf2002-12-16 20:18:38 +00002629static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302630delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitroube6859d2009-11-25 23:02:32 +00002631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002632 PyObject *total_seconds;
2633 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002635 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2636 if (total_microseconds == NULL)
2637 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002638
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002639 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002643}
2644
2645static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302646delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00002647{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002648 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002649}
2650
2651#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2652
2653static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002655 {"days", T_INT, OFFSET(days), READONLY,
2656 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 {"seconds", T_INT, OFFSET(seconds), READONLY,
2659 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002661 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2662 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2663 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002664};
2665
2666static PyMethodDef delta_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302667 {"total_seconds", delta_total_seconds, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002668 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2671 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002673 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002674};
2675
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002676static const char delta_doc[] =
Chris Barkerd6a61f22018-10-19 15:43:24 -07002677PyDoc_STR("Difference between two datetime values.\n\n"
2678 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2679 "minutes=0, hours=0, weeks=0)\n\n"
2680 "All arguments are optional and default to 0.\n"
2681 "Arguments may be integers or floats, and may be positive or negative.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002682
2683static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002684 delta_add, /* nb_add */
2685 delta_subtract, /* nb_subtract */
2686 delta_multiply, /* nb_multiply */
2687 delta_remainder, /* nb_remainder */
2688 delta_divmod, /* nb_divmod */
2689 0, /* nb_power */
2690 (unaryfunc)delta_negative, /* nb_negative */
2691 (unaryfunc)delta_positive, /* nb_positive */
2692 (unaryfunc)delta_abs, /* nb_absolute */
2693 (inquiry)delta_bool, /* nb_bool */
2694 0, /*nb_invert*/
2695 0, /*nb_lshift*/
2696 0, /*nb_rshift*/
2697 0, /*nb_and*/
2698 0, /*nb_xor*/
2699 0, /*nb_or*/
2700 0, /*nb_int*/
2701 0, /*nb_reserved*/
2702 0, /*nb_float*/
2703 0, /*nb_inplace_add*/
2704 0, /*nb_inplace_subtract*/
2705 0, /*nb_inplace_multiply*/
2706 0, /*nb_inplace_remainder*/
2707 0, /*nb_inplace_power*/
2708 0, /*nb_inplace_lshift*/
2709 0, /*nb_inplace_rshift*/
2710 0, /*nb_inplace_and*/
2711 0, /*nb_inplace_xor*/
2712 0, /*nb_inplace_or*/
2713 delta_divide, /* nb_floor_divide */
2714 delta_truedivide, /* nb_true_divide */
2715 0, /* nb_inplace_floor_divide */
2716 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002717};
2718
2719static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 PyVarObject_HEAD_INIT(NULL, 0)
2721 "datetime.timedelta", /* tp_name */
2722 sizeof(PyDateTime_Delta), /* tp_basicsize */
2723 0, /* tp_itemsize */
2724 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002725 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002726 0, /* tp_getattr */
2727 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002728 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002729 (reprfunc)delta_repr, /* tp_repr */
2730 &delta_as_number, /* tp_as_number */
2731 0, /* tp_as_sequence */
2732 0, /* tp_as_mapping */
2733 (hashfunc)delta_hash, /* tp_hash */
2734 0, /* tp_call */
2735 (reprfunc)delta_str, /* tp_str */
2736 PyObject_GenericGetAttr, /* tp_getattro */
2737 0, /* tp_setattro */
2738 0, /* tp_as_buffer */
2739 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2740 delta_doc, /* tp_doc */
2741 0, /* tp_traverse */
2742 0, /* tp_clear */
2743 delta_richcompare, /* tp_richcompare */
2744 0, /* tp_weaklistoffset */
2745 0, /* tp_iter */
2746 0, /* tp_iternext */
2747 delta_methods, /* tp_methods */
2748 delta_members, /* tp_members */
2749 0, /* tp_getset */
2750 0, /* tp_base */
2751 0, /* tp_dict */
2752 0, /* tp_descr_get */
2753 0, /* tp_descr_set */
2754 0, /* tp_dictoffset */
2755 0, /* tp_init */
2756 0, /* tp_alloc */
2757 delta_new, /* tp_new */
2758 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002759};
2760
2761/*
2762 * PyDateTime_Date implementation.
2763 */
2764
2765/* Accessor properties. */
2766
2767static PyObject *
2768date_year(PyDateTime_Date *self, void *unused)
2769{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002770 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002771}
2772
2773static PyObject *
2774date_month(PyDateTime_Date *self, void *unused)
2775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002776 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002777}
2778
2779static PyObject *
2780date_day(PyDateTime_Date *self, void *unused)
2781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002782 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002783}
2784
2785static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002786 {"year", (getter)date_year},
2787 {"month", (getter)date_month},
2788 {"day", (getter)date_day},
2789 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002790};
2791
2792/* Constructors. */
2793
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002794static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002795
Tim Peters2a799bf2002-12-16 20:18:38 +00002796static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002797date_from_pickle(PyTypeObject *type, PyObject *state)
2798{
2799 PyDateTime_Date *me;
2800
2801 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2802 if (me != NULL) {
2803 const char *pdata = PyBytes_AS_STRING(state);
2804 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2805 me->hashcode = -1;
2806 }
2807 return (PyObject *)me;
2808}
2809
2810static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002811date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002813 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 int year;
2815 int month;
2816 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002817
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002818 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka1133a8c2018-12-07 16:48:21 +02002819 if (PyTuple_GET_SIZE(args) == 1) {
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002820 PyObject *state = PyTuple_GET_ITEM(args, 0);
2821 if (PyBytes_Check(state)) {
2822 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2823 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2824 {
2825 return date_from_pickle(type, state);
Victor Stinnerb37672d2018-11-22 03:37:50 +01002826 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002827 }
2828 else if (PyUnicode_Check(state)) {
2829 if (PyUnicode_READY(state)) {
2830 return NULL;
2831 }
2832 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
2833 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
2834 {
2835 state = PyUnicode_AsLatin1String(state);
2836 if (state == NULL) {
2837 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
2838 /* More informative error message. */
2839 PyErr_SetString(PyExc_ValueError,
2840 "Failed to encode latin1 string when unpickling "
2841 "a date object. "
2842 "pickle.load(data, encoding='latin1') is assumed.");
2843 }
2844 return NULL;
2845 }
2846 self = date_from_pickle(type, state);
2847 Py_DECREF(state);
2848 return self;
2849 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2854 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002855 self = new_date_ex(year, month, day, type);
2856 }
2857 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002858}
2859
Tim Peters2a799bf2002-12-16 20:18:38 +00002860static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002861date_fromtimestamp(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002862{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002863 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002865
Victor Stinnere4a994d2015-03-30 01:10:14 +02002866 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002867 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002868
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002869 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002870 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002871
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002872 return new_date_subclass_ex(tm.tm_year + 1900,
2873 tm.tm_mon + 1,
2874 tm.tm_mday,
2875 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002876}
2877
2878/* Return new date from current time.
2879 * We say this is equivalent to fromtimestamp(time.time()), and the
2880 * only way to be sure of that is to *call* time.time(). That's not
2881 * generally the same as calling C's time.
2882 */
2883static PyObject *
2884date_today(PyObject *cls, PyObject *dummy)
2885{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002886 PyObject *time;
2887 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002888 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 time = time_time();
2891 if (time == NULL)
2892 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002894 /* Note well: today() is a class method, so this may not call
2895 * date.fromtimestamp. For example, it may call
2896 * datetime.fromtimestamp. That's why we need all the accuracy
2897 * time.time() delivers; if someone were gonzo about optimization,
2898 * date.today() could get away with plain C time().
2899 */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02002900 result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002901 Py_DECREF(time);
2902 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002903}
2904
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002905/*[clinic input]
2906@classmethod
2907datetime.date.fromtimestamp
2908
2909 timestamp: object
2910 /
2911
2912Create a date from a POSIX timestamp.
2913
2914The timestamp is a number, e.g. created via time.time(), that is interpreted
2915as local time.
2916[clinic start generated code]*/
2917
Tim Peters2a799bf2002-12-16 20:18:38 +00002918static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002919datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp)
2920/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00002921{
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002922 return date_fromtimestamp((PyObject *) type, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002923}
2924
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04002925/* bpo-36025: This is a wrapper for API compatibility with the public C API,
2926 * which expects a function that takes an *args tuple, whereas the argument
2927 * clinic generates code that takes METH_O.
2928 */
2929static PyObject *
2930datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args)
2931{
2932 PyObject *timestamp;
2933 PyObject *result = NULL;
2934
2935 if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, &timestamp)) {
2936 result = date_fromtimestamp(cls, timestamp);
2937 }
2938
2939 return result;
2940}
2941
Tim Peters2a799bf2002-12-16 20:18:38 +00002942/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2943 * the ordinal is out of range.
2944 */
2945static PyObject *
2946date_fromordinal(PyObject *cls, PyObject *args)
2947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002948 PyObject *result = NULL;
2949 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002951 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2952 int year;
2953 int month;
2954 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002956 if (ordinal < 1)
2957 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2958 ">= 1");
2959 else {
2960 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002961 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002962 }
2963 }
2964 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002965}
2966
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002967/* Return the new date from a string as generated by date.isoformat() */
2968static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04002969date_fromisoformat(PyObject *cls, PyObject *dtstr)
2970{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002971 assert(dtstr != NULL);
2972
2973 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04002974 PyErr_SetString(PyExc_TypeError,
2975 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002976 return NULL;
2977 }
2978
2979 Py_ssize_t len;
2980
Paul Ganssle3df85402018-10-22 12:32:52 -04002981 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04002982 if (dt_ptr == NULL) {
2983 goto invalid_string_error;
2984 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002985
2986 int year = 0, month = 0, day = 0;
2987
2988 int rv;
2989 if (len == 10) {
2990 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
Paul Ganssle3df85402018-10-22 12:32:52 -04002991 }
2992 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002993 rv = -1;
2994 }
2995
2996 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04002997 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002998 }
2999
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05003000 return new_date_subclass_ex(year, month, day, cls);
Paul Ganssle096329f2018-08-23 11:06:20 -04003001
3002invalid_string_error:
Paul Ganssle3df85402018-10-22 12:32:52 -04003003 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04003004 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003005}
3006
Paul Ganssle88c09372019-04-29 09:22:03 -04003007
3008static PyObject *
3009date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw)
3010{
3011 static char *keywords[] = {
3012 "year", "week", "day", NULL
3013 };
3014
3015 int year, week, day;
3016 if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar",
3017 keywords,
3018 &year, &week, &day) == 0) {
3019 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
3020 PyErr_Format(PyExc_ValueError,
3021 "ISO calendar component out of range");
3022
3023 }
3024 return NULL;
3025 }
3026
3027 // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
3028 if (year < MINYEAR || year > MAXYEAR) {
3029 PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
3030 return NULL;
3031 }
3032
3033 if (week <= 0 || week >= 53) {
3034 int out_of_range = 1;
3035 if (week == 53) {
3036 // ISO years have 53 weeks in it on years starting with a Thursday
3037 // and on leap years starting on Wednesday
3038 int first_weekday = weekday(year, 1, 1);
3039 if (first_weekday == 3 || (first_weekday == 2 && is_leap(year))) {
3040 out_of_range = 0;
3041 }
3042 }
3043
3044 if (out_of_range) {
3045 PyErr_Format(PyExc_ValueError, "Invalid week: %d", week);
3046 return NULL;
3047 }
3048 }
3049
3050 if (day <= 0 || day >= 8) {
3051 PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])",
3052 day);
3053 return NULL;
3054 }
3055
3056 // Convert (Y, W, D) to (Y, M, D) in-place
3057 int day_1 = iso_week1_monday(year);
3058
3059 int month = week;
3060 int day_offset = (month - 1)*7 + day - 1;
3061
3062 ord_to_ymd(day_1 + day_offset, &year, &month, &day);
3063
3064 return new_date_subclass_ex(year, month, day, cls);
3065}
3066
3067
Tim Peters2a799bf2002-12-16 20:18:38 +00003068/*
3069 * Date arithmetic.
3070 */
3071
3072/* date + timedelta -> date. If arg negate is true, subtract the timedelta
3073 * instead.
3074 */
3075static PyObject *
3076add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
3077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003078 PyObject *result = NULL;
3079 int year = GET_YEAR(date);
3080 int month = GET_MONTH(date);
3081 int deltadays = GET_TD_DAYS(delta);
3082 /* C-level overflow is impossible because |deltadays| < 1e9. */
3083 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00003084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003085 if (normalize_date(&year, &month, &day) >= 0)
Paul Ganssle89427cd2019-02-04 14:42:04 -05003086 result = new_date_subclass_ex(year, month, day,
3087 (PyObject* )Py_TYPE(date));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003088 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003089}
3090
3091static PyObject *
3092date_add(PyObject *left, PyObject *right)
3093{
Brian Curtindfc80e32011-08-10 20:28:54 -05003094 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3095 Py_RETURN_NOTIMPLEMENTED;
3096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003097 if (PyDate_Check(left)) {
3098 /* date + ??? */
3099 if (PyDelta_Check(right))
3100 /* date + delta */
3101 return add_date_timedelta((PyDateTime_Date *) left,
3102 (PyDateTime_Delta *) right,
3103 0);
3104 }
3105 else {
3106 /* ??? + date
3107 * 'right' must be one of us, or we wouldn't have been called
3108 */
3109 if (PyDelta_Check(left))
3110 /* delta + date */
3111 return add_date_timedelta((PyDateTime_Date *) right,
3112 (PyDateTime_Delta *) left,
3113 0);
3114 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003115 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003116}
3117
3118static PyObject *
3119date_subtract(PyObject *left, PyObject *right)
3120{
Brian Curtindfc80e32011-08-10 20:28:54 -05003121 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3122 Py_RETURN_NOTIMPLEMENTED;
3123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003124 if (PyDate_Check(left)) {
3125 if (PyDate_Check(right)) {
3126 /* date - date */
3127 int left_ord = ymd_to_ord(GET_YEAR(left),
3128 GET_MONTH(left),
3129 GET_DAY(left));
3130 int right_ord = ymd_to_ord(GET_YEAR(right),
3131 GET_MONTH(right),
3132 GET_DAY(right));
3133 return new_delta(left_ord - right_ord, 0, 0, 0);
3134 }
3135 if (PyDelta_Check(right)) {
3136 /* date - delta */
3137 return add_date_timedelta((PyDateTime_Date *) left,
3138 (PyDateTime_Delta *) right,
3139 1);
3140 }
3141 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003142 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003143}
3144
3145
3146/* Various ways to turn a date into a string. */
3147
3148static PyObject *
3149date_repr(PyDateTime_Date *self)
3150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003151 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3152 Py_TYPE(self)->tp_name,
3153 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003154}
3155
3156static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303157date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003159 return PyUnicode_FromFormat("%04d-%02d-%02d",
3160 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003161}
3162
Tim Peterse2df5ff2003-05-02 18:39:55 +00003163/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003164static PyObject *
3165date_str(PyDateTime_Date *self)
3166{
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02003167 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
Tim Peters2a799bf2002-12-16 20:18:38 +00003168}
3169
3170
3171static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303172date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003174 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003175}
3176
3177static PyObject *
3178date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003180 /* This method can be inherited, and needs to call the
3181 * timetuple() method appropriate to self's class.
3182 */
3183 PyObject *result;
3184 PyObject *tuple;
3185 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003186 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003187 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003189 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3190 &format))
3191 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003192
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02003193 tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003194 if (tuple == NULL)
3195 return NULL;
3196 result = wrap_strftime((PyObject *)self, format, tuple,
3197 (PyObject *)self);
3198 Py_DECREF(tuple);
3199 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003200}
3201
Eric Smith1ba31142007-09-11 18:06:02 +00003202static PyObject *
3203date_format(PyDateTime_Date *self, PyObject *args)
3204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003205 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003207 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3208 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003210 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003211 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003212 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003213
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02003214 return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime,
3215 format);
Eric Smith1ba31142007-09-11 18:06:02 +00003216}
3217
Tim Peters2a799bf2002-12-16 20:18:38 +00003218/* ISO methods. */
3219
3220static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303221date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003223 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003225 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003226}
3227
3228static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303229date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003231 int year = GET_YEAR(self);
3232 int week1_monday = iso_week1_monday(year);
3233 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3234 int week;
3235 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003237 week = divmod(today - week1_monday, 7, &day);
3238 if (week < 0) {
3239 --year;
3240 week1_monday = iso_week1_monday(year);
3241 week = divmod(today - week1_monday, 7, &day);
3242 }
3243 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3244 ++year;
3245 week = 0;
3246 }
3247 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003248}
3249
3250/* Miscellaneous methods. */
3251
Tim Peters2a799bf2002-12-16 20:18:38 +00003252static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003253date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003255 if (PyDate_Check(other)) {
3256 int diff = memcmp(((PyDateTime_Date *)self)->data,
3257 ((PyDateTime_Date *)other)->data,
3258 _PyDateTime_DATE_DATASIZE);
3259 return diff_to_bool(diff, op);
3260 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003261 else
3262 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003263}
3264
3265static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303266date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003268 return build_struct_time(GET_YEAR(self),
3269 GET_MONTH(self),
3270 GET_DAY(self),
3271 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003272}
3273
Tim Peters12bf3392002-12-24 05:41:27 +00003274static PyObject *
3275date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003277 PyObject *clone;
3278 PyObject *tuple;
3279 int year = GET_YEAR(self);
3280 int month = GET_MONTH(self);
3281 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003283 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3284 &year, &month, &day))
3285 return NULL;
3286 tuple = Py_BuildValue("iii", year, month, day);
3287 if (tuple == NULL)
3288 return NULL;
3289 clone = date_new(Py_TYPE(self), tuple, NULL);
3290 Py_DECREF(tuple);
3291 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003292}
3293
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003294static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003295generic_hash(unsigned char *data, int len)
3296{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003297 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003298}
3299
3300
3301static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003302
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003303static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003304date_hash(PyDateTime_Date *self)
3305{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003306 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003307 self->hashcode = generic_hash(
3308 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003309 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003311 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003312}
3313
3314static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303315date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003317 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3318 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003319}
3320
3321static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303322date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003323{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003324 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003326 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003327}
3328
Tim Peters371935f2003-02-01 01:52:50 +00003329/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003330
Tim Petersb57f8f02003-02-01 02:54:15 +00003331/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003332static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003333date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003335 PyObject* field;
3336 field = PyBytes_FromStringAndSize((char*)self->data,
3337 _PyDateTime_DATE_DATASIZE);
3338 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003339}
3340
3341static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003342date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003344 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003345}
3346
3347static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003349 /* Class methods: */
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02003350 DATETIME_DATE_FROMTIMESTAMP_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00003351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003352 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3353 METH_CLASS,
3354 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3355 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003356
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003357 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3358 METH_CLASS,
3359 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3360
Paul Ganssle88c09372019-04-29 09:22:03 -04003361 {"fromisocalendar", (PyCFunction)(void(*)(void))date_fromisocalendar,
3362 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
3363 PyDoc_STR("int, int, int -> Construct a date from the ISO year, week "
3364 "number and weekday.\n\n"
3365 "This is the inverse of the date.isocalendar() function")},
3366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003367 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3368 PyDoc_STR("Current date or datetime: same as "
3369 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003371 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003373 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3374 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003375
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003376 {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003377 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003379 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3380 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003382 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3383 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003385 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3386 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3387 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003389 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3390 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003392 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3393 PyDoc_STR("Return the day of the week represented by the date.\n"
3394 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003396 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3397 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3398 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003400 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3401 PyDoc_STR("Return the day of the week represented by the date.\n"
3402 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003403
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003404 {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003405 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003407 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3408 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003410 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003411};
3412
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003413static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003414PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003415
3416static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003417 date_add, /* nb_add */
3418 date_subtract, /* nb_subtract */
3419 0, /* nb_multiply */
3420 0, /* nb_remainder */
3421 0, /* nb_divmod */
3422 0, /* nb_power */
3423 0, /* nb_negative */
3424 0, /* nb_positive */
3425 0, /* nb_absolute */
3426 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003427};
3428
3429static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003430 PyVarObject_HEAD_INIT(NULL, 0)
3431 "datetime.date", /* tp_name */
3432 sizeof(PyDateTime_Date), /* tp_basicsize */
3433 0, /* tp_itemsize */
3434 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003435 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003436 0, /* tp_getattr */
3437 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003438 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003439 (reprfunc)date_repr, /* tp_repr */
3440 &date_as_number, /* tp_as_number */
3441 0, /* tp_as_sequence */
3442 0, /* tp_as_mapping */
3443 (hashfunc)date_hash, /* tp_hash */
3444 0, /* tp_call */
3445 (reprfunc)date_str, /* tp_str */
3446 PyObject_GenericGetAttr, /* tp_getattro */
3447 0, /* tp_setattro */
3448 0, /* tp_as_buffer */
3449 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3450 date_doc, /* tp_doc */
3451 0, /* tp_traverse */
3452 0, /* tp_clear */
3453 date_richcompare, /* tp_richcompare */
3454 0, /* tp_weaklistoffset */
3455 0, /* tp_iter */
3456 0, /* tp_iternext */
3457 date_methods, /* tp_methods */
3458 0, /* tp_members */
3459 date_getset, /* tp_getset */
3460 0, /* tp_base */
3461 0, /* tp_dict */
3462 0, /* tp_descr_get */
3463 0, /* tp_descr_set */
3464 0, /* tp_dictoffset */
3465 0, /* tp_init */
3466 0, /* tp_alloc */
3467 date_new, /* tp_new */
3468 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003469};
3470
3471/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003472 * PyDateTime_TZInfo implementation.
3473 */
3474
3475/* This is a pure abstract base class, so doesn't do anything beyond
3476 * raising NotImplemented exceptions. Real tzinfo classes need
3477 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003478 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003479 * be subclasses of this tzinfo class, which is easy and quick to check).
3480 *
3481 * Note: For reasons having to do with pickling of subclasses, we have
3482 * to allow tzinfo objects to be instantiated. This wasn't an issue
3483 * in the Python implementation (__init__() could raise NotImplementedError
3484 * there without ill effect), but doing so in the C implementation hit a
3485 * brick wall.
3486 */
3487
3488static PyObject *
3489tzinfo_nogo(const char* methodname)
3490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003491 PyErr_Format(PyExc_NotImplementedError,
3492 "a tzinfo subclass must implement %s()",
3493 methodname);
3494 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003495}
3496
3497/* Methods. A subclass must implement these. */
3498
Tim Peters52dcce22003-01-23 16:36:11 +00003499static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003500tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003502 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003503}
3504
Tim Peters52dcce22003-01-23 16:36:11 +00003505static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003506tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3507{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003509}
3510
Tim Peters52dcce22003-01-23 16:36:11 +00003511static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003512tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003514 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003515}
3516
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003517
3518static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3519 PyDateTime_Delta *delta,
3520 int factor);
3521static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3522static PyObject *datetime_dst(PyObject *self, PyObject *);
3523
Tim Peters52dcce22003-01-23 16:36:11 +00003524static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003525tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003526{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003527 PyObject *result = NULL;
3528 PyObject *off = NULL, *dst = NULL;
3529 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003530
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003531 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003532 PyErr_SetString(PyExc_TypeError,
3533 "fromutc: argument must be a datetime");
3534 return NULL;
3535 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003536 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003537 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3538 "is not self");
3539 return NULL;
3540 }
Tim Peters52dcce22003-01-23 16:36:11 +00003541
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003542 off = datetime_utcoffset(dt, NULL);
3543 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003544 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003545 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003546 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3547 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003548 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003549 }
Tim Peters52dcce22003-01-23 16:36:11 +00003550
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003551 dst = datetime_dst(dt, NULL);
3552 if (dst == NULL)
3553 goto Fail;
3554 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3556 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003557 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003558 }
Tim Peters52dcce22003-01-23 16:36:11 +00003559
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003560 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3561 if (delta == NULL)
3562 goto Fail;
3563 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003564 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003565 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003566
3567 Py_DECREF(dst);
3568 dst = call_dst(GET_DT_TZINFO(dt), result);
3569 if (dst == NULL)
3570 goto Fail;
3571 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003572 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003573 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003574 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003575 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003576 if (result == NULL)
3577 goto Fail;
3578 }
3579 Py_DECREF(delta);
3580 Py_DECREF(dst);
3581 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003582 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003583
3584Inconsistent:
Serhiy Storchaka34fd4c22018-11-05 16:20:25 +02003585 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003586 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003587
Leo Ariasc3d95082018-02-03 18:36:10 -06003588 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003589Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003590 Py_XDECREF(off);
3591 Py_XDECREF(dst);
3592 Py_XDECREF(delta);
3593 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003594 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003595}
3596
Tim Peters2a799bf2002-12-16 20:18:38 +00003597/*
3598 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003599 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003600 */
3601
Guido van Rossum177e41a2003-01-30 22:06:23 +00003602static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303603tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003604{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003605 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003606 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003607 _Py_IDENTIFIER(__getinitargs__);
3608 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003609
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003610 if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) {
3611 return NULL;
3612 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003613 if (getinitargs != NULL) {
Victor Stinner2ff58a22019-06-17 14:27:23 +02003614 args = PyObject_CallNoArgs(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003615 Py_DECREF(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003616 }
3617 else {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003618 args = PyTuple_New(0);
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003619 }
3620 if (args == NULL) {
3621 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003622 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003623
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003624 if (_PyObject_LookupAttrId(self, &PyId___getstate__, &getstate) < 0) {
3625 Py_DECREF(args);
3626 return NULL;
3627 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003628 if (getstate != NULL) {
Victor Stinner2ff58a22019-06-17 14:27:23 +02003629 state = PyObject_CallNoArgs(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003630 Py_DECREF(getstate);
3631 if (state == NULL) {
3632 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003633 return NULL;
3634 }
3635 }
3636 else {
3637 PyObject **dictptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003638 state = Py_None;
3639 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003640 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003641 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003642 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003643 Py_INCREF(state);
3644 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003646 if (state == Py_None) {
3647 Py_DECREF(state);
3648 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3649 }
3650 else
3651 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003652}
Tim Peters2a799bf2002-12-16 20:18:38 +00003653
3654static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003656 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3657 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003659 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003660 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3661 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003663 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003664 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003666 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003667 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003668
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303669 {"__reduce__", tzinfo_reduce, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003670 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003672 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003673};
3674
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003675static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003676PyDoc_STR("Abstract base class for time zone info objects.");
3677
Neal Norwitz227b5332006-03-22 09:28:35 +00003678static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003679 PyVarObject_HEAD_INIT(NULL, 0)
3680 "datetime.tzinfo", /* tp_name */
3681 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3682 0, /* tp_itemsize */
3683 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003684 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003685 0, /* tp_getattr */
3686 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003687 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003688 0, /* tp_repr */
3689 0, /* tp_as_number */
3690 0, /* tp_as_sequence */
3691 0, /* tp_as_mapping */
3692 0, /* tp_hash */
3693 0, /* tp_call */
3694 0, /* tp_str */
3695 PyObject_GenericGetAttr, /* tp_getattro */
3696 0, /* tp_setattro */
3697 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003698 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003699 tzinfo_doc, /* tp_doc */
3700 0, /* tp_traverse */
3701 0, /* tp_clear */
3702 0, /* tp_richcompare */
3703 0, /* tp_weaklistoffset */
3704 0, /* tp_iter */
3705 0, /* tp_iternext */
3706 tzinfo_methods, /* tp_methods */
3707 0, /* tp_members */
3708 0, /* tp_getset */
3709 0, /* tp_base */
3710 0, /* tp_dict */
3711 0, /* tp_descr_get */
3712 0, /* tp_descr_set */
3713 0, /* tp_dictoffset */
3714 0, /* tp_init */
3715 0, /* tp_alloc */
3716 PyType_GenericNew, /* tp_new */
3717 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003718};
3719
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003720static char *timezone_kws[] = {"offset", "name", NULL};
3721
3722static PyObject *
3723timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3724{
3725 PyObject *offset;
3726 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003727 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3728 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003729 return new_timezone(offset, name);
3730
3731 return NULL;
3732}
3733
3734static void
3735timezone_dealloc(PyDateTime_TimeZone *self)
3736{
3737 Py_CLEAR(self->offset);
3738 Py_CLEAR(self->name);
3739 Py_TYPE(self)->tp_free((PyObject *)self);
3740}
3741
3742static PyObject *
3743timezone_richcompare(PyDateTime_TimeZone *self,
3744 PyDateTime_TimeZone *other, int op)
3745{
Brian Curtindfc80e32011-08-10 20:28:54 -05003746 if (op != Py_EQ && op != Py_NE)
3747 Py_RETURN_NOTIMPLEMENTED;
Pablo Galindo4be11c02019-08-22 20:24:25 +01003748 if (!PyTimezone_Check(other)) {
Serhiy Storchaka17e52642019-08-04 12:38:46 +03003749 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003750 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003751 return delta_richcompare(self->offset, other->offset, op);
3752}
3753
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003754static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003755timezone_hash(PyDateTime_TimeZone *self)
3756{
3757 return delta_hash((PyDateTime_Delta *)self->offset);
3758}
3759
3760/* Check argument type passed to tzname, utcoffset, or dst methods.
3761 Returns 0 for good argument. Returns -1 and sets exception info
3762 otherwise.
3763 */
3764static int
3765_timezone_check_argument(PyObject *dt, const char *meth)
3766{
3767 if (dt == Py_None || PyDateTime_Check(dt))
3768 return 0;
3769 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3770 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3771 return -1;
3772}
3773
3774static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003775timezone_repr(PyDateTime_TimeZone *self)
3776{
3777 /* Note that although timezone is not subclassable, it is convenient
3778 to use Py_TYPE(self)->tp_name here. */
3779 const char *type_name = Py_TYPE(self)->tp_name;
3780
3781 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3782 return PyUnicode_FromFormat("%s.utc", type_name);
3783
3784 if (self->name == NULL)
3785 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3786
3787 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3788 self->name);
3789}
3790
3791
3792static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003793timezone_str(PyDateTime_TimeZone *self)
3794{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003795 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003796 PyObject *offset;
3797 char sign;
3798
3799 if (self->name != NULL) {
3800 Py_INCREF(self->name);
3801 return self->name;
3802 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003803 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003804 (GET_TD_DAYS(self->offset) == 0 &&
3805 GET_TD_SECONDS(self->offset) == 0 &&
3806 GET_TD_MICROSECONDS(self->offset) == 0))
3807 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003808 /* Offset is normalized, so it is negative if days < 0 */
3809 if (GET_TD_DAYS(self->offset) < 0) {
3810 sign = '-';
3811 offset = delta_negative((PyDateTime_Delta *)self->offset);
3812 if (offset == NULL)
3813 return NULL;
3814 }
3815 else {
3816 sign = '+';
3817 offset = self->offset;
3818 Py_INCREF(offset);
3819 }
3820 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003821 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003822 seconds = GET_TD_SECONDS(offset);
3823 Py_DECREF(offset);
3824 minutes = divmod(seconds, 60, &seconds);
3825 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003826 if (microseconds != 0) {
3827 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3828 sign, hours, minutes,
3829 seconds, microseconds);
3830 }
3831 if (seconds != 0) {
3832 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3833 sign, hours, minutes, seconds);
3834 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003835 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003836}
3837
3838static PyObject *
3839timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3840{
3841 if (_timezone_check_argument(dt, "tzname") == -1)
3842 return NULL;
3843
3844 return timezone_str(self);
3845}
3846
3847static PyObject *
3848timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3849{
3850 if (_timezone_check_argument(dt, "utcoffset") == -1)
3851 return NULL;
3852
3853 Py_INCREF(self->offset);
3854 return self->offset;
3855}
3856
3857static PyObject *
3858timezone_dst(PyObject *self, PyObject *dt)
3859{
3860 if (_timezone_check_argument(dt, "dst") == -1)
3861 return NULL;
3862
3863 Py_RETURN_NONE;
3864}
3865
3866static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003867timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3868{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003869 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003870 PyErr_SetString(PyExc_TypeError,
3871 "fromutc: argument must be a datetime");
3872 return NULL;
3873 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003874 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003875 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3876 "is not self");
3877 return NULL;
3878 }
3879
3880 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3881}
3882
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003883static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303884timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003885{
3886 if (self->name == NULL)
3887 return Py_BuildValue("(O)", self->offset);
3888 return Py_BuildValue("(OO)", self->offset, self->name);
3889}
3890
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003891static PyMethodDef timezone_methods[] = {
3892 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3893 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003894 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003895
3896 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003897 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003898
3899 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003900 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003901
3902 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3903 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3904
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003905 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3906 PyDoc_STR("pickle support")},
3907
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003908 {NULL, NULL}
3909};
3910
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003911static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003912PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3913
3914static PyTypeObject PyDateTime_TimeZoneType = {
3915 PyVarObject_HEAD_INIT(NULL, 0)
3916 "datetime.timezone", /* tp_name */
3917 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3918 0, /* tp_itemsize */
3919 (destructor)timezone_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003920 0, /* tp_vectorcall_offset */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003921 0, /* tp_getattr */
3922 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003923 0, /* tp_as_async */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003924 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003925 0, /* tp_as_number */
3926 0, /* tp_as_sequence */
3927 0, /* tp_as_mapping */
3928 (hashfunc)timezone_hash, /* tp_hash */
3929 0, /* tp_call */
3930 (reprfunc)timezone_str, /* tp_str */
3931 0, /* tp_getattro */
3932 0, /* tp_setattro */
3933 0, /* tp_as_buffer */
3934 Py_TPFLAGS_DEFAULT, /* tp_flags */
3935 timezone_doc, /* tp_doc */
3936 0, /* tp_traverse */
3937 0, /* tp_clear */
3938 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3939 0, /* tp_weaklistoffset */
3940 0, /* tp_iter */
3941 0, /* tp_iternext */
3942 timezone_methods, /* tp_methods */
3943 0, /* tp_members */
3944 0, /* tp_getset */
3945 &PyDateTime_TZInfoType, /* tp_base */
3946 0, /* tp_dict */
3947 0, /* tp_descr_get */
3948 0, /* tp_descr_set */
3949 0, /* tp_dictoffset */
3950 0, /* tp_init */
3951 0, /* tp_alloc */
3952 timezone_new, /* tp_new */
3953};
3954
Tim Peters2a799bf2002-12-16 20:18:38 +00003955/*
Tim Peters37f39822003-01-10 03:49:02 +00003956 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003957 */
3958
Tim Peters37f39822003-01-10 03:49:02 +00003959/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003960 */
3961
3962static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003963time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003964{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003965 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003966}
3967
Tim Peters37f39822003-01-10 03:49:02 +00003968static PyObject *
3969time_minute(PyDateTime_Time *self, void *unused)
3970{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003971 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003972}
3973
3974/* The name time_second conflicted with some platform header file. */
3975static PyObject *
3976py_time_second(PyDateTime_Time *self, void *unused)
3977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003979}
3980
3981static PyObject *
3982time_microsecond(PyDateTime_Time *self, void *unused)
3983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003984 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003985}
3986
3987static PyObject *
3988time_tzinfo(PyDateTime_Time *self, void *unused)
3989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003990 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3991 Py_INCREF(result);
3992 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003993}
3994
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003995static PyObject *
3996time_fold(PyDateTime_Time *self, void *unused)
3997{
3998 return PyLong_FromLong(TIME_GET_FOLD(self));
3999}
4000
Tim Peters37f39822003-01-10 03:49:02 +00004001static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004002 {"hour", (getter)time_hour},
4003 {"minute", (getter)time_minute},
4004 {"second", (getter)py_time_second},
4005 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004006 {"tzinfo", (getter)time_tzinfo},
4007 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004008 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004009};
4010
4011/*
4012 * Constructors.
4013 */
4014
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004015static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004016 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00004017
Tim Peters2a799bf2002-12-16 20:18:38 +00004018static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004019time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4020{
4021 PyDateTime_Time *me;
4022 char aware = (char)(tzinfo != Py_None);
4023
4024 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4025 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4026 return NULL;
4027 }
4028
4029 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
4030 if (me != NULL) {
4031 const char *pdata = PyBytes_AS_STRING(state);
4032
4033 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
4034 me->hashcode = -1;
4035 me->hastzinfo = aware;
4036 if (aware) {
4037 Py_INCREF(tzinfo);
4038 me->tzinfo = tzinfo;
4039 }
4040 if (pdata[0] & (1 << 7)) {
4041 me->data[0] -= 128;
4042 me->fold = 1;
4043 }
4044 else {
4045 me->fold = 0;
4046 }
4047 }
4048 return (PyObject *)me;
4049}
4050
4051static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004052time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004053{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004054 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004055 int hour = 0;
4056 int minute = 0;
4057 int second = 0;
4058 int usecond = 0;
4059 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004060 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004062 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004063 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4064 PyObject *state = PyTuple_GET_ITEM(args, 0);
4065 if (PyTuple_GET_SIZE(args) == 2) {
4066 tzinfo = PyTuple_GET_ITEM(args, 1);
4067 }
4068 if (PyBytes_Check(state)) {
4069 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
4070 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
4071 {
4072 return time_from_pickle(type, state, tzinfo);
4073 }
4074 }
4075 else if (PyUnicode_Check(state)) {
4076 if (PyUnicode_READY(state)) {
4077 return NULL;
4078 }
4079 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
Justin Blanchard122376d2019-08-29 03:36:15 -04004080 (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24)
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004081 {
4082 state = PyUnicode_AsLatin1String(state);
4083 if (state == NULL) {
4084 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4085 /* More informative error message. */
4086 PyErr_SetString(PyExc_ValueError,
4087 "Failed to encode latin1 string when unpickling "
4088 "a time object. "
4089 "pickle.load(data, encoding='latin1') is assumed.");
4090 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004091 return NULL;
4092 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004093 self = time_from_pickle(type, state, tzinfo);
4094 Py_DECREF(state);
4095 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004096 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004097 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004098 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004100
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004101 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004103 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004104 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4105 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004106 }
4107 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004108}
4109
4110/*
4111 * Destructor.
4112 */
4113
4114static void
Tim Peters37f39822003-01-10 03:49:02 +00004115time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004117 if (HASTZINFO(self)) {
4118 Py_XDECREF(self->tzinfo);
4119 }
4120 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004121}
4122
4123/*
Tim Peters855fe882002-12-22 03:43:39 +00004124 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004125 */
4126
Tim Peters2a799bf2002-12-16 20:18:38 +00004127/* These are all METH_NOARGS, so don't need to check the arglist. */
4128static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004129time_utcoffset(PyObject *self, PyObject *unused) {
4130 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004131}
4132
4133static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004134time_dst(PyObject *self, PyObject *unused) {
4135 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004136}
4137
4138static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004139time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004140 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004141}
4142
4143/*
Tim Peters37f39822003-01-10 03:49:02 +00004144 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004145 */
4146
4147static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004148time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004149{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004150 const char *type_name = Py_TYPE(self)->tp_name;
4151 int h = TIME_GET_HOUR(self);
4152 int m = TIME_GET_MINUTE(self);
4153 int s = TIME_GET_SECOND(self);
4154 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004155 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004156 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004158 if (us)
4159 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4160 type_name, h, m, s, us);
4161 else if (s)
4162 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4163 type_name, h, m, s);
4164 else
4165 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4166 if (result != NULL && HASTZINFO(self))
4167 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004168 if (result != NULL && fold)
4169 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004170 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004171}
4172
Tim Peters37f39822003-01-10 03:49:02 +00004173static PyObject *
4174time_str(PyDateTime_Time *self)
4175{
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02004176 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
Tim Peters37f39822003-01-10 03:49:02 +00004177}
Tim Peters2a799bf2002-12-16 20:18:38 +00004178
4179static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004180time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004182 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004183 char *timespec = NULL;
4184 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004185 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004186 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004187 static char *specs[][2] = {
4188 {"hours", "%02d"},
4189 {"minutes", "%02d:%02d"},
4190 {"seconds", "%02d:%02d:%02d"},
4191 {"milliseconds", "%02d:%02d:%02d.%03d"},
4192 {"microseconds", "%02d:%02d:%02d.%06d"},
4193 };
4194 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004195
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004196 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4197 return NULL;
4198
4199 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4200 if (us == 0) {
4201 /* seconds */
4202 given_spec = 2;
4203 }
4204 else {
4205 /* microseconds */
4206 given_spec = 4;
4207 }
4208 }
4209 else {
4210 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4211 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4212 if (given_spec == 3) {
4213 /* milliseconds */
4214 us = us / 1000;
4215 }
4216 break;
4217 }
4218 }
4219 }
4220
4221 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4222 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4223 return NULL;
4224 }
4225 else {
4226 result = PyUnicode_FromFormat(specs[given_spec][1],
4227 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4228 TIME_GET_SECOND(self), us);
4229 }
Tim Peters37f39822003-01-10 03:49:02 +00004230
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004231 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 /* We need to append the UTC offset. */
4235 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4236 Py_None) < 0) {
4237 Py_DECREF(result);
4238 return NULL;
4239 }
4240 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4241 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004242}
4243
Tim Peters37f39822003-01-10 03:49:02 +00004244static PyObject *
4245time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004247 PyObject *result;
4248 PyObject *tuple;
4249 PyObject *format;
4250 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004252 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4253 &format))
4254 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004256 /* Python's strftime does insane things with the year part of the
4257 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004258 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004259 */
4260 tuple = Py_BuildValue("iiiiiiiii",
4261 1900, 1, 1, /* year, month, day */
4262 TIME_GET_HOUR(self),
4263 TIME_GET_MINUTE(self),
4264 TIME_GET_SECOND(self),
4265 0, 1, -1); /* weekday, daynum, dst */
4266 if (tuple == NULL)
4267 return NULL;
4268 assert(PyTuple_Size(tuple) == 9);
4269 result = wrap_strftime((PyObject *)self, format, tuple,
4270 Py_None);
4271 Py_DECREF(tuple);
4272 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004273}
Tim Peters2a799bf2002-12-16 20:18:38 +00004274
4275/*
4276 * Miscellaneous methods.
4277 */
4278
Tim Peters37f39822003-01-10 03:49:02 +00004279static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004280time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004281{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004282 PyObject *result = NULL;
4283 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004284 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004285
Brian Curtindfc80e32011-08-10 20:28:54 -05004286 if (! PyTime_Check(other))
4287 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004288
4289 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004290 diff = memcmp(((PyDateTime_Time *)self)->data,
4291 ((PyDateTime_Time *)other)->data,
4292 _PyDateTime_TIME_DATASIZE);
4293 return diff_to_bool(diff, op);
4294 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004295 offset1 = time_utcoffset(self, NULL);
4296 if (offset1 == NULL)
4297 return NULL;
4298 offset2 = time_utcoffset(other, NULL);
4299 if (offset2 == NULL)
4300 goto done;
4301 /* If they're both naive, or both aware and have the same offsets,
4302 * we get off cheap. Note that if they're both naive, offset1 ==
4303 * offset2 == Py_None at this point.
4304 */
4305 if ((offset1 == offset2) ||
4306 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4307 delta_cmp(offset1, offset2) == 0)) {
4308 diff = memcmp(((PyDateTime_Time *)self)->data,
4309 ((PyDateTime_Time *)other)->data,
4310 _PyDateTime_TIME_DATASIZE);
4311 result = diff_to_bool(diff, op);
4312 }
4313 /* The hard case: both aware with different UTC offsets */
4314 else if (offset1 != Py_None && offset2 != Py_None) {
4315 int offsecs1, offsecs2;
4316 assert(offset1 != offset2); /* else last "if" handled it */
4317 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4318 TIME_GET_MINUTE(self) * 60 +
4319 TIME_GET_SECOND(self) -
4320 GET_TD_DAYS(offset1) * 86400 -
4321 GET_TD_SECONDS(offset1);
4322 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4323 TIME_GET_MINUTE(other) * 60 +
4324 TIME_GET_SECOND(other) -
4325 GET_TD_DAYS(offset2) * 86400 -
4326 GET_TD_SECONDS(offset2);
4327 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004328 if (diff == 0)
4329 diff = TIME_GET_MICROSECOND(self) -
4330 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004331 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004332 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004333 else if (op == Py_EQ) {
4334 result = Py_False;
4335 Py_INCREF(result);
4336 }
4337 else if (op == Py_NE) {
4338 result = Py_True;
4339 Py_INCREF(result);
4340 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004341 else {
4342 PyErr_SetString(PyExc_TypeError,
4343 "can't compare offset-naive and "
4344 "offset-aware times");
4345 }
4346 done:
4347 Py_DECREF(offset1);
4348 Py_XDECREF(offset2);
4349 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004350}
4351
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004352static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004353time_hash(PyDateTime_Time *self)
4354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004355 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004356 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004357 if (TIME_GET_FOLD(self)) {
4358 self0 = new_time_ex2(TIME_GET_HOUR(self),
4359 TIME_GET_MINUTE(self),
4360 TIME_GET_SECOND(self),
4361 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004362 HASTZINFO(self) ? self->tzinfo : Py_None,
4363 0, Py_TYPE(self));
4364 if (self0 == NULL)
4365 return -1;
4366 }
4367 else {
4368 self0 = (PyObject *)self;
4369 Py_INCREF(self0);
4370 }
4371 offset = time_utcoffset(self0, NULL);
4372 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004373
4374 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004375 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004377 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004378 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004379 self->hashcode = generic_hash(
4380 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004381 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004382 PyObject *temp1, *temp2;
4383 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004385 seconds = TIME_GET_HOUR(self) * 3600 +
4386 TIME_GET_MINUTE(self) * 60 +
4387 TIME_GET_SECOND(self);
4388 microseconds = TIME_GET_MICROSECOND(self);
4389 temp1 = new_delta(0, seconds, microseconds, 1);
4390 if (temp1 == NULL) {
4391 Py_DECREF(offset);
4392 return -1;
4393 }
4394 temp2 = delta_subtract(temp1, offset);
4395 Py_DECREF(temp1);
4396 if (temp2 == NULL) {
4397 Py_DECREF(offset);
4398 return -1;
4399 }
4400 self->hashcode = PyObject_Hash(temp2);
4401 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004402 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004403 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004404 }
4405 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004406}
Tim Peters2a799bf2002-12-16 20:18:38 +00004407
Tim Peters12bf3392002-12-24 05:41:27 +00004408static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004409time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 PyObject *clone;
4412 PyObject *tuple;
4413 int hh = TIME_GET_HOUR(self);
4414 int mm = TIME_GET_MINUTE(self);
4415 int ss = TIME_GET_SECOND(self);
4416 int us = TIME_GET_MICROSECOND(self);
4417 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004418 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004419
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004420 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004421 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004422 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004423 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004424 if (fold != 0 && fold != 1) {
4425 PyErr_SetString(PyExc_ValueError,
4426 "fold must be either 0 or 1");
4427 return NULL;
4428 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004429 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4430 if (tuple == NULL)
4431 return NULL;
4432 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004433 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004434 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004435 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004436 Py_DECREF(tuple);
4437 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004438}
4439
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004440static PyObject *
4441time_fromisoformat(PyObject *cls, PyObject *tstr) {
4442 assert(tstr != NULL);
4443
4444 if (!PyUnicode_Check(tstr)) {
4445 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4446 return NULL;
4447 }
4448
4449 Py_ssize_t len;
4450 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4451
Paul Ganssle096329f2018-08-23 11:06:20 -04004452 if (p == NULL) {
4453 goto invalid_string_error;
4454 }
4455
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004456 int hour = 0, minute = 0, second = 0, microsecond = 0;
4457 int tzoffset, tzimicrosecond = 0;
4458 int rv = parse_isoformat_time(p, len,
4459 &hour, &minute, &second, &microsecond,
4460 &tzoffset, &tzimicrosecond);
4461
4462 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04004463 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004464 }
4465
4466 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4467 tzimicrosecond);
4468
4469 if (tzinfo == NULL) {
4470 return NULL;
4471 }
4472
4473 PyObject *t;
4474 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4475 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4476 } else {
4477 t = PyObject_CallFunction(cls, "iiiiO",
4478 hour, minute, second, microsecond, tzinfo);
4479 }
4480
4481 Py_DECREF(tzinfo);
4482 return t;
Paul Ganssle096329f2018-08-23 11:06:20 -04004483
4484invalid_string_error:
4485 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4486 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004487}
4488
4489
Tim Peters371935f2003-02-01 01:52:50 +00004490/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004491
Tim Peters33e0f382003-01-10 02:05:14 +00004492/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004493 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4494 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004495 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004496 */
4497static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004498time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004500 PyObject *basestate;
4501 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004503 basestate = PyBytes_FromStringAndSize((char *)self->data,
4504 _PyDateTime_TIME_DATASIZE);
4505 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004506 if (proto > 3 && TIME_GET_FOLD(self))
4507 /* Set the first bit of the first byte */
4508 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004509 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4510 result = PyTuple_Pack(1, basestate);
4511 else
4512 result = PyTuple_Pack(2, basestate, self->tzinfo);
4513 Py_DECREF(basestate);
4514 }
4515 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004516}
4517
4518static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004519time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004520{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004521 int proto;
4522 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004523 return NULL;
4524
4525 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004526}
4527
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004528static PyObject *
4529time_reduce(PyDateTime_Time *self, PyObject *arg)
4530{
4531 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4532}
4533
Tim Peters37f39822003-01-10 03:49:02 +00004534static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004535
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004536 {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS,
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004537 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4538 "[+HH:MM].\n\n"
4539 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004540
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004541 {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004542 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4545 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004547 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4548 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004550 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4551 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004553 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4554 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004555
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004556 {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004557 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004558
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004559 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4560 PyDoc_STR("string -> time from time.isoformat() output")},
4561
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004562 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004563 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004564
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004565 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4566 PyDoc_STR("__reduce__() -> (cls, state)")},
4567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004568 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004569};
4570
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004571static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004572PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4573\n\
4574All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004575a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004576
Neal Norwitz227b5332006-03-22 09:28:35 +00004577static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004578 PyVarObject_HEAD_INIT(NULL, 0)
4579 "datetime.time", /* tp_name */
4580 sizeof(PyDateTime_Time), /* tp_basicsize */
4581 0, /* tp_itemsize */
4582 (destructor)time_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004583 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004584 0, /* tp_getattr */
4585 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004586 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004587 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004588 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004589 0, /* tp_as_sequence */
4590 0, /* tp_as_mapping */
4591 (hashfunc)time_hash, /* tp_hash */
4592 0, /* tp_call */
4593 (reprfunc)time_str, /* tp_str */
4594 PyObject_GenericGetAttr, /* tp_getattro */
4595 0, /* tp_setattro */
4596 0, /* tp_as_buffer */
4597 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4598 time_doc, /* tp_doc */
4599 0, /* tp_traverse */
4600 0, /* tp_clear */
4601 time_richcompare, /* tp_richcompare */
4602 0, /* tp_weaklistoffset */
4603 0, /* tp_iter */
4604 0, /* tp_iternext */
4605 time_methods, /* tp_methods */
4606 0, /* tp_members */
4607 time_getset, /* tp_getset */
4608 0, /* tp_base */
4609 0, /* tp_dict */
4610 0, /* tp_descr_get */
4611 0, /* tp_descr_set */
4612 0, /* tp_dictoffset */
4613 0, /* tp_init */
4614 time_alloc, /* tp_alloc */
4615 time_new, /* tp_new */
4616 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004617};
4618
4619/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004620 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004621 */
4622
Tim Petersa9bc1682003-01-11 03:39:11 +00004623/* Accessor properties. Properties for day, month, and year are inherited
4624 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004625 */
4626
4627static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004628datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004630 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004631}
4632
Tim Petersa9bc1682003-01-11 03:39:11 +00004633static PyObject *
4634datetime_minute(PyDateTime_DateTime *self, void *unused)
4635{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004636 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004637}
4638
4639static PyObject *
4640datetime_second(PyDateTime_DateTime *self, void *unused)
4641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004642 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004643}
4644
4645static PyObject *
4646datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4647{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004648 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004649}
4650
4651static PyObject *
4652datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004654 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4655 Py_INCREF(result);
4656 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004657}
4658
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004659static PyObject *
4660datetime_fold(PyDateTime_DateTime *self, void *unused)
4661{
4662 return PyLong_FromLong(DATE_GET_FOLD(self));
4663}
4664
Tim Petersa9bc1682003-01-11 03:39:11 +00004665static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004666 {"hour", (getter)datetime_hour},
4667 {"minute", (getter)datetime_minute},
4668 {"second", (getter)datetime_second},
4669 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004670 {"tzinfo", (getter)datetime_tzinfo},
4671 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004672 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004673};
4674
4675/*
4676 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004677 */
4678
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004679static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004680 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004681 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004682};
4683
Tim Peters2a799bf2002-12-16 20:18:38 +00004684static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004685datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4686{
4687 PyDateTime_DateTime *me;
4688 char aware = (char)(tzinfo != Py_None);
4689
4690 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4691 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4692 return NULL;
4693 }
4694
4695 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4696 if (me != NULL) {
4697 const char *pdata = PyBytes_AS_STRING(state);
4698
4699 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4700 me->hashcode = -1;
4701 me->hastzinfo = aware;
4702 if (aware) {
4703 Py_INCREF(tzinfo);
4704 me->tzinfo = tzinfo;
4705 }
4706 if (pdata[2] & (1 << 7)) {
4707 me->data[2] -= 128;
4708 me->fold = 1;
4709 }
4710 else {
4711 me->fold = 0;
4712 }
4713 }
4714 return (PyObject *)me;
4715}
4716
4717static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004718datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004720 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004721 int year;
4722 int month;
4723 int day;
4724 int hour = 0;
4725 int minute = 0;
4726 int second = 0;
4727 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004728 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004729 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004731 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004732 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4733 PyObject *state = PyTuple_GET_ITEM(args, 0);
4734 if (PyTuple_GET_SIZE(args) == 2) {
4735 tzinfo = PyTuple_GET_ITEM(args, 1);
4736 }
4737 if (PyBytes_Check(state)) {
4738 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4739 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4740 {
4741 return datetime_from_pickle(type, state, tzinfo);
4742 }
4743 }
4744 else if (PyUnicode_Check(state)) {
4745 if (PyUnicode_READY(state)) {
4746 return NULL;
4747 }
4748 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4749 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4750 {
4751 state = PyUnicode_AsLatin1String(state);
4752 if (state == NULL) {
4753 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4754 /* More informative error message. */
4755 PyErr_SetString(PyExc_ValueError,
4756 "Failed to encode latin1 string when unpickling "
4757 "a datetime object. "
4758 "pickle.load(data, encoding='latin1') is assumed.");
4759 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004760 return NULL;
4761 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004762 self = datetime_from_pickle(type, state, tzinfo);
4763 Py_DECREF(state);
4764 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004765 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004766 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004767 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004768 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004769
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004770 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004771 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004772 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004773 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004774 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004775 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004776 }
4777 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004778}
4779
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004780/* TM_FUNC is the shared type of _PyTime_localtime() and
4781 * _PyTime_gmtime(). */
4782typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004783
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004784/* As of version 2015f max fold in IANA database is
4785 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004786static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004787/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004788static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004789
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004790static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004791utc_to_seconds(int year, int month, int day,
4792 int hour, int minute, int second)
4793{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004794 long long ordinal;
4795
4796 /* ymd_to_ord() doesn't support year <= 0 */
4797 if (year < MINYEAR || year > MAXYEAR) {
4798 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4799 return -1;
4800 }
4801
4802 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004803 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4804}
4805
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004806static long long
4807local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004808{
4809 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004810 time_t t;
4811 u -= epoch;
4812 t = u;
4813 if (t != u) {
4814 PyErr_SetString(PyExc_OverflowError,
4815 "timestamp out of range for platform time_t");
4816 return -1;
4817 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004818 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004819 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004820 return utc_to_seconds(local_time.tm_year + 1900,
4821 local_time.tm_mon + 1,
4822 local_time.tm_mday,
4823 local_time.tm_hour,
4824 local_time.tm_min,
4825 local_time.tm_sec);
4826}
4827
Tim Petersa9bc1682003-01-11 03:39:11 +00004828/* Internal helper.
4829 * Build datetime from a time_t and a distinct count of microseconds.
4830 * Pass localtime or gmtime for f, to control the interpretation of timet.
4831 */
4832static PyObject *
4833datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004834 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004835{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004836 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004837 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004838
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004839 if (f(timet, &tm) != 0)
4840 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004841
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004842 year = tm.tm_year + 1900;
4843 month = tm.tm_mon + 1;
4844 day = tm.tm_mday;
4845 hour = tm.tm_hour;
4846 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004847 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004848 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004849 * except to the extent that passing them on to the datetime
4850 * constructor would raise ValueError for a reason that
4851 * made no sense to the user.
4852 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004853 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004854
Victor Stinnerb67f0962017-02-10 10:34:02 +01004855 /* local timezone requires to compute fold */
Ammar Askar96d1e692018-07-25 09:54:58 -07004856 if (tzinfo == Py_None && f == _PyTime_localtime
4857 /* On Windows, passing a negative value to local results
4858 * in an OSError because localtime_s on Windows does
4859 * not support negative timestamps. Unfortunately this
4860 * means that fold detection for time values between
4861 * 0 and max_fold_seconds will result in an identical
4862 * error since we subtract max_fold_seconds to detect a
4863 * fold. However, since we know there haven't been any
4864 * folds in the interval [0, max_fold_seconds) in any
4865 * timezone, we can hackily just forego fold detection
4866 * for this time range.
4867 */
4868#ifdef MS_WINDOWS
4869 && (timet - max_fold_seconds > 0)
4870#endif
4871 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004872 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004873
4874 result_seconds = utc_to_seconds(year, month, day,
4875 hour, minute, second);
4876 /* Probe max_fold_seconds to detect a fold. */
4877 probe_seconds = local(epoch + timet - max_fold_seconds);
4878 if (probe_seconds == -1)
4879 return NULL;
4880 transition = result_seconds - probe_seconds - max_fold_seconds;
4881 if (transition < 0) {
4882 probe_seconds = local(epoch + timet + transition);
4883 if (probe_seconds == -1)
4884 return NULL;
4885 if (probe_seconds == result_seconds)
4886 fold = 1;
4887 }
4888 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004889 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4890 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004891}
4892
4893/* Internal helper.
4894 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4895 * to control the interpretation of the timestamp. Since a double doesn't
4896 * have enough bits to cover a datetime's full range of precision, it's
4897 * better to call datetime_from_timet_and_us provided you have a way
4898 * to get that much precision (e.g., C time() isn't good enough).
4899 */
4900static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004901datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004902 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004903{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004904 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004905 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004906
Victor Stinnere4a994d2015-03-30 01:10:14 +02004907 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004908 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004909 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004910
Victor Stinner21f58932012-03-14 00:15:40 +01004911 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004912}
4913
4914/* Internal helper.
4915 * Build most accurate possible datetime for current time. Pass localtime or
4916 * gmtime for f as appropriate.
4917 */
4918static PyObject *
4919datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4920{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004921 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004922 time_t secs;
4923 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004924
Victor Stinner1e2b6882015-09-18 13:23:02 +02004925 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004926 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004927 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004928
Victor Stinner1e2b6882015-09-18 13:23:02 +02004929 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004930}
4931
Larry Hastings61272b72014-01-07 12:41:53 -08004932/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004933
4934@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004935datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004936
4937 tz: object = None
4938 Timezone object.
4939
4940Returns new datetime object representing current time local to tz.
4941
4942If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004943[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004944
Larry Hastings31826802013-10-19 00:09:25 -07004945static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004946datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004947/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004949 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004950
Larry Hastings31826802013-10-19 00:09:25 -07004951 /* Return best possible local time -- this isn't constrained by the
4952 * precision of a timestamp.
4953 */
4954 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004955 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004956
Larry Hastings5c661892014-01-24 06:17:25 -08004957 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004958 tz == Py_None ? _PyTime_localtime :
4959 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004960 tz);
4961 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004962 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004963 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004964 }
4965 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004966}
4967
Tim Petersa9bc1682003-01-11 03:39:11 +00004968/* Return best possible UTC time -- this isn't constrained by the
4969 * precision of a timestamp.
4970 */
4971static PyObject *
4972datetime_utcnow(PyObject *cls, PyObject *dummy)
4973{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004974 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004975}
4976
Tim Peters2a799bf2002-12-16 20:18:38 +00004977/* Return new local datetime from timestamp (Python timestamp -- a double). */
4978static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004979datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004981 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004982 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004983 PyObject *tzinfo = Py_None;
4984 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004985
Victor Stinner5d272cc2012-03-13 13:35:55 +01004986 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004987 keywords, &timestamp, &tzinfo))
4988 return NULL;
4989 if (check_tzinfo_subclass(tzinfo) < 0)
4990 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004992 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004993 tzinfo == Py_None ? _PyTime_localtime :
4994 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004995 timestamp,
4996 tzinfo);
4997 if (self != NULL && tzinfo != Py_None) {
4998 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004999 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005000 }
5001 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005002}
5003
Tim Petersa9bc1682003-01-11 03:39:11 +00005004/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
5005static PyObject *
5006datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
5007{
Victor Stinner5d272cc2012-03-13 13:35:55 +01005008 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005009 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005010
Victor Stinner5d272cc2012-03-13 13:35:55 +01005011 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005012 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005013 Py_None);
5014 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005015}
5016
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005017/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005018static PyObject *
5019datetime_strptime(PyObject *cls, PyObject *args)
5020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005021 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005022 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02005023 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005024
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005025 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005026 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005027
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005028 if (module == NULL) {
5029 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00005030 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005031 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005032 }
Victor Stinner20401de2016-12-09 15:24:31 +01005033 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
5034 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005035}
5036
Tim Petersa9bc1682003-01-11 03:39:11 +00005037/* Return new datetime from date/datetime and time arguments. */
5038static PyObject *
5039datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
5040{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005041 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005042 PyObject *date;
5043 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005044 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005045 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00005046
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005047 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005048 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005049 &PyDateTime_TimeType, &time, &tzinfo)) {
5050 if (tzinfo == NULL) {
5051 if (HASTZINFO(time))
5052 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
5053 else
5054 tzinfo = Py_None;
5055 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005056 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
5057 GET_MONTH(date),
5058 GET_DAY(date),
5059 TIME_GET_HOUR(time),
5060 TIME_GET_MINUTE(time),
5061 TIME_GET_SECOND(time),
5062 TIME_GET_MICROSECOND(time),
5063 tzinfo,
5064 TIME_GET_FOLD(time),
5065 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005066 }
5067 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005068}
Tim Peters2a799bf2002-12-16 20:18:38 +00005069
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005070static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005071_sanitize_isoformat_str(PyObject *dtstr)
5072{
Paul Ganssle096329f2018-08-23 11:06:20 -04005073 // `fromisoformat` allows surrogate characters in exactly one position,
5074 // the separator; to allow datetime_fromisoformat to make the simplifying
5075 // assumption that all valid strings can be encoded in UTF-8, this function
5076 // replaces any surrogate character separators with `T`.
Paul Ganssle3df85402018-10-22 12:32:52 -04005077 //
5078 // The result of this, if not NULL, returns a new reference
Paul Ganssle096329f2018-08-23 11:06:20 -04005079 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005080 if (len < 0) {
5081 return NULL;
5082 }
5083
5084 if (len <= 10 ||
5085 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
5086 Py_INCREF(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005087 return dtstr;
5088 }
5089
Paul Ganssle3df85402018-10-22 12:32:52 -04005090 PyObject *str_out = _PyUnicode_Copy(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005091 if (str_out == NULL) {
5092 return NULL;
5093 }
5094
Paul Ganssle3df85402018-10-22 12:32:52 -04005095 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005096 Py_DECREF(str_out);
5097 return NULL;
5098 }
5099
Paul Ganssle096329f2018-08-23 11:06:20 -04005100 return str_out;
5101}
5102
5103static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005104datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5105{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005106 assert(dtstr != NULL);
5107
5108 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005109 PyErr_SetString(PyExc_TypeError,
5110 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005111 return NULL;
5112 }
5113
Paul Ganssle3df85402018-10-22 12:32:52 -04005114 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5115 if (dtstr_clean == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005116 goto error;
5117 }
5118
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005119 Py_ssize_t len;
Paul Ganssle3df85402018-10-22 12:32:52 -04005120 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04005121
5122 if (dt_ptr == NULL) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005123 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5124 // Encoding errors are invalid string errors at this point
5125 goto invalid_string_error;
5126 }
5127 else {
5128 goto error;
5129 }
Paul Ganssle096329f2018-08-23 11:06:20 -04005130 }
5131
5132 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005133
5134 int year = 0, month = 0, day = 0;
5135 int hour = 0, minute = 0, second = 0, microsecond = 0;
5136 int tzoffset = 0, tzusec = 0;
5137
5138 // date has a fixed length of 10
5139 int rv = parse_isoformat_date(p, &year, &month, &day);
5140
5141 if (!rv && len > 10) {
5142 // In UTF-8, the length of multi-byte characters is encoded in the MSB
5143 if ((p[10] & 0x80) == 0) {
5144 p += 11;
Paul Ganssle3df85402018-10-22 12:32:52 -04005145 }
5146 else {
5147 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005148 case 0xe0:
5149 p += 13;
5150 break;
5151 case 0xf0:
5152 p += 14;
5153 break;
5154 default:
5155 p += 12;
5156 break;
5157 }
5158 }
5159
5160 len -= (p - dt_ptr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005161 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5162 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005163 }
5164 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005165 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005166 }
5167
Paul Ganssle3df85402018-10-22 12:32:52 -04005168 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005169 if (tzinfo == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005170 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005171 }
5172
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005173 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5174 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005175
5176 Py_DECREF(tzinfo);
Paul Ganssle3df85402018-10-22 12:32:52 -04005177 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005178 return dt;
Paul Ganssle096329f2018-08-23 11:06:20 -04005179
5180invalid_string_error:
5181 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5182
5183error:
Paul Ganssle3df85402018-10-22 12:32:52 -04005184 Py_XDECREF(dtstr_clean);
Paul Ganssle096329f2018-08-23 11:06:20 -04005185
5186 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005187}
5188
Tim Peters2a799bf2002-12-16 20:18:38 +00005189/*
5190 * Destructor.
5191 */
5192
5193static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005194datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005196 if (HASTZINFO(self)) {
5197 Py_XDECREF(self->tzinfo);
5198 }
5199 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005200}
5201
5202/*
5203 * Indirect access to tzinfo methods.
5204 */
5205
Tim Peters2a799bf2002-12-16 20:18:38 +00005206/* These are all METH_NOARGS, so don't need to check the arglist. */
5207static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005208datetime_utcoffset(PyObject *self, PyObject *unused) {
5209 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005210}
5211
5212static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005213datetime_dst(PyObject *self, PyObject *unused) {
5214 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005215}
5216
5217static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005218datetime_tzname(PyObject *self, PyObject *unused) {
5219 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005220}
5221
5222/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005223 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005224 */
5225
Tim Petersa9bc1682003-01-11 03:39:11 +00005226/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5227 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005228 */
5229static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005230add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005231 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005233 /* Note that the C-level additions can't overflow, because of
5234 * invariant bounds on the member values.
5235 */
5236 int year = GET_YEAR(date);
5237 int month = GET_MONTH(date);
5238 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5239 int hour = DATE_GET_HOUR(date);
5240 int minute = DATE_GET_MINUTE(date);
5241 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5242 int microsecond = DATE_GET_MICROSECOND(date) +
5243 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005245 assert(factor == 1 || factor == -1);
5246 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005247 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005248 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005249 }
5250
Paul Ganssle89427cd2019-02-04 14:42:04 -05005251 return new_datetime_subclass_ex(year, month, day,
5252 hour, minute, second, microsecond,
5253 HASTZINFO(date) ? date->tzinfo : Py_None,
5254 (PyObject *)Py_TYPE(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00005255}
5256
5257static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005258datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005260 if (PyDateTime_Check(left)) {
5261 /* datetime + ??? */
5262 if (PyDelta_Check(right))
5263 /* datetime + delta */
5264 return add_datetime_timedelta(
5265 (PyDateTime_DateTime *)left,
5266 (PyDateTime_Delta *)right,
5267 1);
5268 }
5269 else if (PyDelta_Check(left)) {
5270 /* delta + datetime */
5271 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5272 (PyDateTime_Delta *) left,
5273 1);
5274 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005275 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005276}
5277
5278static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005279datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005281 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005283 if (PyDateTime_Check(left)) {
5284 /* datetime - ??? */
5285 if (PyDateTime_Check(right)) {
5286 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005287 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005288 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005289
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005290 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5291 offset2 = offset1 = Py_None;
5292 Py_INCREF(offset1);
5293 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005294 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005295 else {
5296 offset1 = datetime_utcoffset(left, NULL);
5297 if (offset1 == NULL)
5298 return NULL;
5299 offset2 = datetime_utcoffset(right, NULL);
5300 if (offset2 == NULL) {
5301 Py_DECREF(offset1);
5302 return NULL;
5303 }
5304 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5305 PyErr_SetString(PyExc_TypeError,
5306 "can't subtract offset-naive and "
5307 "offset-aware datetimes");
5308 Py_DECREF(offset1);
5309 Py_DECREF(offset2);
5310 return NULL;
5311 }
5312 }
5313 if ((offset1 != offset2) &&
5314 delta_cmp(offset1, offset2) != 0) {
5315 offdiff = delta_subtract(offset1, offset2);
5316 if (offdiff == NULL) {
5317 Py_DECREF(offset1);
5318 Py_DECREF(offset2);
5319 return NULL;
5320 }
5321 }
5322 Py_DECREF(offset1);
5323 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005324 delta_d = ymd_to_ord(GET_YEAR(left),
5325 GET_MONTH(left),
5326 GET_DAY(left)) -
5327 ymd_to_ord(GET_YEAR(right),
5328 GET_MONTH(right),
5329 GET_DAY(right));
5330 /* These can't overflow, since the values are
5331 * normalized. At most this gives the number of
5332 * seconds in one day.
5333 */
5334 delta_s = (DATE_GET_HOUR(left) -
5335 DATE_GET_HOUR(right)) * 3600 +
5336 (DATE_GET_MINUTE(left) -
5337 DATE_GET_MINUTE(right)) * 60 +
5338 (DATE_GET_SECOND(left) -
5339 DATE_GET_SECOND(right));
5340 delta_us = DATE_GET_MICROSECOND(left) -
5341 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005342 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005343 if (result == NULL)
5344 return NULL;
5345
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005346 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005347 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005348 Py_DECREF(offdiff);
5349 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005350 }
5351 else if (PyDelta_Check(right)) {
5352 /* datetime - delta */
5353 result = add_datetime_timedelta(
5354 (PyDateTime_DateTime *)left,
5355 (PyDateTime_Delta *)right,
5356 -1);
5357 }
5358 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005360 if (result == Py_NotImplemented)
5361 Py_INCREF(result);
5362 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005363}
5364
5365/* Various ways to turn a datetime into a string. */
5366
5367static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005368datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005370 const char *type_name = Py_TYPE(self)->tp_name;
5371 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005373 if (DATE_GET_MICROSECOND(self)) {
5374 baserepr = PyUnicode_FromFormat(
5375 "%s(%d, %d, %d, %d, %d, %d, %d)",
5376 type_name,
5377 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5378 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5379 DATE_GET_SECOND(self),
5380 DATE_GET_MICROSECOND(self));
5381 }
5382 else if (DATE_GET_SECOND(self)) {
5383 baserepr = PyUnicode_FromFormat(
5384 "%s(%d, %d, %d, %d, %d, %d)",
5385 type_name,
5386 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5387 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5388 DATE_GET_SECOND(self));
5389 }
5390 else {
5391 baserepr = PyUnicode_FromFormat(
5392 "%s(%d, %d, %d, %d, %d)",
5393 type_name,
5394 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5395 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5396 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005397 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5398 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005399 if (baserepr == NULL || ! HASTZINFO(self))
5400 return baserepr;
5401 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005402}
5403
Tim Petersa9bc1682003-01-11 03:39:11 +00005404static PyObject *
5405datetime_str(PyDateTime_DateTime *self)
5406{
Victor Stinner4c381542016-12-09 00:33:39 +01005407 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005408}
Tim Peters2a799bf2002-12-16 20:18:38 +00005409
5410static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005411datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005413 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005414 char *timespec = NULL;
5415 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005416 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005417 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005418 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005419 static char *specs[][2] = {
5420 {"hours", "%04d-%02d-%02d%c%02d"},
5421 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5422 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5423 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5424 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5425 };
5426 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005427
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005428 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005429 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005430
5431 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5432 if (us == 0) {
5433 /* seconds */
5434 given_spec = 2;
5435 }
5436 else {
5437 /* microseconds */
5438 given_spec = 4;
5439 }
5440 }
5441 else {
5442 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5443 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5444 if (given_spec == 3) {
5445 us = us / 1000;
5446 }
5447 break;
5448 }
5449 }
5450 }
5451
5452 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5453 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5454 return NULL;
5455 }
5456 else {
5457 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005458 GET_YEAR(self), GET_MONTH(self),
5459 GET_DAY(self), (int)sep,
5460 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5461 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005462 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005464 if (!result || !HASTZINFO(self))
5465 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005467 /* We need to append the UTC offset. */
5468 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5469 (PyObject *)self) < 0) {
5470 Py_DECREF(result);
5471 return NULL;
5472 }
5473 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5474 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005475}
5476
Tim Petersa9bc1682003-01-11 03:39:11 +00005477static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305478datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005479{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005480 return format_ctime((PyDateTime_Date *)self,
5481 DATE_GET_HOUR(self),
5482 DATE_GET_MINUTE(self),
5483 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005484}
5485
Tim Peters2a799bf2002-12-16 20:18:38 +00005486/* Miscellaneous methods. */
5487
Tim Petersa9bc1682003-01-11 03:39:11 +00005488static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005489flip_fold(PyObject *dt)
5490{
5491 return new_datetime_ex2(GET_YEAR(dt),
5492 GET_MONTH(dt),
5493 GET_DAY(dt),
5494 DATE_GET_HOUR(dt),
5495 DATE_GET_MINUTE(dt),
5496 DATE_GET_SECOND(dt),
5497 DATE_GET_MICROSECOND(dt),
5498 HASTZINFO(dt) ?
5499 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5500 !DATE_GET_FOLD(dt),
5501 Py_TYPE(dt));
5502}
5503
5504static PyObject *
5505get_flip_fold_offset(PyObject *dt)
5506{
5507 PyObject *result, *flip_dt;
5508
5509 flip_dt = flip_fold(dt);
5510 if (flip_dt == NULL)
5511 return NULL;
5512 result = datetime_utcoffset(flip_dt, NULL);
5513 Py_DECREF(flip_dt);
5514 return result;
5515}
5516
5517/* PEP 495 exception: Whenever one or both of the operands in
5518 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakabac2d5b2018-03-28 22:14:26 +03005519 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005520 *
5521 * Return 1 if exception applies, 0 if not, and -1 on error.
5522 */
5523static int
5524pep495_eq_exception(PyObject *self, PyObject *other,
5525 PyObject *offset_self, PyObject *offset_other)
5526{
5527 int result = 0;
5528 PyObject *flip_offset;
5529
5530 flip_offset = get_flip_fold_offset(self);
5531 if (flip_offset == NULL)
5532 return -1;
5533 if (flip_offset != offset_self &&
5534 delta_cmp(flip_offset, offset_self))
5535 {
5536 result = 1;
5537 goto done;
5538 }
5539 Py_DECREF(flip_offset);
5540
5541 flip_offset = get_flip_fold_offset(other);
5542 if (flip_offset == NULL)
5543 return -1;
5544 if (flip_offset != offset_other &&
5545 delta_cmp(flip_offset, offset_other))
5546 result = 1;
5547 done:
5548 Py_DECREF(flip_offset);
5549 return result;
5550}
5551
5552static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005553datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005554{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005555 PyObject *result = NULL;
5556 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005557 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005559 if (! PyDateTime_Check(other)) {
5560 if (PyDate_Check(other)) {
5561 /* Prevent invocation of date_richcompare. We want to
5562 return NotImplemented here to give the other object
5563 a chance. But since DateTime is a subclass of
5564 Date, if the other object is a Date, it would
5565 compute an ordering based on the date part alone,
5566 and we don't want that. So force unequal or
5567 uncomparable here in that case. */
5568 if (op == Py_EQ)
5569 Py_RETURN_FALSE;
5570 if (op == Py_NE)
5571 Py_RETURN_TRUE;
5572 return cmperror(self, other);
5573 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005574 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005575 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005576
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005577 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005578 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5579 ((PyDateTime_DateTime *)other)->data,
5580 _PyDateTime_DATETIME_DATASIZE);
5581 return diff_to_bool(diff, op);
5582 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005583 offset1 = datetime_utcoffset(self, NULL);
5584 if (offset1 == NULL)
5585 return NULL;
5586 offset2 = datetime_utcoffset(other, NULL);
5587 if (offset2 == NULL)
5588 goto done;
5589 /* If they're both naive, or both aware and have the same offsets,
5590 * we get off cheap. Note that if they're both naive, offset1 ==
5591 * offset2 == Py_None at this point.
5592 */
5593 if ((offset1 == offset2) ||
5594 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5595 delta_cmp(offset1, offset2) == 0)) {
5596 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5597 ((PyDateTime_DateTime *)other)->data,
5598 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005599 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5600 int ex = pep495_eq_exception(self, other, offset1, offset2);
5601 if (ex == -1)
5602 goto done;
5603 if (ex)
5604 diff = 1;
5605 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005606 result = diff_to_bool(diff, op);
5607 }
5608 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005609 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005610
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005611 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005612 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5613 other);
5614 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005615 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005616 diff = GET_TD_DAYS(delta);
5617 if (diff == 0)
5618 diff = GET_TD_SECONDS(delta) |
5619 GET_TD_MICROSECONDS(delta);
5620 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005621 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5622 int ex = pep495_eq_exception(self, other, offset1, offset2);
5623 if (ex == -1)
5624 goto done;
5625 if (ex)
5626 diff = 1;
5627 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005628 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005629 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005630 else if (op == Py_EQ) {
5631 result = Py_False;
5632 Py_INCREF(result);
5633 }
5634 else if (op == Py_NE) {
5635 result = Py_True;
5636 Py_INCREF(result);
5637 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005638 else {
5639 PyErr_SetString(PyExc_TypeError,
5640 "can't compare offset-naive and "
5641 "offset-aware datetimes");
5642 }
5643 done:
5644 Py_DECREF(offset1);
5645 Py_XDECREF(offset2);
5646 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005647}
5648
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005649static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005650datetime_hash(PyDateTime_DateTime *self)
5651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005652 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005653 PyObject *offset, *self0;
5654 if (DATE_GET_FOLD(self)) {
5655 self0 = new_datetime_ex2(GET_YEAR(self),
5656 GET_MONTH(self),
5657 GET_DAY(self),
5658 DATE_GET_HOUR(self),
5659 DATE_GET_MINUTE(self),
5660 DATE_GET_SECOND(self),
5661 DATE_GET_MICROSECOND(self),
5662 HASTZINFO(self) ? self->tzinfo : Py_None,
5663 0, Py_TYPE(self));
5664 if (self0 == NULL)
5665 return -1;
5666 }
5667 else {
5668 self0 = (PyObject *)self;
5669 Py_INCREF(self0);
5670 }
5671 offset = datetime_utcoffset(self0, NULL);
5672 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005673
5674 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005675 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005677 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005678 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005679 self->hashcode = generic_hash(
5680 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005681 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005682 PyObject *temp1, *temp2;
5683 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005685 assert(HASTZINFO(self));
5686 days = ymd_to_ord(GET_YEAR(self),
5687 GET_MONTH(self),
5688 GET_DAY(self));
5689 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005690 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005691 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005692 temp1 = new_delta(days, seconds,
5693 DATE_GET_MICROSECOND(self),
5694 1);
5695 if (temp1 == NULL) {
5696 Py_DECREF(offset);
5697 return -1;
5698 }
5699 temp2 = delta_subtract(temp1, offset);
5700 Py_DECREF(temp1);
5701 if (temp2 == NULL) {
5702 Py_DECREF(offset);
5703 return -1;
5704 }
5705 self->hashcode = PyObject_Hash(temp2);
5706 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005707 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005708 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005709 }
5710 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005711}
Tim Peters2a799bf2002-12-16 20:18:38 +00005712
5713static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005714datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005716 PyObject *clone;
5717 PyObject *tuple;
5718 int y = GET_YEAR(self);
5719 int m = GET_MONTH(self);
5720 int d = GET_DAY(self);
5721 int hh = DATE_GET_HOUR(self);
5722 int mm = DATE_GET_MINUTE(self);
5723 int ss = DATE_GET_SECOND(self);
5724 int us = DATE_GET_MICROSECOND(self);
5725 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005726 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005727
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005728 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005729 datetime_kws,
5730 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005731 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005732 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005733 if (fold != 0 && fold != 1) {
5734 PyErr_SetString(PyExc_ValueError,
5735 "fold must be either 0 or 1");
5736 return NULL;
5737 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005738 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5739 if (tuple == NULL)
5740 return NULL;
5741 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005742 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005743 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005744 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005745 Py_DECREF(tuple);
5746 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005747}
5748
5749static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005750local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005751{
5752 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005753 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005754 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005755 PyObject *nameo = NULL;
5756 const char *zone = NULL;
5757
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005758 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005759 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005760#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005761 zone = local_time_tm.tm_zone;
5762 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005763#else /* HAVE_STRUCT_TM_TM_ZONE */
5764 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005765 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005766 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005767 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005768 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005769 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005770 local_time = new_datetime(local_time_tm.tm_year + 1900,
5771 local_time_tm.tm_mon + 1,
5772 local_time_tm.tm_mday,
5773 local_time_tm.tm_hour,
5774 local_time_tm.tm_min,
5775 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005776 if (local_time == NULL) {
5777 return NULL;
5778 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005779 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005780 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005781 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5782 utc_time_tm.tm_mon + 1,
5783 utc_time_tm.tm_mday,
5784 utc_time_tm.tm_hour,
5785 utc_time_tm.tm_min,
5786 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005787 if (utc_time == NULL) {
5788 Py_DECREF(local_time);
5789 return NULL;
5790 }
5791 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005792 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005793 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005794 }
5795#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005796 if (delta == NULL) {
5797 return NULL;
5798 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005799 if (zone != NULL) {
5800 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5801 if (nameo == NULL)
5802 goto error;
5803 }
5804 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005805 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005806 error:
5807 Py_DECREF(delta);
5808 return result;
5809}
5810
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005811static PyObject *
5812local_timezone(PyDateTime_DateTime *utc_time)
5813{
5814 time_t timestamp;
5815 PyObject *delta;
5816 PyObject *one_second;
5817 PyObject *seconds;
5818
5819 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5820 if (delta == NULL)
5821 return NULL;
5822 one_second = new_delta(0, 1, 0, 0);
5823 if (one_second == NULL) {
5824 Py_DECREF(delta);
5825 return NULL;
5826 }
5827 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5828 (PyDateTime_Delta *)one_second);
5829 Py_DECREF(one_second);
5830 Py_DECREF(delta);
5831 if (seconds == NULL)
5832 return NULL;
5833 timestamp = _PyLong_AsTime_t(seconds);
5834 Py_DECREF(seconds);
5835 if (timestamp == -1 && PyErr_Occurred())
5836 return NULL;
5837 return local_timezone_from_timestamp(timestamp);
5838}
5839
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005840static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005841local_to_seconds(int year, int month, int day,
5842 int hour, int minute, int second, int fold);
5843
5844static PyObject *
5845local_timezone_from_local(PyDateTime_DateTime *local_dt)
5846{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005847 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005848 time_t timestamp;
5849 seconds = local_to_seconds(GET_YEAR(local_dt),
5850 GET_MONTH(local_dt),
5851 GET_DAY(local_dt),
5852 DATE_GET_HOUR(local_dt),
5853 DATE_GET_MINUTE(local_dt),
5854 DATE_GET_SECOND(local_dt),
5855 DATE_GET_FOLD(local_dt));
5856 if (seconds == -1)
5857 return NULL;
5858 /* XXX: add bounds check */
5859 timestamp = seconds - epoch;
5860 return local_timezone_from_timestamp(timestamp);
5861}
5862
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005863static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005864datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005865{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005866 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005867 PyObject *offset;
5868 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005869 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005870 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005871 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005872
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005873 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005874 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005875 return NULL;
5876
5877 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005878 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005879
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005880 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005881 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005882 self_tzinfo = local_timezone_from_local(self);
5883 if (self_tzinfo == NULL)
5884 return NULL;
5885 } else {
5886 self_tzinfo = self->tzinfo;
5887 Py_INCREF(self_tzinfo);
5888 }
Tim Peters521fc152002-12-31 17:36:56 +00005889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005890 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005891 if (self_tzinfo == tzinfo) {
5892 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005893 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005894 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005895 }
Tim Peters521fc152002-12-31 17:36:56 +00005896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005897 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005898 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5899 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005900 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005901 return NULL;
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005902 else if(offset == Py_None) {
5903 Py_DECREF(offset);
5904 goto naive;
5905 }
5906 else if (!PyDelta_Check(offset)) {
5907 Py_DECREF(offset);
5908 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5909 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5910 return NULL;
5911 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005912 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005913 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5914 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005915 Py_DECREF(offset);
5916 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005917 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005918
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005919 /* Make sure result is aware and UTC. */
5920 if (!HASTZINFO(result)) {
5921 temp = (PyObject *)result;
5922 result = (PyDateTime_DateTime *)
5923 new_datetime_ex2(GET_YEAR(result),
5924 GET_MONTH(result),
5925 GET_DAY(result),
5926 DATE_GET_HOUR(result),
5927 DATE_GET_MINUTE(result),
5928 DATE_GET_SECOND(result),
5929 DATE_GET_MICROSECOND(result),
5930 PyDateTime_TimeZone_UTC,
5931 DATE_GET_FOLD(result),
5932 Py_TYPE(result));
5933 Py_DECREF(temp);
5934 if (result == NULL)
5935 return NULL;
5936 }
5937 else {
5938 /* Result is already aware - just replace tzinfo. */
5939 temp = result->tzinfo;
5940 result->tzinfo = PyDateTime_TimeZone_UTC;
5941 Py_INCREF(result->tzinfo);
5942 Py_DECREF(temp);
5943 }
5944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005945 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005946 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005947 if (tzinfo == Py_None) {
5948 tzinfo = local_timezone(result);
5949 if (tzinfo == NULL) {
5950 Py_DECREF(result);
5951 return NULL;
5952 }
5953 }
5954 else
5955 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005956 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005957 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005958
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005959 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005960 result = (PyDateTime_DateTime *)
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02005961 _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005962 Py_DECREF(temp);
5963
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005964 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005965}
5966
5967static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305968datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00005969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005970 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005972 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005973 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005974
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005975 dst = call_dst(self->tzinfo, (PyObject *)self);
5976 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005977 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005978
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005979 if (dst != Py_None)
5980 dstflag = delta_bool((PyDateTime_Delta *)dst);
5981 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005982 }
5983 return build_struct_time(GET_YEAR(self),
5984 GET_MONTH(self),
5985 GET_DAY(self),
5986 DATE_GET_HOUR(self),
5987 DATE_GET_MINUTE(self),
5988 DATE_GET_SECOND(self),
5989 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005990}
5991
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005992static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005993local_to_seconds(int year, int month, int day,
5994 int hour, int minute, int second, int fold)
5995{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005996 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005997 t = utc_to_seconds(year, month, day, hour, minute, second);
5998 /* Our goal is to solve t = local(u) for u. */
5999 lt = local(t);
6000 if (lt == -1)
6001 return -1;
6002 a = lt - t;
6003 u1 = t - a;
6004 t1 = local(u1);
6005 if (t1 == -1)
6006 return -1;
6007 if (t1 == t) {
6008 /* We found one solution, but it may not be the one we need.
6009 * Look for an earlier solution (if `fold` is 0), or a
6010 * later one (if `fold` is 1). */
6011 if (fold)
6012 u2 = u1 + max_fold_seconds;
6013 else
6014 u2 = u1 - max_fold_seconds;
6015 lt = local(u2);
6016 if (lt == -1)
6017 return -1;
6018 b = lt - u2;
6019 if (a == b)
6020 return u1;
6021 }
6022 else {
6023 b = t1 - u1;
6024 assert(a != b);
6025 }
6026 u2 = t - b;
6027 t2 = local(u2);
6028 if (t2 == -1)
6029 return -1;
6030 if (t2 == t)
6031 return u2;
6032 if (t1 == t)
6033 return u1;
6034 /* We have found both offsets a and b, but neither t - a nor t - b is
6035 * a solution. This means t is in the gap. */
6036 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
6037}
6038
6039/* date(1970,1,1).toordinal() == 719163 */
6040#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
6041
Tim Peters2a799bf2002-12-16 20:18:38 +00006042static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306043datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolskya4415142012-06-08 12:33:09 -04006044{
6045 PyObject *result;
6046
6047 if (HASTZINFO(self) && self->tzinfo != Py_None) {
6048 PyObject *delta;
6049 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
6050 if (delta == NULL)
6051 return NULL;
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306052 result = delta_total_seconds(delta, NULL);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006053 Py_DECREF(delta);
6054 }
6055 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006056 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006057 seconds = local_to_seconds(GET_YEAR(self),
6058 GET_MONTH(self),
6059 GET_DAY(self),
6060 DATE_GET_HOUR(self),
6061 DATE_GET_MINUTE(self),
6062 DATE_GET_SECOND(self),
6063 DATE_GET_FOLD(self));
6064 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04006065 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006066 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
6067 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006068 }
6069 return result;
6070}
6071
6072static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306073datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006075 return new_date(GET_YEAR(self),
6076 GET_MONTH(self),
6077 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006078}
6079
6080static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306081datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006083 return new_time(DATE_GET_HOUR(self),
6084 DATE_GET_MINUTE(self),
6085 DATE_GET_SECOND(self),
6086 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006087 Py_None,
6088 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006089}
6090
6091static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306092datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006094 return new_time(DATE_GET_HOUR(self),
6095 DATE_GET_MINUTE(self),
6096 DATE_GET_SECOND(self),
6097 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006098 GET_DT_TZINFO(self),
6099 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006100}
6101
6102static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306103datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006104{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006105 int y, m, d, hh, mm, ss;
6106 PyObject *tzinfo;
6107 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006108
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006109 tzinfo = GET_DT_TZINFO(self);
6110 if (tzinfo == Py_None) {
6111 utcself = self;
6112 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006113 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006114 else {
6115 PyObject *offset;
6116 offset = call_utcoffset(tzinfo, (PyObject *)self);
6117 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006118 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006119 if (offset == Py_None) {
6120 Py_DECREF(offset);
6121 utcself = self;
6122 Py_INCREF(utcself);
6123 }
6124 else {
6125 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6126 (PyDateTime_Delta *)offset, -1);
6127 Py_DECREF(offset);
6128 if (utcself == NULL)
6129 return NULL;
6130 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006131 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006132 y = GET_YEAR(utcself);
6133 m = GET_MONTH(utcself);
6134 d = GET_DAY(utcself);
6135 hh = DATE_GET_HOUR(utcself);
6136 mm = DATE_GET_MINUTE(utcself);
6137 ss = DATE_GET_SECOND(utcself);
6138
6139 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006140 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006141}
6142
Tim Peters371935f2003-02-01 01:52:50 +00006143/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006144
Tim Petersa9bc1682003-01-11 03:39:11 +00006145/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006146 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6147 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006148 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006149 */
6150static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006151datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006153 PyObject *basestate;
6154 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006156 basestate = PyBytes_FromStringAndSize((char *)self->data,
6157 _PyDateTime_DATETIME_DATASIZE);
6158 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006159 if (proto > 3 && DATE_GET_FOLD(self))
6160 /* Set the first bit of the third byte */
6161 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006162 if (! HASTZINFO(self) || self->tzinfo == Py_None)
6163 result = PyTuple_Pack(1, basestate);
6164 else
6165 result = PyTuple_Pack(2, basestate, self->tzinfo);
6166 Py_DECREF(basestate);
6167 }
6168 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00006169}
6170
6171static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006172datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006173{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006174 int proto;
6175 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006176 return NULL;
6177
6178 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006179}
6180
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006181static PyObject *
6182datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6183{
6184 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6185}
6186
Tim Petersa9bc1682003-01-11 03:39:11 +00006187static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006189 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006190
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006191 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006193 {"utcnow", (PyCFunction)datetime_utcnow,
6194 METH_NOARGS | METH_CLASS,
6195 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006196
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006197 {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006198 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6199 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006201 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6202 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006203 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006205 {"strptime", (PyCFunction)datetime_strptime,
6206 METH_VARARGS | METH_CLASS,
6207 PyDoc_STR("string, format -> new datetime parsed from a string "
6208 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006209
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006210 {"combine", (PyCFunction)(void(*)(void))datetime_combine,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006211 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6212 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006213
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006214 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6215 METH_O | METH_CLASS,
6216 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006218 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006220 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6221 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006223 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6224 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006226 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6227 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006229 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6230 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006232 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6233 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006234
Alexander Belopolskya4415142012-06-08 12:33:09 -04006235 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6236 PyDoc_STR("Return POSIX timestamp as float.")},
6237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006238 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6239 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006240
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006241 {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006242 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006243 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006244 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006245 "defaults to 'T'.\n"
6246 "timespec specifies what components of the time to include"
6247 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6248 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006250 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6251 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006253 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6254 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006256 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6257 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006258
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006259 {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006260 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006261
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006262 {"astimezone", (PyCFunction)(void(*)(void))datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006263 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006264
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006265 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006266 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006267
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006268 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6269 PyDoc_STR("__reduce__() -> (cls, state)")},
6270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006271 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006272};
6273
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006274static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006275PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6276\n\
6277The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006278instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006279
Tim Petersa9bc1682003-01-11 03:39:11 +00006280static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006281 datetime_add, /* nb_add */
6282 datetime_subtract, /* nb_subtract */
6283 0, /* nb_multiply */
6284 0, /* nb_remainder */
6285 0, /* nb_divmod */
6286 0, /* nb_power */
6287 0, /* nb_negative */
6288 0, /* nb_positive */
6289 0, /* nb_absolute */
6290 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006291};
6292
Neal Norwitz227b5332006-03-22 09:28:35 +00006293static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006294 PyVarObject_HEAD_INIT(NULL, 0)
6295 "datetime.datetime", /* tp_name */
6296 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6297 0, /* tp_itemsize */
6298 (destructor)datetime_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006299 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006300 0, /* tp_getattr */
6301 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006302 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006303 (reprfunc)datetime_repr, /* tp_repr */
6304 &datetime_as_number, /* tp_as_number */
6305 0, /* tp_as_sequence */
6306 0, /* tp_as_mapping */
6307 (hashfunc)datetime_hash, /* tp_hash */
6308 0, /* tp_call */
6309 (reprfunc)datetime_str, /* tp_str */
6310 PyObject_GenericGetAttr, /* tp_getattro */
6311 0, /* tp_setattro */
6312 0, /* tp_as_buffer */
6313 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6314 datetime_doc, /* tp_doc */
6315 0, /* tp_traverse */
6316 0, /* tp_clear */
6317 datetime_richcompare, /* tp_richcompare */
6318 0, /* tp_weaklistoffset */
6319 0, /* tp_iter */
6320 0, /* tp_iternext */
6321 datetime_methods, /* tp_methods */
6322 0, /* tp_members */
6323 datetime_getset, /* tp_getset */
6324 &PyDateTime_DateType, /* tp_base */
6325 0, /* tp_dict */
6326 0, /* tp_descr_get */
6327 0, /* tp_descr_set */
6328 0, /* tp_dictoffset */
6329 0, /* tp_init */
6330 datetime_alloc, /* tp_alloc */
6331 datetime_new, /* tp_new */
6332 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006333};
6334
6335/* ---------------------------------------------------------------------------
6336 * Module methods and initialization.
6337 */
6338
6339static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006340 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006341};
6342
Tim Peters9ddf40b2004-06-20 22:41:32 +00006343/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6344 * datetime.h.
6345 */
6346static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006347 &PyDateTime_DateType,
6348 &PyDateTime_DateTimeType,
6349 &PyDateTime_TimeType,
6350 &PyDateTime_DeltaType,
6351 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006352 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006353 new_date_ex,
6354 new_datetime_ex,
6355 new_time_ex,
6356 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006357 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006358 datetime_fromtimestamp,
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04006359 datetime_date_fromtimestamp_capi,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006360 new_datetime_ex2,
6361 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006362};
6363
6364
Martin v. Löwis1a214512008-06-11 05:26:20 +00006365
6366static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006367 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006368 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006369 "Fast implementation of the datetime type.",
6370 -1,
6371 module_methods,
6372 NULL,
6373 NULL,
6374 NULL,
6375 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006376};
6377
Tim Peters2a799bf2002-12-16 20:18:38 +00006378PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006379PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006381 PyObject *m; /* a module object */
6382 PyObject *d; /* its dict */
6383 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006384 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006386 m = PyModule_Create(&datetimemodule);
6387 if (m == NULL)
6388 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006390 if (PyType_Ready(&PyDateTime_DateType) < 0)
6391 return NULL;
6392 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6393 return NULL;
6394 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6395 return NULL;
6396 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6397 return NULL;
6398 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6399 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006400 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6401 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006403 /* timedelta values */
6404 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006406 x = new_delta(0, 0, 1, 0);
6407 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6408 return NULL;
6409 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006411 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6412 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6413 return NULL;
6414 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006416 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6417 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6418 return NULL;
6419 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006421 /* date values */
6422 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006424 x = new_date(1, 1, 1);
6425 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6426 return NULL;
6427 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006429 x = new_date(MAXYEAR, 12, 31);
6430 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6431 return NULL;
6432 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006434 x = new_delta(1, 0, 0, 0);
6435 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6436 return NULL;
6437 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006439 /* time values */
6440 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006441
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006442 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006443 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6444 return NULL;
6445 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006446
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006447 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006448 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6449 return NULL;
6450 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006452 x = new_delta(0, 0, 1, 0);
6453 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6454 return NULL;
6455 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006457 /* datetime values */
6458 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006459
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006460 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006461 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6462 return NULL;
6463 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006464
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006465 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006466 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6467 return NULL;
6468 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006470 x = new_delta(0, 0, 1, 0);
6471 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6472 return NULL;
6473 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006474
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006475 /* timezone values */
6476 d = PyDateTime_TimeZoneType.tp_dict;
6477
6478 delta = new_delta(0, 0, 0, 0);
6479 if (delta == NULL)
6480 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006481 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006482 Py_DECREF(delta);
6483 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6484 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006485 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006486 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006487
Ngalim Siregar92c7e302019-08-09 21:22:16 +07006488 /* bpo-37642: These attributes are rounded to the nearest minute for backwards
6489 * compatibility, even though the constructor will accept a wider range of
6490 * values. This may change in the future.*/
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006491 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6492 if (delta == NULL)
6493 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006494 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006495 Py_DECREF(delta);
6496 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6497 return NULL;
6498 Py_DECREF(x);
6499
6500 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6501 if (delta == NULL)
6502 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006503 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006504 Py_DECREF(delta);
6505 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6506 return NULL;
6507 Py_DECREF(x);
6508
Alexander Belopolskya4415142012-06-08 12:33:09 -04006509 /* Epoch */
6510 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006511 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006512 if (PyDateTime_Epoch == NULL)
6513 return NULL;
6514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006515 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006516 PyModule_AddIntMacro(m, MINYEAR);
6517 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006519 Py_INCREF(&PyDateTime_DateType);
6520 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006522 Py_INCREF(&PyDateTime_DateTimeType);
6523 PyModule_AddObject(m, "datetime",
6524 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006526 Py_INCREF(&PyDateTime_TimeType);
6527 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006529 Py_INCREF(&PyDateTime_DeltaType);
6530 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006532 Py_INCREF(&PyDateTime_TZInfoType);
6533 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006534
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006535 Py_INCREF(&PyDateTime_TimeZoneType);
6536 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006538 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6539 if (x == NULL)
6540 return NULL;
6541 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006543 /* A 4-year cycle has an extra leap day over what we'd get from
6544 * pasting together 4 single years.
6545 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006546 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006547 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006549 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6550 * get from pasting together 4 100-year cycles.
6551 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006552 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006553 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006555 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6556 * pasting together 25 4-year cycles.
6557 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006558 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006559 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006561 us_per_ms = PyLong_FromLong(1000);
6562 us_per_second = PyLong_FromLong(1000000);
6563 us_per_minute = PyLong_FromLong(60000000);
6564 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006565 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006566 us_per_minute == NULL || seconds_per_day == NULL)
6567 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006569 /* The rest are too big for 32-bit ints, but even
6570 * us_per_week fits in 40 bits, so doubles should be exact.
6571 */
6572 us_per_hour = PyLong_FromDouble(3600000000.0);
6573 us_per_day = PyLong_FromDouble(86400000000.0);
6574 us_per_week = PyLong_FromDouble(604800000000.0);
6575 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6576 return NULL;
6577 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006578}
Tim Petersf3615152003-01-01 21:51:37 +00006579
6580/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006581Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006582 x.n = x stripped of its timezone -- its naive time.
6583 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006584 return None
Tim Petersf3615152003-01-01 21:51:37 +00006585 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006586 return None
Tim Petersf3615152003-01-01 21:51:37 +00006587 x.s = x's standard offset, x.o - x.d
6588
6589Now some derived rules, where k is a duration (timedelta).
6590
65911. x.o = x.s + x.d
6592 This follows from the definition of x.s.
6593
Tim Petersc5dc4da2003-01-02 17:55:03 +000065942. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006595 This is actually a requirement, an assumption we need to make about
6596 sane tzinfo classes.
6597
65983. The naive UTC time corresponding to x is x.n - x.o.
6599 This is again a requirement for a sane tzinfo class.
6600
66014. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006602 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006603
Tim Petersc5dc4da2003-01-02 17:55:03 +000066045. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006605 Again follows from how arithmetic is defined.
6606
Tim Peters8bb5ad22003-01-24 02:44:45 +00006607Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006608(meaning that the various tzinfo methods exist, and don't blow up or return
6609None when called).
6610
Tim Petersa9bc1682003-01-11 03:39:11 +00006611The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006612x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006613
6614By #3, we want
6615
Tim Peters8bb5ad22003-01-24 02:44:45 +00006616 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006617
6618The algorithm starts by attaching tz to x.n, and calling that y. So
6619x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6620becomes true; in effect, we want to solve [2] for k:
6621
Tim Peters8bb5ad22003-01-24 02:44:45 +00006622 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006623
6624By #1, this is the same as
6625
Tim Peters8bb5ad22003-01-24 02:44:45 +00006626 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006627
6628By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6629Substituting that into [3],
6630
Tim Peters8bb5ad22003-01-24 02:44:45 +00006631 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6632 k - (y+k).s - (y+k).d = 0; rearranging,
6633 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6634 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006635
Tim Peters8bb5ad22003-01-24 02:44:45 +00006636On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6637approximate k by ignoring the (y+k).d term at first. Note that k can't be
6638very large, since all offset-returning methods return a duration of magnitude
6639less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6640be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006641
6642In any case, the new value is
6643
Tim Peters8bb5ad22003-01-24 02:44:45 +00006644 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006645
Tim Peters8bb5ad22003-01-24 02:44:45 +00006646It's helpful to step back at look at [4] from a higher level: it's simply
6647mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006648
6649At this point, if
6650
Tim Peters8bb5ad22003-01-24 02:44:45 +00006651 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006652
6653we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006654at the start of daylight time. Picture US Eastern for concreteness. The wall
6655time 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 +00006656sense then. The docs ask that an Eastern tzinfo class consider such a time to
6657be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6658on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006659the only spelling that makes sense on the local wall clock.
6660
Tim Petersc5dc4da2003-01-02 17:55:03 +00006661In fact, if [5] holds at this point, we do have the standard-time spelling,
6662but that takes a bit of proof. We first prove a stronger result. What's the
6663difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006664
Tim Peters8bb5ad22003-01-24 02:44:45 +00006665 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006666
Tim Petersc5dc4da2003-01-02 17:55:03 +00006667Now
6668 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006669 (y + y.s).n = by #5
6670 y.n + y.s = since y.n = x.n
6671 x.n + y.s = since z and y are have the same tzinfo member,
6672 y.s = z.s by #2
6673 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006674
Tim Petersc5dc4da2003-01-02 17:55:03 +00006675Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006676
Tim Petersc5dc4da2003-01-02 17:55:03 +00006677 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006678 x.n - ((x.n + z.s) - z.o) = expanding
6679 x.n - x.n - z.s + z.o = cancelling
6680 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006681 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006682
Tim Petersc5dc4da2003-01-02 17:55:03 +00006683So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006684
Tim Petersc5dc4da2003-01-02 17:55:03 +00006685If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006686spelling we wanted in the endcase described above. We're done. Contrarily,
6687if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006688
Tim Petersc5dc4da2003-01-02 17:55:03 +00006689If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6690add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006691local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006692
Tim Petersc5dc4da2003-01-02 17:55:03 +00006693Let
Tim Petersf3615152003-01-01 21:51:37 +00006694
Tim Peters4fede1a2003-01-04 00:26:59 +00006695 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006696
Tim Peters4fede1a2003-01-04 00:26:59 +00006697and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006698
Tim Peters8bb5ad22003-01-24 02:44:45 +00006699 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006700
Tim Peters8bb5ad22003-01-24 02:44:45 +00006701If so, we're done. If not, the tzinfo class is insane, according to the
6702assumptions we've made. This also requires a bit of proof. As before, let's
6703compute the difference between the LHS and RHS of [8] (and skipping some of
6704the justifications for the kinds of substitutions we've done several times
6705already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006706
Tim Peters8bb5ad22003-01-24 02:44:45 +00006707 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006708 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6709 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6710 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6711 - z.n + z.n - z.o + z'.o = cancel z.n
6712 - z.o + z'.o = #1 twice
6713 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6714 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006715
6716So 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 +00006717we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6718return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006719
Tim Peters8bb5ad22003-01-24 02:44:45 +00006720How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6721a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6722would have to change the result dst() returns: we start in DST, and moving
6723a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006724
Tim Peters8bb5ad22003-01-24 02:44:45 +00006725There isn't a sane case where this can happen. The closest it gets is at
6726the end of DST, where there's an hour in UTC with no spelling in a hybrid
6727tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6728that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6729UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6730time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6731clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6732standard time. Since that's what the local clock *does*, we want to map both
6733UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006734in local time, but so it goes -- it's the way the local clock works.
6735
Tim Peters8bb5ad22003-01-24 02:44:45 +00006736When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6737so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6738z' = 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 +00006739(correctly) concludes that z' is not UTC-equivalent to x.
6740
6741Because we know z.d said z was in daylight time (else [5] would have held and
6742we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006743and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006744return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6745but the reasoning doesn't depend on the example -- it depends on there being
6746two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006747z' must be in standard time, and is the spelling we want in this case.
6748
6749Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6750concerned (because it takes z' as being in standard time rather than the
6751daylight time we intend here), but returning it gives the real-life "local
6752clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6753tz.
6754
6755When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6756the 1:MM standard time spelling we want.
6757
6758So how can this break? One of the assumptions must be violated. Two
6759possibilities:
6760
67611) [2] effectively says that y.s is invariant across all y belong to a given
6762 time zone. This isn't true if, for political reasons or continental drift,
6763 a region decides to change its base offset from UTC.
6764
67652) There may be versions of "double daylight" time where the tail end of
6766 the analysis gives up a step too early. I haven't thought about that
6767 enough to say.
6768
6769In any case, it's clear that the default fromutc() is strong enough to handle
6770"almost all" time zones: so long as the standard offset is invariant, it
6771doesn't matter if daylight time transition points change from year to year, or
6772if daylight time is skipped in some years; it doesn't matter how large or
6773small dst() may get within its bounds; and it doesn't even matter if some
6774perverse time zone returns a negative dst()). So a breaking case must be
6775pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006776--------------------------------------------------------------------------- */