blob: 4d3562cbe64f69fc521c8e748ff35672fd37c17f [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
Tim Peters2a799bf2002-12-16 20:18:38 +000035
Larry Hastings61272b72014-01-07 12:41:53 -080036/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080037module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080038class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +020039class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType"
Larry Hastings61272b72014-01-07 12:41:53 -080040[clinic start generated code]*/
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +020041/*[clinic end generated code: output=da39a3ee5e6b4b0d input=25138ad6a696b785]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080042
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030043#include "clinic/_datetimemodule.c.h"
44
Tim Peters2a799bf2002-12-16 20:18:38 +000045/* We require that C int be at least 32 bits, and use int virtually
46 * everywhere. In just a few cases we use a temp long, where a Python
47 * API returns a C long. In such cases, we have to ensure that the
48 * final result fits in a C int (this can be an issue on 64-bit boxes).
49 */
50#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000051# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000052#endif
53
54#define MINYEAR 1
55#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000056#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000057
58/* Nine decimal digits is easy to communicate, and leaves enough room
59 * so that two delta days can be added w/o fear of overflowing a signed
60 * 32-bit int, and with plenty of room left over to absorb any possible
61 * carries from adding seconds.
62 */
63#define MAX_DELTA_DAYS 999999999
64
65/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066#define GET_YEAR PyDateTime_GET_YEAR
67#define GET_MONTH PyDateTime_GET_MONTH
68#define GET_DAY PyDateTime_GET_DAY
69#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
70#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
71#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
72#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040073#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000074
75/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
77 ((o)->data[1] = ((v) & 0x00ff)))
78#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
79#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000080
81/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
83#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
84#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
85#define DATE_SET_MICROSECOND(o, v) \
86 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
87 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
88 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040089#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000090
91/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
93#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
94#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
95#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040096#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
98#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
99#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
100#define TIME_SET_MICROSECOND(o, v) \
101 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
102 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
103 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400104#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000105
106/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
108#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
109#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111#define SET_TD_DAYS(o, v) ((o)->days = (v))
112#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000113#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
114
Tim Petersa032d2e2003-01-11 00:15:54 +0000115/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
116 * p->hastzinfo.
117 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000118#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
119#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
120 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
121#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
122 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000123/* M is a char or int claiming to be a valid month. The macro is equivalent
124 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000126 */
127#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
128
Tim Peters2a799bf2002-12-16 20:18:38 +0000129/* Forward declarations. */
130static PyTypeObject PyDateTime_DateType;
131static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000132static PyTypeObject PyDateTime_DeltaType;
133static PyTypeObject PyDateTime_TimeType;
134static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000135static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000136
Victor Stinnerb67f0962017-02-10 10:34:02 +0100137static int check_tzinfo_subclass(PyObject *p);
138
Martin v. Löwise75fc142013-11-07 18:46:53 +0100139_Py_IDENTIFIER(as_integer_ratio);
140_Py_IDENTIFIER(fromutc);
141_Py_IDENTIFIER(isoformat);
142_Py_IDENTIFIER(strftime);
143
Tim Peters2a799bf2002-12-16 20:18:38 +0000144/* ---------------------------------------------------------------------------
145 * Math utilities.
146 */
147
148/* k = i+j overflows iff k differs in sign from both inputs,
149 * iff k^i has sign bit set and k^j has sign bit set,
150 * iff (k^i)&(k^j) has sign bit set.
151 */
152#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000154
155/* Compute Python divmod(x, y), returning the quotient and storing the
156 * remainder into *r. The quotient is the floor of x/y, and that's
157 * the real point of this. C will probably truncate instead (C99
158 * requires truncation; C89 left it implementation-defined).
159 * Simplification: we *require* that y > 0 here. That's appropriate
160 * for all the uses made of it. This simplifies the code and makes
161 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
162 * overflow case).
163 */
164static int
165divmod(int x, int y, int *r)
166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 assert(y > 0);
170 quo = x / y;
171 *r = x - quo * y;
172 if (*r < 0) {
173 --quo;
174 *r += y;
175 }
176 assert(0 <= *r && *r < y);
177 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000178}
179
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000180/* Nearest integer to m / n for integers m and n. Half-integer results
181 * are rounded to even.
182 */
183static PyObject *
184divide_nearest(PyObject *m, PyObject *n)
185{
186 PyObject *result;
187 PyObject *temp;
188
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000189 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000190 if (temp == NULL)
191 return NULL;
192 result = PyTuple_GET_ITEM(temp, 0);
193 Py_INCREF(result);
194 Py_DECREF(temp);
195
196 return result;
197}
198
Tim Peters2a799bf2002-12-16 20:18:38 +0000199/* ---------------------------------------------------------------------------
200 * General calendrical helper functions
201 */
202
203/* For each month ordinal in 1..12, the number of days in that month,
204 * and the number of days before that month in the same year. These
205 * are correct for non-leap years only.
206 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200207static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 0, /* unused; this vector uses 1-based indexing */
209 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000210};
211
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200212static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 0, /* unused; this vector uses 1-based indexing */
214 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000215};
216
217/* year -> 1 if leap year, else 0. */
218static int
219is_leap(int year)
220{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 /* Cast year to unsigned. The result is the same either way, but
222 * C can generate faster code for unsigned mod than for signed
223 * mod (especially for % 4 -- a good compiler should just grab
224 * the last 2 bits when the LHS is unsigned).
225 */
226 const unsigned int ayear = (unsigned int)year;
227 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000228}
229
230/* year, month -> number of days in that month in that year */
231static int
232days_in_month(int year, int month)
233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 assert(month >= 1);
235 assert(month <= 12);
236 if (month == 2 && is_leap(year))
237 return 29;
238 else
239 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000240}
241
Martin Panter46f50722016-05-26 05:35:26 +0000242/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000243static int
244days_before_month(int year, int month)
245{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 assert(month >= 1);
249 assert(month <= 12);
250 days = _days_before_month[month];
251 if (month > 2 && is_leap(year))
252 ++days;
253 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000254}
255
256/* year -> number of days before January 1st of year. Remember that we
257 * start with year 1, so days_before_year(1) == 0.
258 */
259static int
260days_before_year(int year)
261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 int y = year - 1;
263 /* This is incorrect if year <= 0; we really want the floor
264 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000265 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000267 assert (year >= 1);
268 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000269}
270
271/* Number of days in 4, 100, and 400 year cycles. That these have
272 * the correct values is asserted in the module init function.
273 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274#define DI4Y 1461 /* days_before_year(5); days in 4 years */
275#define DI100Y 36524 /* days_before_year(101); days in 100 years */
276#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000277
278/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
279static void
280ord_to_ymd(int ordinal, int *year, int *month, int *day)
281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
285 * leap years repeats exactly every 400 years. The basic strategy is
286 * to find the closest 400-year boundary at or before ordinal, then
287 * work with the offset from that boundary to ordinal. Life is much
288 * clearer if we subtract 1 from ordinal first -- then the values
289 * of ordinal at 400-year boundaries are exactly those divisible
290 * by DI400Y:
291 *
292 * D M Y n n-1
293 * -- --- ---- ---------- ----------------
294 * 31 Dec -400 -DI400Y -DI400Y -1
295 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
296 * ...
297 * 30 Dec 000 -1 -2
298 * 31 Dec 000 0 -1
299 * 1 Jan 001 1 0 400-year boundary
300 * 2 Jan 001 2 1
301 * 3 Jan 001 3 2
302 * ...
303 * 31 Dec 400 DI400Y DI400Y -1
304 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
305 */
306 assert(ordinal >= 1);
307 --ordinal;
308 n400 = ordinal / DI400Y;
309 n = ordinal % DI400Y;
310 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 /* Now n is the (non-negative) offset, in days, from January 1 of
313 * year, to the desired date. Now compute how many 100-year cycles
314 * precede n.
315 * Note that it's possible for n100 to equal 4! In that case 4 full
316 * 100-year cycles precede the desired day, which implies the
317 * desired day is December 31 at the end of a 400-year cycle.
318 */
319 n100 = n / DI100Y;
320 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 /* Now compute how many 4-year cycles precede it. */
323 n4 = n / DI4Y;
324 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 /* And now how many single years. Again n1 can be 4, and again
327 * meaning that the desired day is December 31 at the end of the
328 * 4-year cycle.
329 */
330 n1 = n / 365;
331 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 *year += n100 * 100 + n4 * 4 + n1;
334 if (n1 == 4 || n100 == 4) {
335 assert(n == 0);
336 *year -= 1;
337 *month = 12;
338 *day = 31;
339 return;
340 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 /* Now the year is correct, and n is the offset from January 1. We
343 * find the month via an estimate that's either exact or one too
344 * large.
345 */
346 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
347 assert(leapyear == is_leap(*year));
348 *month = (n + 50) >> 5;
349 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
350 if (preceding > n) {
351 /* estimate is too large */
352 *month -= 1;
353 preceding -= days_in_month(*year, *month);
354 }
355 n -= preceding;
356 assert(0 <= n);
357 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000360}
361
362/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
363static int
364ymd_to_ord(int year, int month, int day)
365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000367}
368
369/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
370static int
371weekday(int year, int month, int day)
372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000374}
375
376/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
377 * first calendar week containing a Thursday.
378 */
379static int
380iso_week1_monday(int year)
381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
383 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
384 int first_weekday = (first_day + 6) % 7;
385 /* ordinal of closest Monday at or before 1/1 */
386 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
389 week1_monday += 7;
390 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000391}
392
393/* ---------------------------------------------------------------------------
394 * Range checkers.
395 */
396
397/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
398 * If not, raise OverflowError and return -1.
399 */
400static int
401check_delta_day_range(int days)
402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
404 return 0;
405 PyErr_Format(PyExc_OverflowError,
406 "days=%d; must have magnitude <= %d",
407 days, MAX_DELTA_DAYS);
408 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000409}
410
411/* Check that date arguments are in range. Return 0 if they are. If they
412 * aren't, raise ValueError and return -1.
413 */
414static int
415check_date_args(int year, int month, int day)
416{
417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 if (year < MINYEAR || year > MAXYEAR) {
Victor Stinnerb67f0962017-02-10 10:34:02 +0100419 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 return -1;
421 }
422 if (month < 1 || month > 12) {
423 PyErr_SetString(PyExc_ValueError,
424 "month must be in 1..12");
425 return -1;
426 }
427 if (day < 1 || day > days_in_month(year, month)) {
428 PyErr_SetString(PyExc_ValueError,
429 "day is out of range for month");
430 return -1;
431 }
432 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000433}
434
435/* Check that time arguments are in range. Return 0 if they are. If they
436 * aren't, raise ValueError and return -1.
437 */
438static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400439check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000440{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 if (h < 0 || h > 23) {
442 PyErr_SetString(PyExc_ValueError,
443 "hour must be in 0..23");
444 return -1;
445 }
446 if (m < 0 || m > 59) {
447 PyErr_SetString(PyExc_ValueError,
448 "minute must be in 0..59");
449 return -1;
450 }
451 if (s < 0 || s > 59) {
452 PyErr_SetString(PyExc_ValueError,
453 "second must be in 0..59");
454 return -1;
455 }
456 if (us < 0 || us > 999999) {
457 PyErr_SetString(PyExc_ValueError,
458 "microsecond must be in 0..999999");
459 return -1;
460 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400461 if (fold != 0 && fold != 1) {
462 PyErr_SetString(PyExc_ValueError,
463 "fold must be either 0 or 1");
464 return -1;
465 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000467}
468
469/* ---------------------------------------------------------------------------
470 * Normalization utilities.
471 */
472
473/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
474 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
475 * at least factor, enough of *lo is converted into "hi" units so that
476 * 0 <= *lo < factor. The input values must be such that int overflow
477 * is impossible.
478 */
479static void
480normalize_pair(int *hi, int *lo, int factor)
481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 assert(factor > 0);
483 assert(lo != hi);
484 if (*lo < 0 || *lo >= factor) {
485 const int num_hi = divmod(*lo, factor, lo);
486 const int new_hi = *hi + num_hi;
487 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
488 *hi = new_hi;
489 }
490 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000491}
492
493/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 * 0 <= *s < 24*3600
495 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000496 * The input values must be such that the internals don't overflow.
497 * The way this routine is used, we don't get close.
498 */
499static void
500normalize_d_s_us(int *d, int *s, int *us)
501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 if (*us < 0 || *us >= 1000000) {
503 normalize_pair(s, us, 1000000);
504 /* |s| can't be bigger than about
505 * |original s| + |original us|/1000000 now.
506 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
509 if (*s < 0 || *s >= 24*3600) {
510 normalize_pair(d, s, 24*3600);
511 /* |d| can't be bigger than about
512 * |original d| +
513 * (|original s| + |original us|/1000000) / (24*3600) now.
514 */
515 }
516 assert(0 <= *s && *s < 24*3600);
517 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000518}
519
520/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 * 1 <= *m <= 12
522 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000523 * The input values must be such that the internals don't overflow.
524 * The way this routine is used, we don't get close.
525 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000526static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000527normalize_y_m_d(int *y, int *m, int *d)
528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000530
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000531 /* In actual use, m is always the month component extracted from a
532 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 /* Now only day can be out of bounds (year may also be out of bounds
538 * for a datetime object, but we don't care about that here).
539 * If day is out of bounds, what to do is arguable, but at least the
540 * method here is principled and explainable.
541 */
542 dim = days_in_month(*y, *m);
543 if (*d < 1 || *d > dim) {
544 /* Move day-1 days from the first of the month. First try to
545 * get off cheap if we're only one day out of range
546 * (adjustments for timezone alone can't be worse than that).
547 */
548 if (*d == 0) {
549 --*m;
550 if (*m > 0)
551 *d = days_in_month(*y, *m);
552 else {
553 --*y;
554 *m = 12;
555 *d = 31;
556 }
557 }
558 else if (*d == dim + 1) {
559 /* move forward a day */
560 ++*m;
561 *d = 1;
562 if (*m > 12) {
563 *m = 1;
564 ++*y;
565 }
566 }
567 else {
568 int ordinal = ymd_to_ord(*y, *m, 1) +
569 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000570 if (ordinal < 1 || ordinal > MAXORDINAL) {
571 goto error;
572 } else {
573 ord_to_ymd(ordinal, y, m, d);
574 return 0;
575 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 }
577 }
578 assert(*m > 0);
579 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000580 if (MINYEAR <= *y && *y <= MAXYEAR)
581 return 0;
582 error:
583 PyErr_SetString(PyExc_OverflowError,
584 "date value out of range");
585 return -1;
586
Tim Peters2a799bf2002-12-16 20:18:38 +0000587}
588
589/* Fiddle out-of-bounds months and days so that the result makes some kind
590 * of sense. The parameters are both inputs and outputs. Returns < 0 on
591 * failure, where failure means the adjusted year is out of bounds.
592 */
593static int
594normalize_date(int *year, int *month, int *day)
595{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000596 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000597}
598
599/* Force all the datetime fields into range. The parameters are both
600 * inputs and outputs. Returns < 0 on error.
601 */
602static int
603normalize_datetime(int *year, int *month, int *day,
604 int *hour, int *minute, int *second,
605 int *microsecond)
606{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 normalize_pair(second, microsecond, 1000000);
608 normalize_pair(minute, second, 60);
609 normalize_pair(hour, minute, 60);
610 normalize_pair(day, hour, 24);
611 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000612}
613
614/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000615 * Basic object allocation: tp_alloc implementations. These allocate
616 * Python objects of the right size and type, and do the Python object-
617 * initialization bit. If there's not enough memory, they return NULL after
618 * setting MemoryError. All data members remain uninitialized trash.
619 *
620 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000621 * member is needed. This is ugly, imprecise, and possibly insecure.
622 * tp_basicsize for the time and datetime types is set to the size of the
623 * struct that has room for the tzinfo member, so subclasses in Python will
624 * allocate enough space for a tzinfo member whether or not one is actually
625 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
626 * part is that PyType_GenericAlloc() (which subclasses in Python end up
627 * using) just happens today to effectively ignore the nitems argument
628 * when tp_itemsize is 0, which it is for these type objects. If that
629 * changes, perhaps the callers of tp_alloc slots in this file should
630 * be changed to force a 0 nitems argument unless the type being allocated
631 * is a base type implemented in this file (so that tp_alloc is time_alloc
632 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000633 */
634
635static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000636time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 self = (PyObject *)
641 PyObject_MALLOC(aware ?
642 sizeof(PyDateTime_Time) :
643 sizeof(_PyDateTime_BaseTime));
644 if (self == NULL)
645 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100646 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000648}
649
650static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000651datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000652{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 self = (PyObject *)
656 PyObject_MALLOC(aware ?
657 sizeof(PyDateTime_DateTime) :
658 sizeof(_PyDateTime_BaseDateTime));
659 if (self == NULL)
660 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100661 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000663}
664
665/* ---------------------------------------------------------------------------
666 * Helpers for setting object fields. These work on pointers to the
667 * appropriate base class.
668 */
669
670/* For date and datetime. */
671static void
672set_date_fields(PyDateTime_Date *self, int y, int m, int d)
673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 self->hashcode = -1;
675 SET_YEAR(self, y);
676 SET_MONTH(self, m);
677 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000678}
679
680/* ---------------------------------------------------------------------------
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500681 * String parsing utilities and helper functions
682 */
683
Paul Ganssle3df85402018-10-22 12:32:52 -0400684static const char *
685parse_digits(const char *ptr, int *var, size_t num_digits)
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500686{
687 for (size_t i = 0; i < num_digits; ++i) {
688 unsigned int tmp = (unsigned int)(*(ptr++) - '0');
689 if (tmp > 9) {
690 return NULL;
691 }
692 *var *= 10;
693 *var += (signed int)tmp;
694 }
695
696 return ptr;
697}
698
Paul Ganssle3df85402018-10-22 12:32:52 -0400699static int
700parse_isoformat_date(const char *dtstr, int *year, int *month, int *day)
701{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500702 /* Parse the date components of the result of date.isoformat()
Paul Ganssle3df85402018-10-22 12:32:52 -0400703 *
704 * Return codes:
705 * 0: Success
706 * -1: Failed to parse date component
707 * -2: Failed to parse dateseparator
708 */
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500709 const char *p = dtstr;
710 p = parse_digits(p, year, 4);
711 if (NULL == p) {
712 return -1;
713 }
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100714
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500715 if (*(p++) != '-') {
716 return -2;
717 }
718
719 p = parse_digits(p, month, 2);
720 if (NULL == p) {
721 return -1;
722 }
723
724 if (*(p++) != '-') {
725 return -2;
726 }
727
728 p = parse_digits(p, day, 2);
729 if (p == NULL) {
730 return -1;
731 }
732
733 return 0;
734}
735
736static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400737parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
738 int *minute, int *second, int *microsecond)
739{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500740 const char *p = tstr;
741 const char *p_end = tstr_end;
742 int *vals[3] = {hour, minute, second};
743
744 // Parse [HH[:MM[:SS]]]
745 for (size_t i = 0; i < 3; ++i) {
746 p = parse_digits(p, vals[i], 2);
747 if (NULL == p) {
748 return -3;
749 }
750
751 char c = *(p++);
752 if (p >= p_end) {
753 return c != '\0';
Paul Ganssle3df85402018-10-22 12:32:52 -0400754 }
755 else if (c == ':') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500756 continue;
Paul Ganssle3df85402018-10-22 12:32:52 -0400757 }
758 else if (c == '.') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500759 break;
Paul Ganssle3df85402018-10-22 12:32:52 -0400760 }
761 else {
762 return -4; // Malformed time separator
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500763 }
764 }
765
766 // Parse .fff[fff]
767 size_t len_remains = p_end - p;
768 if (!(len_remains == 6 || len_remains == 3)) {
769 return -3;
770 }
771
772 p = parse_digits(p, microsecond, len_remains);
773 if (NULL == p) {
774 return -3;
775 }
776
777 if (len_remains == 3) {
778 *microsecond *= 1000;
779 }
780
781 // Return 1 if it's not the end of the string
782 return *p != '\0';
783}
784
785static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400786parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
787 int *second, int *microsecond, int *tzoffset,
788 int *tzmicrosecond)
789{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500790 // Parse the time portion of a datetime.isoformat() string
791 //
792 // Return codes:
793 // 0: Success (no tzoffset)
794 // 1: Success (with tzoffset)
795 // -3: Failed to parse time component
796 // -4: Failed to parse time separator
797 // -5: Malformed timezone string
798
799 const char *p = dtstr;
800 const char *p_end = dtstr + dtlen;
801
802 const char *tzinfo_pos = p;
803 do {
804 if (*tzinfo_pos == '+' || *tzinfo_pos == '-') {
805 break;
806 }
Paul Ganssle3df85402018-10-22 12:32:52 -0400807 } while (++tzinfo_pos < p_end);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500808
Paul Ganssle3df85402018-10-22 12:32:52 -0400809 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second,
810 microsecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500811
812 if (rv < 0) {
813 return rv;
Paul Ganssle3df85402018-10-22 12:32:52 -0400814 }
815 else if (tzinfo_pos == p_end) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500816 // We know that there's no time zone, so if there's stuff at the
817 // end of the string it's an error.
818 if (rv == 1) {
819 return -5;
Paul Ganssle3df85402018-10-22 12:32:52 -0400820 }
821 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500822 return 0;
823 }
824 }
825
826 // Parse time zone component
827 // Valid formats are:
828 // - +HH:MM (len 6)
829 // - +HH:MM:SS (len 9)
830 // - +HH:MM:SS.ffffff (len 16)
831 size_t tzlen = p_end - tzinfo_pos;
832 if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) {
833 return -5;
834 }
835
Paul Ganssle3df85402018-10-22 12:32:52 -0400836 int tzsign = (*tzinfo_pos == '-') ? -1 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500837 tzinfo_pos++;
838 int tzhour = 0, tzminute = 0, tzsecond = 0;
Paul Ganssle3df85402018-10-22 12:32:52 -0400839 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond,
840 tzmicrosecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500841
842 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
843 *tzmicrosecond *= tzsign;
844
Paul Ganssle3df85402018-10-22 12:32:52 -0400845 return rv ? -5 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500846}
847
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500848/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000849 * Create various objects, mostly without range checking.
850 */
851
852/* Create a date instance with no range checking. */
853static PyObject *
854new_date_ex(int year, int month, int day, PyTypeObject *type)
855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000857
Victor Stinnerb67f0962017-02-10 10:34:02 +0100858 if (check_date_args(year, month, day) < 0) {
859 return NULL;
860 }
861
Paul Ganssle3df85402018-10-22 12:32:52 -0400862 self = (PyDateTime_Date *)(type->tp_alloc(type, 0));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 if (self != NULL)
864 set_date_fields(self, year, month, day);
Paul Ganssle3df85402018-10-22 12:32:52 -0400865 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000866}
867
868#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000870
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500871// Forward declaration
Paul Ganssle3df85402018-10-22 12:32:52 -0400872static PyObject *
873new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500874
875/* Create date instance with no range checking, or call subclass constructor */
876static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -0400877new_date_subclass_ex(int year, int month, int day, PyObject *cls)
878{
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500879 PyObject *result;
880 // We have "fast path" constructors for two subclasses: date and datetime
881 if ((PyTypeObject *)cls == &PyDateTime_DateType) {
882 result = new_date_ex(year, month, day, (PyTypeObject *)cls);
Paul Ganssle3df85402018-10-22 12:32:52 -0400883 }
884 else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500885 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
886 (PyTypeObject *)cls);
Paul Ganssle3df85402018-10-22 12:32:52 -0400887 }
888 else {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500889 result = PyObject_CallFunction(cls, "iii", year, month, day);
890 }
891
892 return result;
893}
894
Tim Petersb0c854d2003-05-17 15:57:00 +0000895/* Create a datetime instance with no range checking. */
896static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400897new_datetime_ex2(int year, int month, int day, int hour, int minute,
898 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 PyDateTime_DateTime *self;
901 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000902
Victor Stinnerb67f0962017-02-10 10:34:02 +0100903 if (check_date_args(year, month, day) < 0) {
904 return NULL;
905 }
906 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
907 return NULL;
908 }
909 if (check_tzinfo_subclass(tzinfo) < 0) {
910 return NULL;
911 }
912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
914 if (self != NULL) {
915 self->hastzinfo = aware;
916 set_date_fields((PyDateTime_Date *)self, year, month, day);
917 DATE_SET_HOUR(self, hour);
918 DATE_SET_MINUTE(self, minute);
919 DATE_SET_SECOND(self, second);
920 DATE_SET_MICROSECOND(self, usecond);
921 if (aware) {
922 Py_INCREF(tzinfo);
923 self->tzinfo = tzinfo;
924 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400925 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 }
927 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000928}
929
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400930static PyObject *
931new_datetime_ex(int year, int month, int day, int hour, int minute,
932 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
933{
934 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
935 tzinfo, 0, type);
936}
937
938#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
939 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000941
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500942static PyObject *
943new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
944 int second, int usecond, PyObject *tzinfo,
945 int fold, PyObject *cls) {
946 PyObject* dt;
947 if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) {
948 // Use the fast path constructor
949 dt = new_datetime(year, month, day, hour, minute, second, usecond,
950 tzinfo, fold);
951 } else {
952 // Subclass
953 dt = PyObject_CallFunction(cls, "iiiiiiiO",
954 year,
955 month,
956 day,
957 hour,
958 minute,
959 second,
960 usecond,
961 tzinfo);
962 }
963
964 return dt;
965}
966
967static PyObject *
968new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
969 int second, int usecond, PyObject *tzinfo,
970 PyObject *cls) {
971 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
972 second, usecond, tzinfo, 0,
973 cls);
974}
975
Tim Petersb0c854d2003-05-17 15:57:00 +0000976/* Create a time instance with no range checking. */
977static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400978new_time_ex2(int hour, int minute, int second, int usecond,
979 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 PyDateTime_Time *self;
982 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000983
Victor Stinnerb67f0962017-02-10 10:34:02 +0100984 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
985 return NULL;
986 }
987 if (check_tzinfo_subclass(tzinfo) < 0) {
988 return NULL;
989 }
990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
992 if (self != NULL) {
993 self->hastzinfo = aware;
994 self->hashcode = -1;
995 TIME_SET_HOUR(self, hour);
996 TIME_SET_MINUTE(self, minute);
997 TIME_SET_SECOND(self, second);
998 TIME_SET_MICROSECOND(self, usecond);
999 if (aware) {
1000 Py_INCREF(tzinfo);
1001 self->tzinfo = tzinfo;
1002 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001003 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 }
1005 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001006}
1007
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001008static PyObject *
1009new_time_ex(int hour, int minute, int second, int usecond,
1010 PyObject *tzinfo, PyTypeObject *type)
1011{
1012 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
1013}
1014
1015#define new_time(hh, mm, ss, us, tzinfo, fold) \
1016 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001017
1018/* Create a timedelta instance. Normalize the members iff normalize is
1019 * true. Passing false is a speed optimization, if you know for sure
1020 * that seconds and microseconds are already in their proper ranges. In any
1021 * case, raises OverflowError and returns NULL if the normalized days is out
1022 * of range).
1023 */
1024static PyObject *
1025new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +00001027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 if (normalize)
1031 normalize_d_s_us(&days, &seconds, &microseconds);
1032 assert(0 <= seconds && seconds < 24*3600);
1033 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +00001034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 if (check_delta_day_range(days) < 0)
1036 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +00001037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1039 if (self != NULL) {
1040 self->hashcode = -1;
1041 SET_TD_DAYS(self, days);
1042 SET_TD_SECONDS(self, seconds);
1043 SET_TD_MICROSECONDS(self, microseconds);
1044 }
1045 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001046}
1047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048#define new_delta(d, s, us, normalize) \
1049 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001050
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001051
1052typedef struct
1053{
1054 PyObject_HEAD
1055 PyObject *offset;
1056 PyObject *name;
1057} PyDateTime_TimeZone;
1058
Victor Stinner6ced7c42011-03-21 18:15:42 +01001059/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001060static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -04001061/* The interned Epoch datetime instance */
1062static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00001063
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001064/* Create new timezone instance checking offset range. This
1065 function does not check the name argument. Caller must assure
1066 that offset is a timedelta instance and name is either NULL
1067 or a unicode object. */
1068static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001069create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001070{
1071 PyDateTime_TimeZone *self;
1072 PyTypeObject *type = &PyDateTime_TimeZoneType;
1073
1074 assert(offset != NULL);
1075 assert(PyDelta_Check(offset));
1076 assert(name == NULL || PyUnicode_Check(name));
1077
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001078 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1079 if (self == NULL) {
1080 return NULL;
1081 }
1082 Py_INCREF(offset);
1083 self->offset = offset;
1084 Py_XINCREF(name);
1085 self->name = name;
1086 return (PyObject *)self;
1087}
1088
1089static int delta_bool(PyDateTime_Delta *self);
1090
1091static PyObject *
1092new_timezone(PyObject *offset, PyObject *name)
1093{
1094 assert(offset != NULL);
1095 assert(PyDelta_Check(offset));
1096 assert(name == NULL || PyUnicode_Check(name));
1097
1098 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
1099 Py_INCREF(PyDateTime_TimeZone_UTC);
1100 return PyDateTime_TimeZone_UTC;
1101 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001102 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1103 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1104 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1105 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04001106 " timedelta(hours=24),"
1107 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001108 return NULL;
1109 }
1110
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001111 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001112}
1113
Tim Petersb0c854d2003-05-17 15:57:00 +00001114/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001115 * tzinfo helpers.
1116 */
1117
Tim Peters855fe882002-12-22 03:43:39 +00001118/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
1119 * raise TypeError and return -1.
1120 */
1121static int
1122check_tzinfo_subclass(PyObject *p)
1123{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 if (p == Py_None || PyTZInfo_Check(p))
1125 return 0;
1126 PyErr_Format(PyExc_TypeError,
1127 "tzinfo argument must be None or of a tzinfo subclass, "
1128 "not type '%s'",
1129 Py_TYPE(p)->tp_name);
1130 return -1;
Tim Peters855fe882002-12-22 03:43:39 +00001131}
1132
Tim Peters2a799bf2002-12-16 20:18:38 +00001133/* If self has a tzinfo member, return a BORROWED reference to it. Else
1134 * return NULL, which is NOT AN ERROR. There are no error returns here,
1135 * and the caller must not decref the result.
1136 */
1137static PyObject *
1138get_tzinfo_member(PyObject *self)
1139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 if (PyDateTime_Check(self) && HASTZINFO(self))
1143 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1144 else if (PyTime_Check(self) && HASTZINFO(self))
1145 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001148}
1149
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001150/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
1151 * be an instance of the tzinfo class. If the method returns None, this
1152 * returns None. If the method doesn't return None or timedelta, TypeError is
1153 * raised and this returns NULL. If it returns a timedelta and the value is
1154 * out of range or isn't a whole number of minutes, ValueError is raised and
1155 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +00001156 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001157static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001158call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001159{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001160 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001163 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001165
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001166 if (tzinfo == Py_None)
1167 Py_RETURN_NONE;
1168 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1169 if (offset == Py_None || offset == NULL)
1170 return offset;
1171 if (PyDelta_Check(offset)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001172 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1173 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1174 Py_DECREF(offset);
1175 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1176 " strictly between -timedelta(hours=24) and"
1177 " timedelta(hours=24).");
1178 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 }
1180 }
1181 else {
1182 PyErr_Format(PyExc_TypeError,
1183 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001184 "timedelta, not '%.200s'",
1185 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07001186 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001187 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001189
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001190 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001191}
1192
1193/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1194 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
1195 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +00001196 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001197 * If utcoffset() returns an out of range timedelta,
1198 * ValueError is raised and this returns -1. Else *none is
1199 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001200 */
Tim Peters855fe882002-12-22 03:43:39 +00001201static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001202call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1203{
1204 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001205}
1206
Tim Peters2a799bf2002-12-16 20:18:38 +00001207/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1208 * result. tzinfo must be an instance of the tzinfo class. If dst()
1209 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001210 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00001211 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +00001212 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001213 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001214 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001215static PyObject *
1216call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001217{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001218 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001219}
1220
Tim Petersbad8ff02002-12-30 20:52:32 +00001221/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +00001222 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001223 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001224 * returns NULL. If the result is a string, we ensure it is a Unicode
1225 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001226 */
1227static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001228call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001231 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 assert(tzinfo != NULL);
1234 assert(check_tzinfo_subclass(tzinfo) >= 0);
1235 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001238 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001239
Victor Stinner20401de2016-12-09 15:24:31 +01001240 result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname,
1241 tzinfoarg, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001242
1243 if (result == NULL || result == Py_None)
1244 return result;
1245
1246 if (!PyUnicode_Check(result)) {
1247 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1248 "return None or a string, not '%s'",
1249 Py_TYPE(result)->tp_name);
1250 Py_DECREF(result);
1251 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001253
1254 return result;
Tim Peters00237032002-12-27 02:21:51 +00001255}
1256
Tim Peters2a799bf2002-12-16 20:18:38 +00001257/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1258 * stuff
1259 * ", tzinfo=" + repr(tzinfo)
1260 * before the closing ")".
1261 */
1262static PyObject *
1263append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 assert(PyUnicode_Check(repr));
1268 assert(tzinfo);
1269 if (tzinfo == Py_None)
1270 return repr;
1271 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001272 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1273 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 Py_DECREF(repr);
1275 if (temp == NULL)
1276 return NULL;
1277 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1278 Py_DECREF(temp);
1279 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001280}
1281
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001282/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1283 * stuff
1284 * ", fold=" + repr(tzinfo)
1285 * before the closing ")".
1286 */
1287static PyObject *
1288append_keyword_fold(PyObject *repr, int fold)
1289{
1290 PyObject *temp;
1291
1292 assert(PyUnicode_Check(repr));
1293 if (fold == 0)
1294 return repr;
1295 /* Get rid of the trailing ')'. */
1296 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1297 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1298 Py_DECREF(repr);
1299 if (temp == NULL)
1300 return NULL;
1301 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1302 Py_DECREF(temp);
1303 return repr;
1304}
1305
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001306static inline PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04001307tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
1308{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001309 PyObject *tzinfo;
1310 if (rv == 1) {
1311 // Create a timezone from offset in seconds (0 returns UTC)
1312 if (tzoffset == 0) {
1313 Py_INCREF(PyDateTime_TimeZone_UTC);
1314 return PyDateTime_TimeZone_UTC;
1315 }
1316
1317 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001318 if (delta == NULL) {
1319 return NULL;
1320 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001321 tzinfo = new_timezone(delta, NULL);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001322 Py_DECREF(delta);
Paul Ganssle3df85402018-10-22 12:32:52 -04001323 }
1324 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001325 tzinfo = Py_None;
1326 Py_INCREF(Py_None);
1327 }
1328
1329 return tzinfo;
1330}
1331
Tim Peters2a799bf2002-12-16 20:18:38 +00001332/* ---------------------------------------------------------------------------
1333 * String format helpers.
1334 */
1335
1336static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001337format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001338{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001339 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1341 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001342 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1344 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1345 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1350 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1351 GET_DAY(date), hours, minutes, seconds,
1352 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001353}
1354
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001355static PyObject *delta_negative(PyDateTime_Delta *self);
1356
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001357/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001358 * buflen bytes remaining. The UTC offset is gotten by calling
1359 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1360 * *buf, and that's all. Else the returned value is checked for sanity (an
1361 * integer in range), and if that's OK it's converted to an hours & minutes
1362 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001363 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001364 * Returns 0 if everything is OK. If the return value from utcoffset() is
1365 * bogus, an appropriate exception is set and -1 is returned.
1366 */
1367static int
Tim Peters328fff72002-12-20 01:31:27 +00001368format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001370{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001371 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001372 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001376
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001377 offset = call_utcoffset(tzinfo, tzinfoarg);
1378 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001380 if (offset == Py_None) {
1381 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 *buf = '\0';
1383 return 0;
1384 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001385 /* Offset is normalized, so it is negative if days < 0 */
1386 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001388 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001389 if (offset == NULL)
1390 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001392 else {
1393 sign = '+';
1394 }
1395 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001396 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001397 seconds = GET_TD_SECONDS(offset);
1398 Py_DECREF(offset);
1399 minutes = divmod(seconds, 60, &seconds);
1400 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001401 if (microseconds) {
1402 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1403 hours, sep, minutes, sep, seconds, microseconds);
1404 return 0;
1405 }
1406 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001407 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1408 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001409 return 0;
1410 }
1411 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001413}
1414
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001415static PyObject *
1416make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 PyObject *temp;
1419 PyObject *tzinfo = get_tzinfo_member(object);
1420 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001421 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 if (Zreplacement == NULL)
1424 return NULL;
1425 if (tzinfo == Py_None || tzinfo == NULL)
1426 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 assert(tzinfoarg != NULL);
1429 temp = call_tzname(tzinfo, tzinfoarg);
1430 if (temp == NULL)
1431 goto Error;
1432 if (temp == Py_None) {
1433 Py_DECREF(temp);
1434 return Zreplacement;
1435 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 assert(PyUnicode_Check(temp));
1438 /* Since the tzname is getting stuffed into the
1439 * format, we have to double any % signs so that
1440 * strftime doesn't treat them as format codes.
1441 */
1442 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001443 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 Py_DECREF(temp);
1445 if (Zreplacement == NULL)
1446 return NULL;
1447 if (!PyUnicode_Check(Zreplacement)) {
1448 PyErr_SetString(PyExc_TypeError,
1449 "tzname.replace() did not return a string");
1450 goto Error;
1451 }
1452 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001453
1454 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 Py_DECREF(Zreplacement);
1456 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001457}
1458
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001459static PyObject *
1460make_freplacement(PyObject *object)
1461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 char freplacement[64];
1463 if (PyTime_Check(object))
1464 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1465 else if (PyDateTime_Check(object))
1466 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1467 else
1468 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001471}
1472
Tim Peters2a799bf2002-12-16 20:18:38 +00001473/* I sure don't want to reproduce the strftime code from the time module,
1474 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001475 * giving special meanings to the %z, %Z and %f format codes via a
1476 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001477 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1478 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001479 */
1480static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001481wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1487 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1488 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 const char *pin; /* pointer to next char in input format */
1491 Py_ssize_t flen; /* length of input format */
1492 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 PyObject *newfmt = NULL; /* py string, the output format */
1495 char *pnew; /* pointer to available byte in output format */
1496 size_t totalnew; /* number bytes total in output format buffer,
1497 exclusive of trailing \0 */
1498 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 const char *ptoappend; /* ptr to string to append to output buffer */
1501 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 assert(object && format && timetuple);
1504 assert(PyUnicode_Check(format));
1505 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001506 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 if (!pin)
1508 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 /* Scan the input format, looking for %z/%Z/%f escapes, building
1511 * a new format. Since computing the replacements for those codes
1512 * is expensive, don't unless they're actually used.
1513 */
1514 if (flen > INT_MAX - 1) {
1515 PyErr_NoMemory();
1516 goto Done;
1517 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 totalnew = flen + 1; /* realistic if no %z/%Z */
1520 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1521 if (newfmt == NULL) goto Done;
1522 pnew = PyBytes_AsString(newfmt);
1523 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 while ((ch = *pin++) != '\0') {
1526 if (ch != '%') {
1527 ptoappend = pin - 1;
1528 ntoappend = 1;
1529 }
1530 else if ((ch = *pin++) == '\0') {
MichaelSaah454b3d42019-01-14 05:23:39 -05001531 /* Null byte follows %, copy only '%'.
1532 *
1533 * Back the pin up one char so that we catch the null check
1534 * the next time through the loop.*/
1535 pin--;
1536 ptoappend = pin - 1;
1537 ntoappend = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 }
1539 /* A % has been seen and ch is the character after it. */
1540 else if (ch == 'z') {
1541 if (zreplacement == NULL) {
1542 /* format utcoffset */
1543 char buf[100];
1544 PyObject *tzinfo = get_tzinfo_member(object);
1545 zreplacement = PyBytes_FromStringAndSize("", 0);
1546 if (zreplacement == NULL) goto Done;
1547 if (tzinfo != Py_None && tzinfo != NULL) {
1548 assert(tzinfoarg != NULL);
1549 if (format_utcoffset(buf,
1550 sizeof(buf),
1551 "",
1552 tzinfo,
1553 tzinfoarg) < 0)
1554 goto Done;
1555 Py_DECREF(zreplacement);
1556 zreplacement =
1557 PyBytes_FromStringAndSize(buf,
1558 strlen(buf));
1559 if (zreplacement == NULL)
1560 goto Done;
1561 }
1562 }
1563 assert(zreplacement != NULL);
1564 ptoappend = PyBytes_AS_STRING(zreplacement);
1565 ntoappend = PyBytes_GET_SIZE(zreplacement);
1566 }
1567 else if (ch == 'Z') {
1568 /* format tzname */
1569 if (Zreplacement == NULL) {
1570 Zreplacement = make_Zreplacement(object,
1571 tzinfoarg);
1572 if (Zreplacement == NULL)
1573 goto Done;
1574 }
1575 assert(Zreplacement != NULL);
1576 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001577 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001579 if (ptoappend == NULL)
1580 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 }
1582 else if (ch == 'f') {
1583 /* format microseconds */
1584 if (freplacement == NULL) {
1585 freplacement = make_freplacement(object);
1586 if (freplacement == NULL)
1587 goto Done;
1588 }
1589 assert(freplacement != NULL);
1590 assert(PyBytes_Check(freplacement));
1591 ptoappend = PyBytes_AS_STRING(freplacement);
1592 ntoappend = PyBytes_GET_SIZE(freplacement);
1593 }
1594 else {
1595 /* percent followed by neither z nor Z */
1596 ptoappend = pin - 2;
1597 ntoappend = 2;
1598 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 /* Append the ntoappend chars starting at ptoappend to
1601 * the new format.
1602 */
1603 if (ntoappend == 0)
1604 continue;
1605 assert(ptoappend != NULL);
1606 assert(ntoappend > 0);
1607 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001608 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 PyErr_NoMemory();
1610 goto Done;
1611 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001612 totalnew <<= 1;
1613 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 pnew = PyBytes_AsString(newfmt) + usednew;
1616 }
1617 memcpy(pnew, ptoappend, ntoappend);
1618 pnew += ntoappend;
1619 usednew += ntoappend;
1620 assert(usednew <= totalnew);
1621 } /* end while() */
MichaelSaah454b3d42019-01-14 05:23:39 -05001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1624 goto Done;
1625 {
1626 PyObject *format;
1627 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 if (time == NULL)
1630 goto Done;
1631 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1632 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001633 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1634 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 Py_DECREF(format);
1636 }
1637 Py_DECREF(time);
1638 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001639 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 Py_XDECREF(freplacement);
1641 Py_XDECREF(zreplacement);
1642 Py_XDECREF(Zreplacement);
1643 Py_XDECREF(newfmt);
1644 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001645}
1646
Tim Peters2a799bf2002-12-16 20:18:38 +00001647/* ---------------------------------------------------------------------------
1648 * Wrap functions from the time module. These aren't directly available
1649 * from C. Perhaps they should be.
1650 */
1651
1652/* Call time.time() and return its result (a Python float). */
1653static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001654time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 PyObject *result = NULL;
1657 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001660 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001661
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001662 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 Py_DECREF(time);
1664 }
1665 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001666}
1667
1668/* Build a time.struct_time. The weekday and day number are automatically
1669 * computed from the y,m,d args.
1670 */
1671static PyObject *
1672build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001675 PyObject *result;
1676 _Py_IDENTIFIER(struct_time);
1677 PyObject *args;
1678
Tim Peters2a799bf2002-12-16 20:18:38 +00001679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001681 if (time == NULL) {
1682 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 }
Victor Stinner2b635972016-12-09 00:38:16 +01001684
1685 args = Py_BuildValue("iiiiiiiii",
1686 y, m, d,
1687 hh, mm, ss,
1688 weekday(y, m, d),
1689 days_before_month(y, m) + d,
1690 dstflag);
1691 if (args == NULL) {
1692 Py_DECREF(time);
1693 return NULL;
1694 }
1695
1696 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1697 args, NULL);
1698 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001699 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001701}
1702
1703/* ---------------------------------------------------------------------------
1704 * Miscellaneous helpers.
1705 */
1706
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001707/* The comparisons here all most naturally compute a cmp()-like result.
Tim Peters2a799bf2002-12-16 20:18:38 +00001708 * This little helper turns that into a bool result for rich comparisons.
1709 */
1710static PyObject *
1711diff_to_bool(int diff, int op)
1712{
stratakise8b19652017-11-02 11:32:54 +01001713 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001714}
1715
Tim Peters07534a62003-02-07 22:50:28 +00001716/* Raises a "can't compare" TypeError and returns NULL. */
1717static PyObject *
1718cmperror(PyObject *a, PyObject *b)
1719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 PyErr_Format(PyExc_TypeError,
1721 "can't compare %s to %s",
1722 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1723 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001724}
1725
Tim Peters2a799bf2002-12-16 20:18:38 +00001726/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001727 * Cached Python objects; these are set by the module init function.
1728 */
1729
1730/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731static PyObject *us_per_ms = NULL; /* 1000 */
1732static PyObject *us_per_second = NULL; /* 1000000 */
1733static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001734static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1735static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1736static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001737static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1738
Tim Peters2a799bf2002-12-16 20:18:38 +00001739/* ---------------------------------------------------------------------------
1740 * Class implementations.
1741 */
1742
1743/*
1744 * PyDateTime_Delta implementation.
1745 */
1746
1747/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001749 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001750 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1751 * due to ubiquitous overflow possibilities.
1752 */
1753static PyObject *
1754delta_to_microseconds(PyDateTime_Delta *self)
1755{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 PyObject *x1 = NULL;
1757 PyObject *x2 = NULL;
1758 PyObject *x3 = NULL;
1759 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1762 if (x1 == NULL)
1763 goto Done;
1764 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1765 if (x2 == NULL)
1766 goto Done;
1767 Py_DECREF(x1);
1768 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 /* x2 has days in seconds */
1771 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1772 if (x1 == NULL)
1773 goto Done;
1774 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1775 if (x3 == NULL)
1776 goto Done;
1777 Py_DECREF(x1);
1778 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001779 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 /* x3 has days+seconds in seconds */
1782 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1783 if (x1 == NULL)
1784 goto Done;
1785 Py_DECREF(x3);
1786 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 /* x1 has days+seconds in us */
1789 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1790 if (x2 == NULL)
1791 goto Done;
1792 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001793 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001794
1795Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 Py_XDECREF(x1);
1797 Py_XDECREF(x2);
1798 Py_XDECREF(x3);
1799 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001800}
1801
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001802static PyObject *
1803checked_divmod(PyObject *a, PyObject *b)
1804{
1805 PyObject *result = PyNumber_Divmod(a, b);
1806 if (result != NULL) {
1807 if (!PyTuple_Check(result)) {
1808 PyErr_Format(PyExc_TypeError,
1809 "divmod() returned non-tuple (type %.200s)",
1810 result->ob_type->tp_name);
1811 Py_DECREF(result);
1812 return NULL;
1813 }
1814 if (PyTuple_GET_SIZE(result) != 2) {
1815 PyErr_Format(PyExc_TypeError,
1816 "divmod() returned a tuple of size %zd",
1817 PyTuple_GET_SIZE(result));
1818 Py_DECREF(result);
1819 return NULL;
1820 }
1821 }
1822 return result;
1823}
1824
Serhiy Storchaka95949422013-08-27 19:40:23 +03001825/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001826 */
1827static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001828microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 int us;
1831 int s;
1832 int d;
Tim Peters2a799bf2002-12-16 20:18:38 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 PyObject *tuple = NULL;
1835 PyObject *num = NULL;
1836 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001837
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001838 tuple = checked_divmod(pyus, us_per_second);
1839 if (tuple == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 goto Done;
1841 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001842
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001843 num = PyTuple_GET_ITEM(tuple, 1); /* us */
1844 us = _PyLong_AsInt(num);
1845 num = NULL;
1846 if (us == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 goto Done;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001848 }
1849 if (!(0 <= us && us < 1000000)) {
1850 goto BadDivmod;
1851 }
1852
1853 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 Py_INCREF(num);
1855 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001856
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001857 tuple = checked_divmod(num, seconds_per_day);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 if (tuple == NULL)
1859 goto Done;
1860 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001861
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001862 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */
1863 s = _PyLong_AsInt(num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 num = NULL;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001865 if (s == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 goto Done;
1867 }
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001868 if (!(0 <= s && s < 24*3600)) {
1869 goto BadDivmod;
1870 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001871
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001872 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 Py_INCREF(num);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001874 d = _PyLong_AsInt(num);
1875 if (d == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 goto Done;
1877 }
1878 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001879
1880Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 Py_XDECREF(tuple);
1882 Py_XDECREF(num);
1883 return result;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001884
1885BadDivmod:
1886 PyErr_SetString(PyExc_TypeError,
1887 "divmod() returned a value out of range");
1888 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001889}
1890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891#define microseconds_to_delta(pymicros) \
1892 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001893
Tim Peters2a799bf2002-12-16 20:18:38 +00001894static PyObject *
1895multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 PyObject *pyus_in;
1898 PyObject *pyus_out;
1899 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 pyus_in = delta_to_microseconds(delta);
1902 if (pyus_in == NULL)
1903 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001904
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001905 pyus_out = PyNumber_Multiply(intobj, pyus_in);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 Py_DECREF(pyus_in);
1907 if (pyus_out == NULL)
1908 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 result = microseconds_to_delta(pyus_out);
1911 Py_DECREF(pyus_out);
1912 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001913}
1914
1915static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001916get_float_as_integer_ratio(PyObject *floatobj)
1917{
1918 PyObject *ratio;
1919
1920 assert(floatobj && PyFloat_Check(floatobj));
1921 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1922 if (ratio == NULL) {
1923 return NULL;
1924 }
1925 if (!PyTuple_Check(ratio)) {
1926 PyErr_Format(PyExc_TypeError,
1927 "unexpected return type from as_integer_ratio(): "
1928 "expected tuple, got '%.200s'",
1929 Py_TYPE(ratio)->tp_name);
1930 Py_DECREF(ratio);
1931 return NULL;
1932 }
1933 if (PyTuple_Size(ratio) != 2) {
1934 PyErr_SetString(PyExc_ValueError,
1935 "as_integer_ratio() must return a 2-tuple");
1936 Py_DECREF(ratio);
1937 return NULL;
1938 }
1939 return ratio;
1940}
1941
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001942/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001943static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001944multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001945{
1946 PyObject *result = NULL;
1947 PyObject *pyus_in = NULL, *temp, *pyus_out;
1948 PyObject *ratio = NULL;
1949
1950 pyus_in = delta_to_microseconds(delta);
1951 if (pyus_in == NULL)
1952 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001953 ratio = get_float_as_integer_ratio(floatobj);
1954 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001955 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001956 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001957 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001958 Py_DECREF(pyus_in);
1959 pyus_in = NULL;
1960 if (temp == NULL)
1961 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001962 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001963 Py_DECREF(temp);
1964 if (pyus_out == NULL)
1965 goto error;
1966 result = microseconds_to_delta(pyus_out);
1967 Py_DECREF(pyus_out);
1968 error:
1969 Py_XDECREF(pyus_in);
1970 Py_XDECREF(ratio);
1971
1972 return result;
1973}
1974
1975static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001976divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 PyObject *pyus_in;
1979 PyObject *pyus_out;
1980 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 pyus_in = delta_to_microseconds(delta);
1983 if (pyus_in == NULL)
1984 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1987 Py_DECREF(pyus_in);
1988 if (pyus_out == NULL)
1989 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 result = microseconds_to_delta(pyus_out);
1992 Py_DECREF(pyus_out);
1993 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001994}
1995
1996static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001997divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 PyObject *pyus_left;
2000 PyObject *pyus_right;
2001 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 pyus_left = delta_to_microseconds(left);
2004 if (pyus_left == NULL)
2005 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 pyus_right = delta_to_microseconds(right);
2008 if (pyus_right == NULL) {
2009 Py_DECREF(pyus_left);
2010 return NULL;
2011 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 result = PyNumber_FloorDivide(pyus_left, pyus_right);
2014 Py_DECREF(pyus_left);
2015 Py_DECREF(pyus_right);
2016 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002017}
2018
2019static PyObject *
2020truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2021{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 PyObject *pyus_left;
2023 PyObject *pyus_right;
2024 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 pyus_left = delta_to_microseconds(left);
2027 if (pyus_left == NULL)
2028 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 pyus_right = delta_to_microseconds(right);
2031 if (pyus_right == NULL) {
2032 Py_DECREF(pyus_left);
2033 return NULL;
2034 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2037 Py_DECREF(pyus_left);
2038 Py_DECREF(pyus_right);
2039 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002040}
2041
2042static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002043truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2044{
2045 PyObject *result;
2046 PyObject *pyus_in, *pyus_out;
2047 pyus_in = delta_to_microseconds(delta);
2048 if (pyus_in == NULL)
2049 return NULL;
2050 pyus_out = divide_nearest(pyus_in, i);
2051 Py_DECREF(pyus_in);
2052 if (pyus_out == NULL)
2053 return NULL;
2054 result = microseconds_to_delta(pyus_out);
2055 Py_DECREF(pyus_out);
2056
2057 return result;
2058}
2059
2060static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002061delta_add(PyObject *left, PyObject *right)
2062{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2066 /* delta + delta */
2067 /* The C-level additions can't overflow because of the
2068 * invariant bounds.
2069 */
2070 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2071 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2072 int microseconds = GET_TD_MICROSECONDS(left) +
2073 GET_TD_MICROSECONDS(right);
2074 result = new_delta(days, seconds, microseconds, 1);
2075 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 if (result == Py_NotImplemented)
2078 Py_INCREF(result);
2079 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002080}
2081
2082static PyObject *
2083delta_negative(PyDateTime_Delta *self)
2084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 return new_delta(-GET_TD_DAYS(self),
2086 -GET_TD_SECONDS(self),
2087 -GET_TD_MICROSECONDS(self),
2088 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002089}
2090
2091static PyObject *
2092delta_positive(PyDateTime_Delta *self)
2093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 /* Could optimize this (by returning self) if this isn't a
2095 * subclass -- but who uses unary + ? Approximately nobody.
2096 */
2097 return new_delta(GET_TD_DAYS(self),
2098 GET_TD_SECONDS(self),
2099 GET_TD_MICROSECONDS(self),
2100 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002101}
2102
2103static PyObject *
2104delta_abs(PyDateTime_Delta *self)
2105{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 assert(GET_TD_MICROSECONDS(self) >= 0);
2109 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 if (GET_TD_DAYS(self) < 0)
2112 result = delta_negative(self);
2113 else
2114 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002117}
2118
2119static PyObject *
2120delta_subtract(PyObject *left, PyObject *right)
2121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2125 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002126 /* The C-level additions can't overflow because of the
2127 * invariant bounds.
2128 */
2129 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2130 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2131 int microseconds = GET_TD_MICROSECONDS(left) -
2132 GET_TD_MICROSECONDS(right);
2133 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002134 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 if (result == Py_NotImplemented)
2137 Py_INCREF(result);
2138 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002139}
2140
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002141static int
2142delta_cmp(PyObject *self, PyObject *other)
2143{
2144 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2145 if (diff == 0) {
2146 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2147 if (diff == 0)
2148 diff = GET_TD_MICROSECONDS(self) -
2149 GET_TD_MICROSECONDS(other);
2150 }
2151 return diff;
2152}
2153
Tim Peters2a799bf2002-12-16 20:18:38 +00002154static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002155delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002158 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 return diff_to_bool(diff, op);
2160 }
2161 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002162 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002164}
2165
2166static PyObject *delta_getstate(PyDateTime_Delta *self);
2167
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002168static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002169delta_hash(PyDateTime_Delta *self)
2170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 if (self->hashcode == -1) {
2172 PyObject *temp = delta_getstate(self);
2173 if (temp != NULL) {
2174 self->hashcode = PyObject_Hash(temp);
2175 Py_DECREF(temp);
2176 }
2177 }
2178 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002179}
2180
2181static PyObject *
2182delta_multiply(PyObject *left, PyObject *right)
2183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 if (PyDelta_Check(left)) {
2187 /* delta * ??? */
2188 if (PyLong_Check(right))
2189 result = multiply_int_timedelta(right,
2190 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002191 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002192 result = multiply_truedivide_timedelta_float(
2193 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 }
2195 else if (PyLong_Check(left))
2196 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002197 (PyDateTime_Delta *) right);
2198 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002199 result = multiply_truedivide_timedelta_float(
2200 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002202 if (result == Py_NotImplemented)
2203 Py_INCREF(result);
2204 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002205}
2206
2207static PyObject *
2208delta_divide(PyObject *left, PyObject *right)
2209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002212 if (PyDelta_Check(left)) {
2213 /* delta * ??? */
2214 if (PyLong_Check(right))
2215 result = divide_timedelta_int(
2216 (PyDateTime_Delta *)left,
2217 right);
2218 else if (PyDelta_Check(right))
2219 result = divide_timedelta_timedelta(
2220 (PyDateTime_Delta *)left,
2221 (PyDateTime_Delta *)right);
2222 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 if (result == Py_NotImplemented)
2225 Py_INCREF(result);
2226 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002227}
2228
Mark Dickinson7c186e22010-04-20 22:32:49 +00002229static PyObject *
2230delta_truedivide(PyObject *left, PyObject *right)
2231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 if (PyDelta_Check(left)) {
2235 if (PyDelta_Check(right))
2236 result = truedivide_timedelta_timedelta(
2237 (PyDateTime_Delta *)left,
2238 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002239 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002240 result = multiply_truedivide_timedelta_float(
2241 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002242 else if (PyLong_Check(right))
2243 result = truedivide_timedelta_int(
2244 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 if (result == Py_NotImplemented)
2248 Py_INCREF(result);
2249 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002250}
2251
2252static PyObject *
2253delta_remainder(PyObject *left, PyObject *right)
2254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 PyObject *pyus_left;
2256 PyObject *pyus_right;
2257 PyObject *pyus_remainder;
2258 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002259
Brian Curtindfc80e32011-08-10 20:28:54 -05002260 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2261 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2264 if (pyus_left == NULL)
2265 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2268 if (pyus_right == NULL) {
2269 Py_DECREF(pyus_left);
2270 return NULL;
2271 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2274 Py_DECREF(pyus_left);
2275 Py_DECREF(pyus_right);
2276 if (pyus_remainder == NULL)
2277 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 remainder = microseconds_to_delta(pyus_remainder);
2280 Py_DECREF(pyus_remainder);
2281 if (remainder == NULL)
2282 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002285}
2286
2287static PyObject *
2288delta_divmod(PyObject *left, PyObject *right)
2289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 PyObject *pyus_left;
2291 PyObject *pyus_right;
2292 PyObject *divmod;
2293 PyObject *delta;
2294 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002295
Brian Curtindfc80e32011-08-10 20:28:54 -05002296 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2297 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2300 if (pyus_left == NULL)
2301 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002303 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2304 if (pyus_right == NULL) {
2305 Py_DECREF(pyus_left);
2306 return NULL;
2307 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002308
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002309 divmod = checked_divmod(pyus_left, pyus_right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002310 Py_DECREF(pyus_left);
2311 Py_DECREF(pyus_right);
2312 if (divmod == NULL)
2313 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2316 if (delta == NULL) {
2317 Py_DECREF(divmod);
2318 return NULL;
2319 }
2320 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2321 Py_DECREF(delta);
2322 Py_DECREF(divmod);
2323 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002324}
2325
Tim Peters2a799bf2002-12-16 20:18:38 +00002326/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2327 * timedelta constructor. sofar is the # of microseconds accounted for
2328 * so far, and there are factor microseconds per current unit, the number
2329 * of which is given by num. num * factor is added to sofar in a
2330 * numerically careful way, and that's the result. Any fractional
2331 * microseconds left over (this can happen if num is a float type) are
2332 * added into *leftover.
2333 * Note that there are many ways this can give an error (NULL) return.
2334 */
2335static PyObject *
2336accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2337 double *leftover)
2338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339 PyObject *prod;
2340 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002342 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 if (PyLong_Check(num)) {
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002345 prod = PyNumber_Multiply(num, factor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346 if (prod == NULL)
2347 return NULL;
2348 sum = PyNumber_Add(sofar, prod);
2349 Py_DECREF(prod);
2350 return sum;
2351 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 if (PyFloat_Check(num)) {
2354 double dnum;
2355 double fracpart;
2356 double intpart;
2357 PyObject *x;
2358 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 /* The Plan: decompose num into an integer part and a
2361 * fractional part, num = intpart + fracpart.
2362 * Then num * factor ==
2363 * intpart * factor + fracpart * factor
2364 * and the LHS can be computed exactly in long arithmetic.
2365 * The RHS is again broken into an int part and frac part.
2366 * and the frac part is added into *leftover.
2367 */
2368 dnum = PyFloat_AsDouble(num);
2369 if (dnum == -1.0 && PyErr_Occurred())
2370 return NULL;
2371 fracpart = modf(dnum, &intpart);
2372 x = PyLong_FromDouble(intpart);
2373 if (x == NULL)
2374 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 prod = PyNumber_Multiply(x, factor);
2377 Py_DECREF(x);
2378 if (prod == NULL)
2379 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 sum = PyNumber_Add(sofar, prod);
2382 Py_DECREF(prod);
2383 if (sum == NULL)
2384 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 if (fracpart == 0.0)
2387 return sum;
2388 /* So far we've lost no information. Dealing with the
2389 * fractional part requires float arithmetic, and may
2390 * lose a little info.
2391 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002392 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 dnum *= fracpart;
2396 fracpart = modf(dnum, &intpart);
2397 x = PyLong_FromDouble(intpart);
2398 if (x == NULL) {
2399 Py_DECREF(sum);
2400 return NULL;
2401 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 y = PyNumber_Add(sum, x);
2404 Py_DECREF(sum);
2405 Py_DECREF(x);
2406 *leftover += fracpart;
2407 return y;
2408 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 PyErr_Format(PyExc_TypeError,
2411 "unsupported type for timedelta %s component: %s",
2412 tag, Py_TYPE(num)->tp_name);
2413 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002414}
2415
2416static PyObject *
2417delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 /* Argument objects. */
2422 PyObject *day = NULL;
2423 PyObject *second = NULL;
2424 PyObject *us = NULL;
2425 PyObject *ms = NULL;
2426 PyObject *minute = NULL;
2427 PyObject *hour = NULL;
2428 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 PyObject *x = NULL; /* running sum of microseconds */
2431 PyObject *y = NULL; /* temp sum of microseconds */
2432 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 static char *keywords[] = {
2435 "days", "seconds", "microseconds", "milliseconds",
2436 "minutes", "hours", "weeks", NULL
2437 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2440 keywords,
2441 &day, &second, &us,
2442 &ms, &minute, &hour, &week) == 0)
2443 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 x = PyLong_FromLong(0);
2446 if (x == NULL)
2447 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002449#define CLEANUP \
2450 Py_DECREF(x); \
2451 x = y; \
2452 if (x == NULL) \
2453 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002456 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 CLEANUP;
2458 }
2459 if (ms) {
2460 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2461 CLEANUP;
2462 }
2463 if (second) {
2464 y = accum("seconds", x, second, us_per_second, &leftover_us);
2465 CLEANUP;
2466 }
2467 if (minute) {
2468 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2469 CLEANUP;
2470 }
2471 if (hour) {
2472 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2473 CLEANUP;
2474 }
2475 if (day) {
2476 y = accum("days", x, day, us_per_day, &leftover_us);
2477 CLEANUP;
2478 }
2479 if (week) {
2480 y = accum("weeks", x, week, us_per_week, &leftover_us);
2481 CLEANUP;
2482 }
2483 if (leftover_us) {
2484 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002485 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002486 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002487 PyObject *temp;
2488
Victor Stinner69cc4872015-09-08 23:58:54 +02002489 whole_us = round(leftover_us);
2490 if (fabs(whole_us - leftover_us) == 0.5) {
2491 /* We're exactly halfway between two integers. In order
2492 * to do round-half-to-even, we must determine whether x
2493 * is odd. Note that x is odd when it's last bit is 1. The
2494 * code below uses bitwise and operation to check the last
2495 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002496 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002497 if (temp == NULL) {
2498 Py_DECREF(x);
2499 goto Done;
2500 }
2501 x_is_odd = PyObject_IsTrue(temp);
2502 Py_DECREF(temp);
2503 if (x_is_odd == -1) {
2504 Py_DECREF(x);
2505 goto Done;
2506 }
2507 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2508 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002509
Victor Stinner36a5a062013-08-28 01:53:39 +02002510 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 if (temp == NULL) {
2513 Py_DECREF(x);
2514 goto Done;
2515 }
2516 y = PyNumber_Add(x, temp);
2517 Py_DECREF(temp);
2518 CLEANUP;
2519 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002521 self = microseconds_to_delta_ex(x, type);
2522 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002523Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002525
2526#undef CLEANUP
2527}
2528
2529static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002530delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002532 return (GET_TD_DAYS(self) != 0
2533 || GET_TD_SECONDS(self) != 0
2534 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002535}
2536
2537static PyObject *
2538delta_repr(PyDateTime_Delta *self)
2539{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002540 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002541
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002542 if (args == NULL) {
2543 return NULL;
2544 }
2545
2546 const char *sep = "";
2547
2548 if (GET_TD_DAYS(self) != 0) {
2549 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2550 if (args == NULL) {
2551 return NULL;
2552 }
2553 sep = ", ";
2554 }
2555
2556 if (GET_TD_SECONDS(self) != 0) {
2557 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2558 GET_TD_SECONDS(self)));
2559 if (args == NULL) {
2560 return NULL;
2561 }
2562 sep = ", ";
2563 }
2564
2565 if (GET_TD_MICROSECONDS(self) != 0) {
2566 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2567 GET_TD_MICROSECONDS(self)));
2568 if (args == NULL) {
2569 return NULL;
2570 }
2571 }
2572
2573 if (PyUnicode_GET_LENGTH(args) == 0) {
2574 Py_SETREF(args, PyUnicode_FromString("0"));
2575 if (args == NULL) {
2576 return NULL;
2577 }
2578 }
2579
2580 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2581 args);
2582 Py_DECREF(args);
2583 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002584}
2585
2586static PyObject *
2587delta_str(PyDateTime_Delta *self)
2588{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002589 int us = GET_TD_MICROSECONDS(self);
2590 int seconds = GET_TD_SECONDS(self);
2591 int minutes = divmod(seconds, 60, &seconds);
2592 int hours = divmod(minutes, 60, &minutes);
2593 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002595 if (days) {
2596 if (us)
2597 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2598 days, (days == 1 || days == -1) ? "" : "s",
2599 hours, minutes, seconds, us);
2600 else
2601 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2602 days, (days == 1 || days == -1) ? "" : "s",
2603 hours, minutes, seconds);
2604 } else {
2605 if (us)
2606 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2607 hours, minutes, seconds, us);
2608 else
2609 return PyUnicode_FromFormat("%d:%02d:%02d",
2610 hours, minutes, seconds);
2611 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002612
Tim Peters2a799bf2002-12-16 20:18:38 +00002613}
2614
Tim Peters371935f2003-02-01 01:52:50 +00002615/* Pickle support, a simple use of __reduce__. */
2616
Tim Petersb57f8f02003-02-01 02:54:15 +00002617/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002618static PyObject *
2619delta_getstate(PyDateTime_Delta *self)
2620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 return Py_BuildValue("iii", GET_TD_DAYS(self),
2622 GET_TD_SECONDS(self),
2623 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002624}
2625
Tim Peters2a799bf2002-12-16 20:18:38 +00002626static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302627delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitroube6859d2009-11-25 23:02:32 +00002628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002629 PyObject *total_seconds;
2630 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002632 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2633 if (total_microseconds == NULL)
2634 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002635
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002636 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002638 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002640}
2641
2642static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302643delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00002644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002645 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002646}
2647
2648#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2649
2650static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002652 {"days", T_INT, OFFSET(days), READONLY,
2653 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002655 {"seconds", T_INT, OFFSET(seconds), READONLY,
2656 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2659 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2660 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002661};
2662
2663static PyMethodDef delta_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302664 {"total_seconds", delta_total_seconds, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002665 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002667 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2668 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002671};
2672
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002673static const char delta_doc[] =
Chris Barkerd6a61f22018-10-19 15:43:24 -07002674PyDoc_STR("Difference between two datetime values.\n\n"
2675 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2676 "minutes=0, hours=0, weeks=0)\n\n"
2677 "All arguments are optional and default to 0.\n"
2678 "Arguments may be integers or floats, and may be positive or negative.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002679
2680static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002681 delta_add, /* nb_add */
2682 delta_subtract, /* nb_subtract */
2683 delta_multiply, /* nb_multiply */
2684 delta_remainder, /* nb_remainder */
2685 delta_divmod, /* nb_divmod */
2686 0, /* nb_power */
2687 (unaryfunc)delta_negative, /* nb_negative */
2688 (unaryfunc)delta_positive, /* nb_positive */
2689 (unaryfunc)delta_abs, /* nb_absolute */
2690 (inquiry)delta_bool, /* nb_bool */
2691 0, /*nb_invert*/
2692 0, /*nb_lshift*/
2693 0, /*nb_rshift*/
2694 0, /*nb_and*/
2695 0, /*nb_xor*/
2696 0, /*nb_or*/
2697 0, /*nb_int*/
2698 0, /*nb_reserved*/
2699 0, /*nb_float*/
2700 0, /*nb_inplace_add*/
2701 0, /*nb_inplace_subtract*/
2702 0, /*nb_inplace_multiply*/
2703 0, /*nb_inplace_remainder*/
2704 0, /*nb_inplace_power*/
2705 0, /*nb_inplace_lshift*/
2706 0, /*nb_inplace_rshift*/
2707 0, /*nb_inplace_and*/
2708 0, /*nb_inplace_xor*/
2709 0, /*nb_inplace_or*/
2710 delta_divide, /* nb_floor_divide */
2711 delta_truedivide, /* nb_true_divide */
2712 0, /* nb_inplace_floor_divide */
2713 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002714};
2715
2716static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002717 PyVarObject_HEAD_INIT(NULL, 0)
2718 "datetime.timedelta", /* tp_name */
2719 sizeof(PyDateTime_Delta), /* tp_basicsize */
2720 0, /* tp_itemsize */
2721 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002722 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002723 0, /* tp_getattr */
2724 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002725 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002726 (reprfunc)delta_repr, /* tp_repr */
2727 &delta_as_number, /* tp_as_number */
2728 0, /* tp_as_sequence */
2729 0, /* tp_as_mapping */
2730 (hashfunc)delta_hash, /* tp_hash */
2731 0, /* tp_call */
2732 (reprfunc)delta_str, /* tp_str */
2733 PyObject_GenericGetAttr, /* tp_getattro */
2734 0, /* tp_setattro */
2735 0, /* tp_as_buffer */
2736 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2737 delta_doc, /* tp_doc */
2738 0, /* tp_traverse */
2739 0, /* tp_clear */
2740 delta_richcompare, /* tp_richcompare */
2741 0, /* tp_weaklistoffset */
2742 0, /* tp_iter */
2743 0, /* tp_iternext */
2744 delta_methods, /* tp_methods */
2745 delta_members, /* tp_members */
2746 0, /* tp_getset */
2747 0, /* tp_base */
2748 0, /* tp_dict */
2749 0, /* tp_descr_get */
2750 0, /* tp_descr_set */
2751 0, /* tp_dictoffset */
2752 0, /* tp_init */
2753 0, /* tp_alloc */
2754 delta_new, /* tp_new */
2755 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002756};
2757
2758/*
2759 * PyDateTime_Date implementation.
2760 */
2761
2762/* Accessor properties. */
2763
2764static PyObject *
2765date_year(PyDateTime_Date *self, void *unused)
2766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002767 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002768}
2769
2770static PyObject *
2771date_month(PyDateTime_Date *self, void *unused)
2772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002773 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002774}
2775
2776static PyObject *
2777date_day(PyDateTime_Date *self, void *unused)
2778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002779 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002780}
2781
2782static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002783 {"year", (getter)date_year},
2784 {"month", (getter)date_month},
2785 {"day", (getter)date_day},
2786 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002787};
2788
2789/* Constructors. */
2790
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002791static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002792
Tim Peters2a799bf2002-12-16 20:18:38 +00002793static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002794date_from_pickle(PyTypeObject *type, PyObject *state)
2795{
2796 PyDateTime_Date *me;
2797
2798 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2799 if (me != NULL) {
2800 const char *pdata = PyBytes_AS_STRING(state);
2801 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2802 me->hashcode = -1;
2803 }
2804 return (PyObject *)me;
2805}
2806
2807static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002808date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002811 int year;
2812 int month;
2813 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka1133a8c2018-12-07 16:48:21 +02002816 if (PyTuple_GET_SIZE(args) == 1) {
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002817 PyObject *state = PyTuple_GET_ITEM(args, 0);
2818 if (PyBytes_Check(state)) {
2819 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2820 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2821 {
2822 return date_from_pickle(type, state);
Victor Stinnerb37672d2018-11-22 03:37:50 +01002823 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002824 }
2825 else if (PyUnicode_Check(state)) {
2826 if (PyUnicode_READY(state)) {
2827 return NULL;
2828 }
2829 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
2830 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
2831 {
2832 state = PyUnicode_AsLatin1String(state);
2833 if (state == NULL) {
2834 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
2835 /* More informative error message. */
2836 PyErr_SetString(PyExc_ValueError,
2837 "Failed to encode latin1 string when unpickling "
2838 "a date object. "
2839 "pickle.load(data, encoding='latin1') is assumed.");
2840 }
2841 return NULL;
2842 }
2843 self = date_from_pickle(type, state);
2844 Py_DECREF(state);
2845 return self;
2846 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002848 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2851 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002852 self = new_date_ex(year, month, day, type);
2853 }
2854 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002855}
2856
Tim Peters2a799bf2002-12-16 20:18:38 +00002857static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002858date_fromtimestamp(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002859{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002860 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002861 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002862
Victor Stinnere4a994d2015-03-30 01:10:14 +02002863 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002865
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002866 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002867 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002868
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002869 return new_date_subclass_ex(tm.tm_year + 1900,
2870 tm.tm_mon + 1,
2871 tm.tm_mday,
2872 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002873}
2874
2875/* Return new date from current time.
2876 * We say this is equivalent to fromtimestamp(time.time()), and the
2877 * only way to be sure of that is to *call* time.time(). That's not
2878 * generally the same as calling C's time.
2879 */
2880static PyObject *
2881date_today(PyObject *cls, PyObject *dummy)
2882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002883 PyObject *time;
2884 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002885 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002887 time = time_time();
2888 if (time == NULL)
2889 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002891 /* Note well: today() is a class method, so this may not call
2892 * date.fromtimestamp. For example, it may call
2893 * datetime.fromtimestamp. That's why we need all the accuracy
2894 * time.time() delivers; if someone were gonzo about optimization,
2895 * date.today() could get away with plain C time().
2896 */
Victor Stinner20401de2016-12-09 15:24:31 +01002897 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2898 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002899 Py_DECREF(time);
2900 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002901}
2902
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002903/*[clinic input]
2904@classmethod
2905datetime.date.fromtimestamp
2906
2907 timestamp: object
2908 /
2909
2910Create a date from a POSIX timestamp.
2911
2912The timestamp is a number, e.g. created via time.time(), that is interpreted
2913as local time.
2914[clinic start generated code]*/
2915
Tim Peters2a799bf2002-12-16 20:18:38 +00002916static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002917datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp)
2918/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00002919{
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002920 return date_fromtimestamp((PyObject *) type, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002921}
2922
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04002923/* bpo-36025: This is a wrapper for API compatibility with the public C API,
2924 * which expects a function that takes an *args tuple, whereas the argument
2925 * clinic generates code that takes METH_O.
2926 */
2927static PyObject *
2928datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args)
2929{
2930 PyObject *timestamp;
2931 PyObject *result = NULL;
2932
2933 if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, &timestamp)) {
2934 result = date_fromtimestamp(cls, timestamp);
2935 }
2936
2937 return result;
2938}
2939
Tim Peters2a799bf2002-12-16 20:18:38 +00002940/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2941 * the ordinal is out of range.
2942 */
2943static PyObject *
2944date_fromordinal(PyObject *cls, PyObject *args)
2945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002946 PyObject *result = NULL;
2947 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002949 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2950 int year;
2951 int month;
2952 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002954 if (ordinal < 1)
2955 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2956 ">= 1");
2957 else {
2958 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002959 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002960 }
2961 }
2962 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002963}
2964
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002965/* Return the new date from a string as generated by date.isoformat() */
2966static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04002967date_fromisoformat(PyObject *cls, PyObject *dtstr)
2968{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002969 assert(dtstr != NULL);
2970
2971 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04002972 PyErr_SetString(PyExc_TypeError,
2973 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002974 return NULL;
2975 }
2976
2977 Py_ssize_t len;
2978
Paul Ganssle3df85402018-10-22 12:32:52 -04002979 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04002980 if (dt_ptr == NULL) {
2981 goto invalid_string_error;
2982 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002983
2984 int year = 0, month = 0, day = 0;
2985
2986 int rv;
2987 if (len == 10) {
2988 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
Paul Ganssle3df85402018-10-22 12:32:52 -04002989 }
2990 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002991 rv = -1;
2992 }
2993
2994 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04002995 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002996 }
2997
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002998 return new_date_subclass_ex(year, month, day, cls);
Paul Ganssle096329f2018-08-23 11:06:20 -04002999
3000invalid_string_error:
Paul Ganssle3df85402018-10-22 12:32:52 -04003001 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04003002 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003003}
3004
Paul Ganssle88c09372019-04-29 09:22:03 -04003005
3006static PyObject *
3007date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw)
3008{
3009 static char *keywords[] = {
3010 "year", "week", "day", NULL
3011 };
3012
3013 int year, week, day;
3014 if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar",
3015 keywords,
3016 &year, &week, &day) == 0) {
3017 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
3018 PyErr_Format(PyExc_ValueError,
3019 "ISO calendar component out of range");
3020
3021 }
3022 return NULL;
3023 }
3024
3025 // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
3026 if (year < MINYEAR || year > MAXYEAR) {
3027 PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
3028 return NULL;
3029 }
3030
3031 if (week <= 0 || week >= 53) {
3032 int out_of_range = 1;
3033 if (week == 53) {
3034 // ISO years have 53 weeks in it on years starting with a Thursday
3035 // and on leap years starting on Wednesday
3036 int first_weekday = weekday(year, 1, 1);
3037 if (first_weekday == 3 || (first_weekday == 2 && is_leap(year))) {
3038 out_of_range = 0;
3039 }
3040 }
3041
3042 if (out_of_range) {
3043 PyErr_Format(PyExc_ValueError, "Invalid week: %d", week);
3044 return NULL;
3045 }
3046 }
3047
3048 if (day <= 0 || day >= 8) {
3049 PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])",
3050 day);
3051 return NULL;
3052 }
3053
3054 // Convert (Y, W, D) to (Y, M, D) in-place
3055 int day_1 = iso_week1_monday(year);
3056
3057 int month = week;
3058 int day_offset = (month - 1)*7 + day - 1;
3059
3060 ord_to_ymd(day_1 + day_offset, &year, &month, &day);
3061
3062 return new_date_subclass_ex(year, month, day, cls);
3063}
3064
3065
Tim Peters2a799bf2002-12-16 20:18:38 +00003066/*
3067 * Date arithmetic.
3068 */
3069
3070/* date + timedelta -> date. If arg negate is true, subtract the timedelta
3071 * instead.
3072 */
3073static PyObject *
3074add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
3075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003076 PyObject *result = NULL;
3077 int year = GET_YEAR(date);
3078 int month = GET_MONTH(date);
3079 int deltadays = GET_TD_DAYS(delta);
3080 /* C-level overflow is impossible because |deltadays| < 1e9. */
3081 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00003082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 if (normalize_date(&year, &month, &day) >= 0)
Paul Ganssle89427cd2019-02-04 14:42:04 -05003084 result = new_date_subclass_ex(year, month, day,
3085 (PyObject* )Py_TYPE(date));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003086 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003087}
3088
3089static PyObject *
3090date_add(PyObject *left, PyObject *right)
3091{
Brian Curtindfc80e32011-08-10 20:28:54 -05003092 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3093 Py_RETURN_NOTIMPLEMENTED;
3094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003095 if (PyDate_Check(left)) {
3096 /* date + ??? */
3097 if (PyDelta_Check(right))
3098 /* date + delta */
3099 return add_date_timedelta((PyDateTime_Date *) left,
3100 (PyDateTime_Delta *) right,
3101 0);
3102 }
3103 else {
3104 /* ??? + date
3105 * 'right' must be one of us, or we wouldn't have been called
3106 */
3107 if (PyDelta_Check(left))
3108 /* delta + date */
3109 return add_date_timedelta((PyDateTime_Date *) right,
3110 (PyDateTime_Delta *) left,
3111 0);
3112 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003113 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003114}
3115
3116static PyObject *
3117date_subtract(PyObject *left, PyObject *right)
3118{
Brian Curtindfc80e32011-08-10 20:28:54 -05003119 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3120 Py_RETURN_NOTIMPLEMENTED;
3121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 if (PyDate_Check(left)) {
3123 if (PyDate_Check(right)) {
3124 /* date - date */
3125 int left_ord = ymd_to_ord(GET_YEAR(left),
3126 GET_MONTH(left),
3127 GET_DAY(left));
3128 int right_ord = ymd_to_ord(GET_YEAR(right),
3129 GET_MONTH(right),
3130 GET_DAY(right));
3131 return new_delta(left_ord - right_ord, 0, 0, 0);
3132 }
3133 if (PyDelta_Check(right)) {
3134 /* date - delta */
3135 return add_date_timedelta((PyDateTime_Date *) left,
3136 (PyDateTime_Delta *) right,
3137 1);
3138 }
3139 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003140 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003141}
3142
3143
3144/* Various ways to turn a date into a string. */
3145
3146static PyObject *
3147date_repr(PyDateTime_Date *self)
3148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003149 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3150 Py_TYPE(self)->tp_name,
3151 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003152}
3153
3154static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303155date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003157 return PyUnicode_FromFormat("%04d-%02d-%02d",
3158 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003159}
3160
Tim Peterse2df5ff2003-05-02 18:39:55 +00003161/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003162static PyObject *
3163date_str(PyDateTime_Date *self)
3164{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003165 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003166}
3167
3168
3169static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303170date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003173}
3174
3175static PyObject *
3176date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003178 /* This method can be inherited, and needs to call the
3179 * timetuple() method appropriate to self's class.
3180 */
3181 PyObject *result;
3182 PyObject *tuple;
3183 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003184 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003185 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003187 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3188 &format))
3189 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003190
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003191 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003192 if (tuple == NULL)
3193 return NULL;
3194 result = wrap_strftime((PyObject *)self, format, tuple,
3195 (PyObject *)self);
3196 Py_DECREF(tuple);
3197 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003198}
3199
Eric Smith1ba31142007-09-11 18:06:02 +00003200static PyObject *
3201date_format(PyDateTime_Date *self, PyObject *args)
3202{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003203 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003205 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3206 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003209 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003210 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003211
Victor Stinner20401de2016-12-09 15:24:31 +01003212 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3213 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003214}
3215
Tim Peters2a799bf2002-12-16 20:18:38 +00003216/* ISO methods. */
3217
3218static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303219date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003220{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003221 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003223 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003224}
3225
3226static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303227date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003228{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003229 int year = GET_YEAR(self);
3230 int week1_monday = iso_week1_monday(year);
3231 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3232 int week;
3233 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003235 week = divmod(today - week1_monday, 7, &day);
3236 if (week < 0) {
3237 --year;
3238 week1_monday = iso_week1_monday(year);
3239 week = divmod(today - week1_monday, 7, &day);
3240 }
3241 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3242 ++year;
3243 week = 0;
3244 }
3245 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003246}
3247
3248/* Miscellaneous methods. */
3249
Tim Peters2a799bf2002-12-16 20:18:38 +00003250static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003251date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003252{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003253 if (PyDate_Check(other)) {
3254 int diff = memcmp(((PyDateTime_Date *)self)->data,
3255 ((PyDateTime_Date *)other)->data,
3256 _PyDateTime_DATE_DATASIZE);
3257 return diff_to_bool(diff, op);
3258 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003259 else
3260 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003261}
3262
3263static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303264date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003266 return build_struct_time(GET_YEAR(self),
3267 GET_MONTH(self),
3268 GET_DAY(self),
3269 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003270}
3271
Tim Peters12bf3392002-12-24 05:41:27 +00003272static PyObject *
3273date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003275 PyObject *clone;
3276 PyObject *tuple;
3277 int year = GET_YEAR(self);
3278 int month = GET_MONTH(self);
3279 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003281 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3282 &year, &month, &day))
3283 return NULL;
3284 tuple = Py_BuildValue("iii", year, month, day);
3285 if (tuple == NULL)
3286 return NULL;
3287 clone = date_new(Py_TYPE(self), tuple, NULL);
3288 Py_DECREF(tuple);
3289 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003290}
3291
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003292static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003293generic_hash(unsigned char *data, int len)
3294{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003295 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003296}
3297
3298
3299static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003300
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003301static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003302date_hash(PyDateTime_Date *self)
3303{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003304 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003305 self->hashcode = generic_hash(
3306 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003307 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003309 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003310}
3311
3312static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303313date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003315 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3316 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003317}
3318
3319static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303320date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003322 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003324 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003325}
3326
Tim Peters371935f2003-02-01 01:52:50 +00003327/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003328
Tim Petersb57f8f02003-02-01 02:54:15 +00003329/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003330static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003331date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003332{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003333 PyObject* field;
3334 field = PyBytes_FromStringAndSize((char*)self->data,
3335 _PyDateTime_DATE_DATASIZE);
3336 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003337}
3338
3339static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003340date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003342 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003343}
3344
3345static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003347 /* Class methods: */
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02003348 DATETIME_DATE_FROMTIMESTAMP_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00003349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003350 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3351 METH_CLASS,
3352 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3353 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003354
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003355 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3356 METH_CLASS,
3357 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3358
Paul Ganssle88c09372019-04-29 09:22:03 -04003359 {"fromisocalendar", (PyCFunction)(void(*)(void))date_fromisocalendar,
3360 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
3361 PyDoc_STR("int, int, int -> Construct a date from the ISO year, week "
3362 "number and weekday.\n\n"
3363 "This is the inverse of the date.isocalendar() function")},
3364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003365 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3366 PyDoc_STR("Current date or datetime: same as "
3367 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003369 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003371 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3372 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003373
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003374 {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003375 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003377 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3378 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003380 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3381 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003383 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3384 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3385 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003387 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3388 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003390 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3391 PyDoc_STR("Return the day of the week represented by the date.\n"
3392 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003394 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3395 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3396 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003398 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3399 PyDoc_STR("Return the day of the week represented by the date.\n"
3400 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003401
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003402 {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003403 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003405 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3406 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003408 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003409};
3410
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003411static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003412PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003413
3414static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003415 date_add, /* nb_add */
3416 date_subtract, /* nb_subtract */
3417 0, /* nb_multiply */
3418 0, /* nb_remainder */
3419 0, /* nb_divmod */
3420 0, /* nb_power */
3421 0, /* nb_negative */
3422 0, /* nb_positive */
3423 0, /* nb_absolute */
3424 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003425};
3426
3427static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003428 PyVarObject_HEAD_INIT(NULL, 0)
3429 "datetime.date", /* tp_name */
3430 sizeof(PyDateTime_Date), /* tp_basicsize */
3431 0, /* tp_itemsize */
3432 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003433 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003434 0, /* tp_getattr */
3435 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003436 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003437 (reprfunc)date_repr, /* tp_repr */
3438 &date_as_number, /* tp_as_number */
3439 0, /* tp_as_sequence */
3440 0, /* tp_as_mapping */
3441 (hashfunc)date_hash, /* tp_hash */
3442 0, /* tp_call */
3443 (reprfunc)date_str, /* tp_str */
3444 PyObject_GenericGetAttr, /* tp_getattro */
3445 0, /* tp_setattro */
3446 0, /* tp_as_buffer */
3447 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3448 date_doc, /* tp_doc */
3449 0, /* tp_traverse */
3450 0, /* tp_clear */
3451 date_richcompare, /* tp_richcompare */
3452 0, /* tp_weaklistoffset */
3453 0, /* tp_iter */
3454 0, /* tp_iternext */
3455 date_methods, /* tp_methods */
3456 0, /* tp_members */
3457 date_getset, /* tp_getset */
3458 0, /* tp_base */
3459 0, /* tp_dict */
3460 0, /* tp_descr_get */
3461 0, /* tp_descr_set */
3462 0, /* tp_dictoffset */
3463 0, /* tp_init */
3464 0, /* tp_alloc */
3465 date_new, /* tp_new */
3466 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003467};
3468
3469/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003470 * PyDateTime_TZInfo implementation.
3471 */
3472
3473/* This is a pure abstract base class, so doesn't do anything beyond
3474 * raising NotImplemented exceptions. Real tzinfo classes need
3475 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003476 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003477 * be subclasses of this tzinfo class, which is easy and quick to check).
3478 *
3479 * Note: For reasons having to do with pickling of subclasses, we have
3480 * to allow tzinfo objects to be instantiated. This wasn't an issue
3481 * in the Python implementation (__init__() could raise NotImplementedError
3482 * there without ill effect), but doing so in the C implementation hit a
3483 * brick wall.
3484 */
3485
3486static PyObject *
3487tzinfo_nogo(const char* methodname)
3488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 PyErr_Format(PyExc_NotImplementedError,
3490 "a tzinfo subclass must implement %s()",
3491 methodname);
3492 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003493}
3494
3495/* Methods. A subclass must implement these. */
3496
Tim Peters52dcce22003-01-23 16:36:11 +00003497static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003498tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003500 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003501}
3502
Tim Peters52dcce22003-01-23 16:36:11 +00003503static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003504tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3505{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003506 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003507}
3508
Tim Peters52dcce22003-01-23 16:36:11 +00003509static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003510tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3511{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003512 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003513}
3514
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003515
3516static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3517 PyDateTime_Delta *delta,
3518 int factor);
3519static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3520static PyObject *datetime_dst(PyObject *self, PyObject *);
3521
Tim Peters52dcce22003-01-23 16:36:11 +00003522static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003523tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003524{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003525 PyObject *result = NULL;
3526 PyObject *off = NULL, *dst = NULL;
3527 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003528
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003529 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003530 PyErr_SetString(PyExc_TypeError,
3531 "fromutc: argument must be a datetime");
3532 return NULL;
3533 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003534 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003535 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3536 "is not self");
3537 return NULL;
3538 }
Tim Peters52dcce22003-01-23 16:36:11 +00003539
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003540 off = datetime_utcoffset(dt, NULL);
3541 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003542 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003543 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003544 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3545 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003546 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003547 }
Tim Peters52dcce22003-01-23 16:36:11 +00003548
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003549 dst = datetime_dst(dt, NULL);
3550 if (dst == NULL)
3551 goto Fail;
3552 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003553 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3554 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003555 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003556 }
Tim Peters52dcce22003-01-23 16:36:11 +00003557
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003558 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3559 if (delta == NULL)
3560 goto Fail;
3561 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003562 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003563 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003564
3565 Py_DECREF(dst);
3566 dst = call_dst(GET_DT_TZINFO(dt), result);
3567 if (dst == NULL)
3568 goto Fail;
3569 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003570 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003571 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003572 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003573 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003574 if (result == NULL)
3575 goto Fail;
3576 }
3577 Py_DECREF(delta);
3578 Py_DECREF(dst);
3579 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003580 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003581
3582Inconsistent:
Serhiy Storchaka34fd4c22018-11-05 16:20:25 +02003583 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003584 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003585
Leo Ariasc3d95082018-02-03 18:36:10 -06003586 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003587Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003588 Py_XDECREF(off);
3589 Py_XDECREF(dst);
3590 Py_XDECREF(delta);
3591 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003592 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003593}
3594
Tim Peters2a799bf2002-12-16 20:18:38 +00003595/*
3596 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003597 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003598 */
3599
Guido van Rossum177e41a2003-01-30 22:06:23 +00003600static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303601tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003602{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003603 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003604 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003605 _Py_IDENTIFIER(__getinitargs__);
3606 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003607
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003608 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003609 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003610 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003611 Py_DECREF(getinitargs);
3612 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003613 return NULL;
3614 }
3615 }
3616 else {
3617 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003618
3619 args = PyTuple_New(0);
3620 if (args == NULL) {
3621 return NULL;
3622 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003623 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003624
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003625 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003626 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003627 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003628 Py_DECREF(getstate);
3629 if (state == NULL) {
3630 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003631 return NULL;
3632 }
3633 }
3634 else {
3635 PyObject **dictptr;
3636 PyErr_Clear();
3637 state = Py_None;
3638 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003639 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003640 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003641 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003642 Py_INCREF(state);
3643 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003645 if (state == Py_None) {
3646 Py_DECREF(state);
3647 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3648 }
3649 else
3650 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003651}
Tim Peters2a799bf2002-12-16 20:18:38 +00003652
3653static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003655 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3656 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003658 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003659 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3660 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003662 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003663 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003665 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003666 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003667
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303668 {"__reduce__", tzinfo_reduce, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003669 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003671 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003672};
3673
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003674static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003675PyDoc_STR("Abstract base class for time zone info objects.");
3676
Neal Norwitz227b5332006-03-22 09:28:35 +00003677static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003678 PyVarObject_HEAD_INIT(NULL, 0)
3679 "datetime.tzinfo", /* tp_name */
3680 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3681 0, /* tp_itemsize */
3682 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003683 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003684 0, /* tp_getattr */
3685 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003686 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003687 0, /* tp_repr */
3688 0, /* tp_as_number */
3689 0, /* tp_as_sequence */
3690 0, /* tp_as_mapping */
3691 0, /* tp_hash */
3692 0, /* tp_call */
3693 0, /* tp_str */
3694 PyObject_GenericGetAttr, /* tp_getattro */
3695 0, /* tp_setattro */
3696 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003697 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003698 tzinfo_doc, /* tp_doc */
3699 0, /* tp_traverse */
3700 0, /* tp_clear */
3701 0, /* tp_richcompare */
3702 0, /* tp_weaklistoffset */
3703 0, /* tp_iter */
3704 0, /* tp_iternext */
3705 tzinfo_methods, /* tp_methods */
3706 0, /* tp_members */
3707 0, /* tp_getset */
3708 0, /* tp_base */
3709 0, /* tp_dict */
3710 0, /* tp_descr_get */
3711 0, /* tp_descr_set */
3712 0, /* tp_dictoffset */
3713 0, /* tp_init */
3714 0, /* tp_alloc */
3715 PyType_GenericNew, /* tp_new */
3716 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003717};
3718
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003719static char *timezone_kws[] = {"offset", "name", NULL};
3720
3721static PyObject *
3722timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3723{
3724 PyObject *offset;
3725 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003726 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3727 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003728 return new_timezone(offset, name);
3729
3730 return NULL;
3731}
3732
3733static void
3734timezone_dealloc(PyDateTime_TimeZone *self)
3735{
3736 Py_CLEAR(self->offset);
3737 Py_CLEAR(self->name);
3738 Py_TYPE(self)->tp_free((PyObject *)self);
3739}
3740
3741static PyObject *
3742timezone_richcompare(PyDateTime_TimeZone *self,
3743 PyDateTime_TimeZone *other, int op)
3744{
Brian Curtindfc80e32011-08-10 20:28:54 -05003745 if (op != Py_EQ && op != Py_NE)
3746 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003747 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003748 if (op == Py_EQ)
3749 Py_RETURN_FALSE;
3750 else
3751 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003752 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003753 return delta_richcompare(self->offset, other->offset, op);
3754}
3755
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003756static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003757timezone_hash(PyDateTime_TimeZone *self)
3758{
3759 return delta_hash((PyDateTime_Delta *)self->offset);
3760}
3761
3762/* Check argument type passed to tzname, utcoffset, or dst methods.
3763 Returns 0 for good argument. Returns -1 and sets exception info
3764 otherwise.
3765 */
3766static int
3767_timezone_check_argument(PyObject *dt, const char *meth)
3768{
3769 if (dt == Py_None || PyDateTime_Check(dt))
3770 return 0;
3771 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3772 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3773 return -1;
3774}
3775
3776static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003777timezone_repr(PyDateTime_TimeZone *self)
3778{
3779 /* Note that although timezone is not subclassable, it is convenient
3780 to use Py_TYPE(self)->tp_name here. */
3781 const char *type_name = Py_TYPE(self)->tp_name;
3782
3783 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3784 return PyUnicode_FromFormat("%s.utc", type_name);
3785
3786 if (self->name == NULL)
3787 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3788
3789 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3790 self->name);
3791}
3792
3793
3794static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003795timezone_str(PyDateTime_TimeZone *self)
3796{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003797 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003798 PyObject *offset;
3799 char sign;
3800
3801 if (self->name != NULL) {
3802 Py_INCREF(self->name);
3803 return self->name;
3804 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003805 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003806 (GET_TD_DAYS(self->offset) == 0 &&
3807 GET_TD_SECONDS(self->offset) == 0 &&
3808 GET_TD_MICROSECONDS(self->offset) == 0))
3809 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003810 /* Offset is normalized, so it is negative if days < 0 */
3811 if (GET_TD_DAYS(self->offset) < 0) {
3812 sign = '-';
3813 offset = delta_negative((PyDateTime_Delta *)self->offset);
3814 if (offset == NULL)
3815 return NULL;
3816 }
3817 else {
3818 sign = '+';
3819 offset = self->offset;
3820 Py_INCREF(offset);
3821 }
3822 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003823 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003824 seconds = GET_TD_SECONDS(offset);
3825 Py_DECREF(offset);
3826 minutes = divmod(seconds, 60, &seconds);
3827 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003828 if (microseconds != 0) {
3829 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3830 sign, hours, minutes,
3831 seconds, microseconds);
3832 }
3833 if (seconds != 0) {
3834 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3835 sign, hours, minutes, seconds);
3836 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003837 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003838}
3839
3840static PyObject *
3841timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3842{
3843 if (_timezone_check_argument(dt, "tzname") == -1)
3844 return NULL;
3845
3846 return timezone_str(self);
3847}
3848
3849static PyObject *
3850timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3851{
3852 if (_timezone_check_argument(dt, "utcoffset") == -1)
3853 return NULL;
3854
3855 Py_INCREF(self->offset);
3856 return self->offset;
3857}
3858
3859static PyObject *
3860timezone_dst(PyObject *self, PyObject *dt)
3861{
3862 if (_timezone_check_argument(dt, "dst") == -1)
3863 return NULL;
3864
3865 Py_RETURN_NONE;
3866}
3867
3868static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003869timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3870{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003871 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003872 PyErr_SetString(PyExc_TypeError,
3873 "fromutc: argument must be a datetime");
3874 return NULL;
3875 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003876 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003877 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3878 "is not self");
3879 return NULL;
3880 }
3881
3882 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3883}
3884
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003885static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303886timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003887{
3888 if (self->name == NULL)
3889 return Py_BuildValue("(O)", self->offset);
3890 return Py_BuildValue("(OO)", self->offset, self->name);
3891}
3892
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003893static PyMethodDef timezone_methods[] = {
3894 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3895 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003896 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003897
3898 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003899 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003900
3901 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003902 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003903
3904 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3905 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3906
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003907 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3908 PyDoc_STR("pickle support")},
3909
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003910 {NULL, NULL}
3911};
3912
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003913static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003914PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3915
3916static PyTypeObject PyDateTime_TimeZoneType = {
3917 PyVarObject_HEAD_INIT(NULL, 0)
3918 "datetime.timezone", /* tp_name */
3919 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3920 0, /* tp_itemsize */
3921 (destructor)timezone_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003922 0, /* tp_vectorcall_offset */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003923 0, /* tp_getattr */
3924 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003925 0, /* tp_as_async */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003926 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003927 0, /* tp_as_number */
3928 0, /* tp_as_sequence */
3929 0, /* tp_as_mapping */
3930 (hashfunc)timezone_hash, /* tp_hash */
3931 0, /* tp_call */
3932 (reprfunc)timezone_str, /* tp_str */
3933 0, /* tp_getattro */
3934 0, /* tp_setattro */
3935 0, /* tp_as_buffer */
3936 Py_TPFLAGS_DEFAULT, /* tp_flags */
3937 timezone_doc, /* tp_doc */
3938 0, /* tp_traverse */
3939 0, /* tp_clear */
3940 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3941 0, /* tp_weaklistoffset */
3942 0, /* tp_iter */
3943 0, /* tp_iternext */
3944 timezone_methods, /* tp_methods */
3945 0, /* tp_members */
3946 0, /* tp_getset */
3947 &PyDateTime_TZInfoType, /* tp_base */
3948 0, /* tp_dict */
3949 0, /* tp_descr_get */
3950 0, /* tp_descr_set */
3951 0, /* tp_dictoffset */
3952 0, /* tp_init */
3953 0, /* tp_alloc */
3954 timezone_new, /* tp_new */
3955};
3956
Tim Peters2a799bf2002-12-16 20:18:38 +00003957/*
Tim Peters37f39822003-01-10 03:49:02 +00003958 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003959 */
3960
Tim Peters37f39822003-01-10 03:49:02 +00003961/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003962 */
3963
3964static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003965time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003966{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003967 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003968}
3969
Tim Peters37f39822003-01-10 03:49:02 +00003970static PyObject *
3971time_minute(PyDateTime_Time *self, void *unused)
3972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003973 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003974}
3975
3976/* The name time_second conflicted with some platform header file. */
3977static PyObject *
3978py_time_second(PyDateTime_Time *self, void *unused)
3979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003981}
3982
3983static PyObject *
3984time_microsecond(PyDateTime_Time *self, void *unused)
3985{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003986 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003987}
3988
3989static PyObject *
3990time_tzinfo(PyDateTime_Time *self, void *unused)
3991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003992 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3993 Py_INCREF(result);
3994 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003995}
3996
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003997static PyObject *
3998time_fold(PyDateTime_Time *self, void *unused)
3999{
4000 return PyLong_FromLong(TIME_GET_FOLD(self));
4001}
4002
Tim Peters37f39822003-01-10 03:49:02 +00004003static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 {"hour", (getter)time_hour},
4005 {"minute", (getter)time_minute},
4006 {"second", (getter)py_time_second},
4007 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004008 {"tzinfo", (getter)time_tzinfo},
4009 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004010 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004011};
4012
4013/*
4014 * Constructors.
4015 */
4016
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004017static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004018 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00004019
Tim Peters2a799bf2002-12-16 20:18:38 +00004020static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004021time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4022{
4023 PyDateTime_Time *me;
4024 char aware = (char)(tzinfo != Py_None);
4025
4026 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4027 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4028 return NULL;
4029 }
4030
4031 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
4032 if (me != NULL) {
4033 const char *pdata = PyBytes_AS_STRING(state);
4034
4035 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
4036 me->hashcode = -1;
4037 me->hastzinfo = aware;
4038 if (aware) {
4039 Py_INCREF(tzinfo);
4040 me->tzinfo = tzinfo;
4041 }
4042 if (pdata[0] & (1 << 7)) {
4043 me->data[0] -= 128;
4044 me->fold = 1;
4045 }
4046 else {
4047 me->fold = 0;
4048 }
4049 }
4050 return (PyObject *)me;
4051}
4052
4053static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004054time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004055{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004056 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004057 int hour = 0;
4058 int minute = 0;
4059 int second = 0;
4060 int usecond = 0;
4061 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004062 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004064 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004065 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4066 PyObject *state = PyTuple_GET_ITEM(args, 0);
4067 if (PyTuple_GET_SIZE(args) == 2) {
4068 tzinfo = PyTuple_GET_ITEM(args, 1);
4069 }
4070 if (PyBytes_Check(state)) {
4071 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
4072 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
4073 {
4074 return time_from_pickle(type, state, tzinfo);
4075 }
4076 }
4077 else if (PyUnicode_Check(state)) {
4078 if (PyUnicode_READY(state)) {
4079 return NULL;
4080 }
4081 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
4082 (0x7F & PyUnicode_READ_CHAR(state, 2)) < 24)
4083 {
4084 state = PyUnicode_AsLatin1String(state);
4085 if (state == NULL) {
4086 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4087 /* More informative error message. */
4088 PyErr_SetString(PyExc_ValueError,
4089 "Failed to encode latin1 string when unpickling "
4090 "a time object. "
4091 "pickle.load(data, encoding='latin1') is assumed.");
4092 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004093 return NULL;
4094 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004095 self = time_from_pickle(type, state, tzinfo);
4096 Py_DECREF(state);
4097 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004098 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004100 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004101 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004102
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004103 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004104 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004105 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004106 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4107 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004108 }
4109 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004110}
4111
4112/*
4113 * Destructor.
4114 */
4115
4116static void
Tim Peters37f39822003-01-10 03:49:02 +00004117time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004118{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004119 if (HASTZINFO(self)) {
4120 Py_XDECREF(self->tzinfo);
4121 }
4122 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004123}
4124
4125/*
Tim Peters855fe882002-12-22 03:43:39 +00004126 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004127 */
4128
Tim Peters2a799bf2002-12-16 20:18:38 +00004129/* These are all METH_NOARGS, so don't need to check the arglist. */
4130static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004131time_utcoffset(PyObject *self, PyObject *unused) {
4132 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004133}
4134
4135static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004136time_dst(PyObject *self, PyObject *unused) {
4137 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004138}
4139
4140static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004141time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004142 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004143}
4144
4145/*
Tim Peters37f39822003-01-10 03:49:02 +00004146 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004147 */
4148
4149static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004150time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004152 const char *type_name = Py_TYPE(self)->tp_name;
4153 int h = TIME_GET_HOUR(self);
4154 int m = TIME_GET_MINUTE(self);
4155 int s = TIME_GET_SECOND(self);
4156 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004157 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004158 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004160 if (us)
4161 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4162 type_name, h, m, s, us);
4163 else if (s)
4164 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4165 type_name, h, m, s);
4166 else
4167 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4168 if (result != NULL && HASTZINFO(self))
4169 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004170 if (result != NULL && fold)
4171 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004172 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004173}
4174
Tim Peters37f39822003-01-10 03:49:02 +00004175static PyObject *
4176time_str(PyDateTime_Time *self)
4177{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07004178 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00004179}
Tim Peters2a799bf2002-12-16 20:18:38 +00004180
4181static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004182time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004184 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004185 char *timespec = NULL;
4186 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004187 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004188 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004189 static char *specs[][2] = {
4190 {"hours", "%02d"},
4191 {"minutes", "%02d:%02d"},
4192 {"seconds", "%02d:%02d:%02d"},
4193 {"milliseconds", "%02d:%02d:%02d.%03d"},
4194 {"microseconds", "%02d:%02d:%02d.%06d"},
4195 };
4196 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004197
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004198 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4199 return NULL;
4200
4201 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4202 if (us == 0) {
4203 /* seconds */
4204 given_spec = 2;
4205 }
4206 else {
4207 /* microseconds */
4208 given_spec = 4;
4209 }
4210 }
4211 else {
4212 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4213 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4214 if (given_spec == 3) {
4215 /* milliseconds */
4216 us = us / 1000;
4217 }
4218 break;
4219 }
4220 }
4221 }
4222
4223 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4224 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4225 return NULL;
4226 }
4227 else {
4228 result = PyUnicode_FromFormat(specs[given_spec][1],
4229 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4230 TIME_GET_SECOND(self), us);
4231 }
Tim Peters37f39822003-01-10 03:49:02 +00004232
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004233 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004236 /* We need to append the UTC offset. */
4237 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4238 Py_None) < 0) {
4239 Py_DECREF(result);
4240 return NULL;
4241 }
4242 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4243 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004244}
4245
Tim Peters37f39822003-01-10 03:49:02 +00004246static PyObject *
4247time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4248{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004249 PyObject *result;
4250 PyObject *tuple;
4251 PyObject *format;
4252 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004254 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4255 &format))
4256 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004258 /* Python's strftime does insane things with the year part of the
4259 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004260 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004261 */
4262 tuple = Py_BuildValue("iiiiiiiii",
4263 1900, 1, 1, /* year, month, day */
4264 TIME_GET_HOUR(self),
4265 TIME_GET_MINUTE(self),
4266 TIME_GET_SECOND(self),
4267 0, 1, -1); /* weekday, daynum, dst */
4268 if (tuple == NULL)
4269 return NULL;
4270 assert(PyTuple_Size(tuple) == 9);
4271 result = wrap_strftime((PyObject *)self, format, tuple,
4272 Py_None);
4273 Py_DECREF(tuple);
4274 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004275}
Tim Peters2a799bf2002-12-16 20:18:38 +00004276
4277/*
4278 * Miscellaneous methods.
4279 */
4280
Tim Peters37f39822003-01-10 03:49:02 +00004281static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004282time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004283{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004284 PyObject *result = NULL;
4285 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004286 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004287
Brian Curtindfc80e32011-08-10 20:28:54 -05004288 if (! PyTime_Check(other))
4289 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004290
4291 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004292 diff = memcmp(((PyDateTime_Time *)self)->data,
4293 ((PyDateTime_Time *)other)->data,
4294 _PyDateTime_TIME_DATASIZE);
4295 return diff_to_bool(diff, op);
4296 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004297 offset1 = time_utcoffset(self, NULL);
4298 if (offset1 == NULL)
4299 return NULL;
4300 offset2 = time_utcoffset(other, NULL);
4301 if (offset2 == NULL)
4302 goto done;
4303 /* If they're both naive, or both aware and have the same offsets,
4304 * we get off cheap. Note that if they're both naive, offset1 ==
4305 * offset2 == Py_None at this point.
4306 */
4307 if ((offset1 == offset2) ||
4308 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4309 delta_cmp(offset1, offset2) == 0)) {
4310 diff = memcmp(((PyDateTime_Time *)self)->data,
4311 ((PyDateTime_Time *)other)->data,
4312 _PyDateTime_TIME_DATASIZE);
4313 result = diff_to_bool(diff, op);
4314 }
4315 /* The hard case: both aware with different UTC offsets */
4316 else if (offset1 != Py_None && offset2 != Py_None) {
4317 int offsecs1, offsecs2;
4318 assert(offset1 != offset2); /* else last "if" handled it */
4319 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4320 TIME_GET_MINUTE(self) * 60 +
4321 TIME_GET_SECOND(self) -
4322 GET_TD_DAYS(offset1) * 86400 -
4323 GET_TD_SECONDS(offset1);
4324 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4325 TIME_GET_MINUTE(other) * 60 +
4326 TIME_GET_SECOND(other) -
4327 GET_TD_DAYS(offset2) * 86400 -
4328 GET_TD_SECONDS(offset2);
4329 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004330 if (diff == 0)
4331 diff = TIME_GET_MICROSECOND(self) -
4332 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004333 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004334 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004335 else if (op == Py_EQ) {
4336 result = Py_False;
4337 Py_INCREF(result);
4338 }
4339 else if (op == Py_NE) {
4340 result = Py_True;
4341 Py_INCREF(result);
4342 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004343 else {
4344 PyErr_SetString(PyExc_TypeError,
4345 "can't compare offset-naive and "
4346 "offset-aware times");
4347 }
4348 done:
4349 Py_DECREF(offset1);
4350 Py_XDECREF(offset2);
4351 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004352}
4353
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004354static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004355time_hash(PyDateTime_Time *self)
4356{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004357 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004358 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004359 if (TIME_GET_FOLD(self)) {
4360 self0 = new_time_ex2(TIME_GET_HOUR(self),
4361 TIME_GET_MINUTE(self),
4362 TIME_GET_SECOND(self),
4363 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004364 HASTZINFO(self) ? self->tzinfo : Py_None,
4365 0, Py_TYPE(self));
4366 if (self0 == NULL)
4367 return -1;
4368 }
4369 else {
4370 self0 = (PyObject *)self;
4371 Py_INCREF(self0);
4372 }
4373 offset = time_utcoffset(self0, NULL);
4374 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004375
4376 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004377 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004379 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004380 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004381 self->hashcode = generic_hash(
4382 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004383 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004384 PyObject *temp1, *temp2;
4385 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004386 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004387 seconds = TIME_GET_HOUR(self) * 3600 +
4388 TIME_GET_MINUTE(self) * 60 +
4389 TIME_GET_SECOND(self);
4390 microseconds = TIME_GET_MICROSECOND(self);
4391 temp1 = new_delta(0, seconds, microseconds, 1);
4392 if (temp1 == NULL) {
4393 Py_DECREF(offset);
4394 return -1;
4395 }
4396 temp2 = delta_subtract(temp1, offset);
4397 Py_DECREF(temp1);
4398 if (temp2 == NULL) {
4399 Py_DECREF(offset);
4400 return -1;
4401 }
4402 self->hashcode = PyObject_Hash(temp2);
4403 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004404 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004405 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004406 }
4407 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004408}
Tim Peters2a799bf2002-12-16 20:18:38 +00004409
Tim Peters12bf3392002-12-24 05:41:27 +00004410static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004411time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004413 PyObject *clone;
4414 PyObject *tuple;
4415 int hh = TIME_GET_HOUR(self);
4416 int mm = TIME_GET_MINUTE(self);
4417 int ss = TIME_GET_SECOND(self);
4418 int us = TIME_GET_MICROSECOND(self);
4419 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004420 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004421
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004422 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004423 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004424 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004425 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004426 if (fold != 0 && fold != 1) {
4427 PyErr_SetString(PyExc_ValueError,
4428 "fold must be either 0 or 1");
4429 return NULL;
4430 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004431 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4432 if (tuple == NULL)
4433 return NULL;
4434 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004435 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004436 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004437 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004438 Py_DECREF(tuple);
4439 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004440}
4441
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004442static PyObject *
4443time_fromisoformat(PyObject *cls, PyObject *tstr) {
4444 assert(tstr != NULL);
4445
4446 if (!PyUnicode_Check(tstr)) {
4447 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4448 return NULL;
4449 }
4450
4451 Py_ssize_t len;
4452 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4453
Paul Ganssle096329f2018-08-23 11:06:20 -04004454 if (p == NULL) {
4455 goto invalid_string_error;
4456 }
4457
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004458 int hour = 0, minute = 0, second = 0, microsecond = 0;
4459 int tzoffset, tzimicrosecond = 0;
4460 int rv = parse_isoformat_time(p, len,
4461 &hour, &minute, &second, &microsecond,
4462 &tzoffset, &tzimicrosecond);
4463
4464 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04004465 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004466 }
4467
4468 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4469 tzimicrosecond);
4470
4471 if (tzinfo == NULL) {
4472 return NULL;
4473 }
4474
4475 PyObject *t;
4476 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4477 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4478 } else {
4479 t = PyObject_CallFunction(cls, "iiiiO",
4480 hour, minute, second, microsecond, tzinfo);
4481 }
4482
4483 Py_DECREF(tzinfo);
4484 return t;
Paul Ganssle096329f2018-08-23 11:06:20 -04004485
4486invalid_string_error:
4487 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4488 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004489}
4490
4491
Tim Peters371935f2003-02-01 01:52:50 +00004492/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004493
Tim Peters33e0f382003-01-10 02:05:14 +00004494/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004495 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4496 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004497 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004498 */
4499static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004500time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004502 PyObject *basestate;
4503 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004505 basestate = PyBytes_FromStringAndSize((char *)self->data,
4506 _PyDateTime_TIME_DATASIZE);
4507 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004508 if (proto > 3 && TIME_GET_FOLD(self))
4509 /* Set the first bit of the first byte */
4510 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004511 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4512 result = PyTuple_Pack(1, basestate);
4513 else
4514 result = PyTuple_Pack(2, basestate, self->tzinfo);
4515 Py_DECREF(basestate);
4516 }
4517 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004518}
4519
4520static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004521time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004522{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004523 int proto;
4524 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004525 return NULL;
4526
4527 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004528}
4529
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004530static PyObject *
4531time_reduce(PyDateTime_Time *self, PyObject *arg)
4532{
4533 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4534}
4535
Tim Peters37f39822003-01-10 03:49:02 +00004536static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004537
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004538 {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS,
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004539 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4540 "[+HH:MM].\n\n"
4541 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004542
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004543 {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004546 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4547 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004549 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4550 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004552 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4553 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004555 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4556 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004557
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004558 {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004559 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004560
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004561 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4562 PyDoc_STR("string -> time from time.isoformat() output")},
4563
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004564 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004565 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004566
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004567 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4568 PyDoc_STR("__reduce__() -> (cls, state)")},
4569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004570 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004571};
4572
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004573static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004574PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4575\n\
4576All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004577a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004578
Neal Norwitz227b5332006-03-22 09:28:35 +00004579static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004580 PyVarObject_HEAD_INIT(NULL, 0)
4581 "datetime.time", /* tp_name */
4582 sizeof(PyDateTime_Time), /* tp_basicsize */
4583 0, /* tp_itemsize */
4584 (destructor)time_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004585 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004586 0, /* tp_getattr */
4587 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004588 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004589 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004590 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004591 0, /* tp_as_sequence */
4592 0, /* tp_as_mapping */
4593 (hashfunc)time_hash, /* tp_hash */
4594 0, /* tp_call */
4595 (reprfunc)time_str, /* tp_str */
4596 PyObject_GenericGetAttr, /* tp_getattro */
4597 0, /* tp_setattro */
4598 0, /* tp_as_buffer */
4599 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4600 time_doc, /* tp_doc */
4601 0, /* tp_traverse */
4602 0, /* tp_clear */
4603 time_richcompare, /* tp_richcompare */
4604 0, /* tp_weaklistoffset */
4605 0, /* tp_iter */
4606 0, /* tp_iternext */
4607 time_methods, /* tp_methods */
4608 0, /* tp_members */
4609 time_getset, /* tp_getset */
4610 0, /* tp_base */
4611 0, /* tp_dict */
4612 0, /* tp_descr_get */
4613 0, /* tp_descr_set */
4614 0, /* tp_dictoffset */
4615 0, /* tp_init */
4616 time_alloc, /* tp_alloc */
4617 time_new, /* tp_new */
4618 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004619};
4620
4621/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004622 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004623 */
4624
Tim Petersa9bc1682003-01-11 03:39:11 +00004625/* Accessor properties. Properties for day, month, and year are inherited
4626 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004627 */
4628
4629static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004630datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004632 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004633}
4634
Tim Petersa9bc1682003-01-11 03:39:11 +00004635static PyObject *
4636datetime_minute(PyDateTime_DateTime *self, void *unused)
4637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004638 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004639}
4640
4641static PyObject *
4642datetime_second(PyDateTime_DateTime *self, void *unused)
4643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004644 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004645}
4646
4647static PyObject *
4648datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004650 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004651}
4652
4653static PyObject *
4654datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004656 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4657 Py_INCREF(result);
4658 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004659}
4660
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004661static PyObject *
4662datetime_fold(PyDateTime_DateTime *self, void *unused)
4663{
4664 return PyLong_FromLong(DATE_GET_FOLD(self));
4665}
4666
Tim Petersa9bc1682003-01-11 03:39:11 +00004667static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004668 {"hour", (getter)datetime_hour},
4669 {"minute", (getter)datetime_minute},
4670 {"second", (getter)datetime_second},
4671 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004672 {"tzinfo", (getter)datetime_tzinfo},
4673 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004674 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004675};
4676
4677/*
4678 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004679 */
4680
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004681static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004682 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004683 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004684};
4685
Tim Peters2a799bf2002-12-16 20:18:38 +00004686static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004687datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4688{
4689 PyDateTime_DateTime *me;
4690 char aware = (char)(tzinfo != Py_None);
4691
4692 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4693 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4694 return NULL;
4695 }
4696
4697 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4698 if (me != NULL) {
4699 const char *pdata = PyBytes_AS_STRING(state);
4700
4701 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4702 me->hashcode = -1;
4703 me->hastzinfo = aware;
4704 if (aware) {
4705 Py_INCREF(tzinfo);
4706 me->tzinfo = tzinfo;
4707 }
4708 if (pdata[2] & (1 << 7)) {
4709 me->data[2] -= 128;
4710 me->fold = 1;
4711 }
4712 else {
4713 me->fold = 0;
4714 }
4715 }
4716 return (PyObject *)me;
4717}
4718
4719static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004720datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004721{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004722 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004723 int year;
4724 int month;
4725 int day;
4726 int hour = 0;
4727 int minute = 0;
4728 int second = 0;
4729 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004730 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004731 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004733 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004734 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4735 PyObject *state = PyTuple_GET_ITEM(args, 0);
4736 if (PyTuple_GET_SIZE(args) == 2) {
4737 tzinfo = PyTuple_GET_ITEM(args, 1);
4738 }
4739 if (PyBytes_Check(state)) {
4740 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4741 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4742 {
4743 return datetime_from_pickle(type, state, tzinfo);
4744 }
4745 }
4746 else if (PyUnicode_Check(state)) {
4747 if (PyUnicode_READY(state)) {
4748 return NULL;
4749 }
4750 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4751 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4752 {
4753 state = PyUnicode_AsLatin1String(state);
4754 if (state == NULL) {
4755 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4756 /* More informative error message. */
4757 PyErr_SetString(PyExc_ValueError,
4758 "Failed to encode latin1 string when unpickling "
4759 "a datetime object. "
4760 "pickle.load(data, encoding='latin1') is assumed.");
4761 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004762 return NULL;
4763 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004764 self = datetime_from_pickle(type, state, tzinfo);
4765 Py_DECREF(state);
4766 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004767 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004768 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004769 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004770 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004771
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004772 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004773 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004774 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004775 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004776 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004777 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004778 }
4779 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004780}
4781
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004782/* TM_FUNC is the shared type of _PyTime_localtime() and
4783 * _PyTime_gmtime(). */
4784typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004785
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004786/* As of version 2015f max fold in IANA database is
4787 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004788static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004789/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004790static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004791
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004792static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004793utc_to_seconds(int year, int month, int day,
4794 int hour, int minute, int second)
4795{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004796 long long ordinal;
4797
4798 /* ymd_to_ord() doesn't support year <= 0 */
4799 if (year < MINYEAR || year > MAXYEAR) {
4800 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4801 return -1;
4802 }
4803
4804 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004805 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4806}
4807
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004808static long long
4809local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004810{
4811 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004812 time_t t;
4813 u -= epoch;
4814 t = u;
4815 if (t != u) {
4816 PyErr_SetString(PyExc_OverflowError,
4817 "timestamp out of range for platform time_t");
4818 return -1;
4819 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004820 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004821 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004822 return utc_to_seconds(local_time.tm_year + 1900,
4823 local_time.tm_mon + 1,
4824 local_time.tm_mday,
4825 local_time.tm_hour,
4826 local_time.tm_min,
4827 local_time.tm_sec);
4828}
4829
Tim Petersa9bc1682003-01-11 03:39:11 +00004830/* Internal helper.
4831 * Build datetime from a time_t and a distinct count of microseconds.
4832 * Pass localtime or gmtime for f, to control the interpretation of timet.
4833 */
4834static PyObject *
4835datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004836 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004837{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004838 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004839 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004840
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004841 if (f(timet, &tm) != 0)
4842 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004843
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004844 year = tm.tm_year + 1900;
4845 month = tm.tm_mon + 1;
4846 day = tm.tm_mday;
4847 hour = tm.tm_hour;
4848 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004849 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004850 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004851 * except to the extent that passing them on to the datetime
4852 * constructor would raise ValueError for a reason that
4853 * made no sense to the user.
4854 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004855 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004856
Victor Stinnerb67f0962017-02-10 10:34:02 +01004857 /* local timezone requires to compute fold */
Ammar Askar96d1e692018-07-25 09:54:58 -07004858 if (tzinfo == Py_None && f == _PyTime_localtime
4859 /* On Windows, passing a negative value to local results
4860 * in an OSError because localtime_s on Windows does
4861 * not support negative timestamps. Unfortunately this
4862 * means that fold detection for time values between
4863 * 0 and max_fold_seconds will result in an identical
4864 * error since we subtract max_fold_seconds to detect a
4865 * fold. However, since we know there haven't been any
4866 * folds in the interval [0, max_fold_seconds) in any
4867 * timezone, we can hackily just forego fold detection
4868 * for this time range.
4869 */
4870#ifdef MS_WINDOWS
4871 && (timet - max_fold_seconds > 0)
4872#endif
4873 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004874 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004875
4876 result_seconds = utc_to_seconds(year, month, day,
4877 hour, minute, second);
4878 /* Probe max_fold_seconds to detect a fold. */
4879 probe_seconds = local(epoch + timet - max_fold_seconds);
4880 if (probe_seconds == -1)
4881 return NULL;
4882 transition = result_seconds - probe_seconds - max_fold_seconds;
4883 if (transition < 0) {
4884 probe_seconds = local(epoch + timet + transition);
4885 if (probe_seconds == -1)
4886 return NULL;
4887 if (probe_seconds == result_seconds)
4888 fold = 1;
4889 }
4890 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004891 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4892 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004893}
4894
4895/* Internal helper.
4896 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4897 * to control the interpretation of the timestamp. Since a double doesn't
4898 * have enough bits to cover a datetime's full range of precision, it's
4899 * better to call datetime_from_timet_and_us provided you have a way
4900 * to get that much precision (e.g., C time() isn't good enough).
4901 */
4902static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004903datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004904 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004906 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004907 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004908
Victor Stinnere4a994d2015-03-30 01:10:14 +02004909 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004910 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004911 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004912
Victor Stinner21f58932012-03-14 00:15:40 +01004913 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004914}
4915
4916/* Internal helper.
4917 * Build most accurate possible datetime for current time. Pass localtime or
4918 * gmtime for f as appropriate.
4919 */
4920static PyObject *
4921datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4922{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004923 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004924 time_t secs;
4925 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004926
Victor Stinner1e2b6882015-09-18 13:23:02 +02004927 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004928 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004929 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004930
Victor Stinner1e2b6882015-09-18 13:23:02 +02004931 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004932}
4933
Larry Hastings61272b72014-01-07 12:41:53 -08004934/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004935
4936@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004937datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004938
4939 tz: object = None
4940 Timezone object.
4941
4942Returns new datetime object representing current time local to tz.
4943
4944If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004945[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004946
Larry Hastings31826802013-10-19 00:09:25 -07004947static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004948datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004949/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004951 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004952
Larry Hastings31826802013-10-19 00:09:25 -07004953 /* Return best possible local time -- this isn't constrained by the
4954 * precision of a timestamp.
4955 */
4956 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004957 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004958
Larry Hastings5c661892014-01-24 06:17:25 -08004959 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004960 tz == Py_None ? _PyTime_localtime :
4961 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004962 tz);
4963 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004964 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004965 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004966 }
4967 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004968}
4969
Tim Petersa9bc1682003-01-11 03:39:11 +00004970/* Return best possible UTC time -- this isn't constrained by the
4971 * precision of a timestamp.
4972 */
4973static PyObject *
4974datetime_utcnow(PyObject *cls, PyObject *dummy)
4975{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004976 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004977}
4978
Tim Peters2a799bf2002-12-16 20:18:38 +00004979/* Return new local datetime from timestamp (Python timestamp -- a double). */
4980static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004981datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004983 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004984 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004985 PyObject *tzinfo = Py_None;
4986 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004987
Victor Stinner5d272cc2012-03-13 13:35:55 +01004988 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004989 keywords, &timestamp, &tzinfo))
4990 return NULL;
4991 if (check_tzinfo_subclass(tzinfo) < 0)
4992 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004994 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004995 tzinfo == Py_None ? _PyTime_localtime :
4996 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004997 timestamp,
4998 tzinfo);
4999 if (self != NULL && tzinfo != Py_None) {
5000 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02005001 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005002 }
5003 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005004}
5005
Tim Petersa9bc1682003-01-11 03:39:11 +00005006/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
5007static PyObject *
5008datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
5009{
Victor Stinner5d272cc2012-03-13 13:35:55 +01005010 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005011 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005012
Victor Stinner5d272cc2012-03-13 13:35:55 +01005013 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005014 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005015 Py_None);
5016 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005017}
5018
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005019/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005020static PyObject *
5021datetime_strptime(PyObject *cls, PyObject *args)
5022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005023 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005024 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02005025 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005026
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005027 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005028 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005029
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005030 if (module == NULL) {
5031 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00005032 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005033 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005034 }
Victor Stinner20401de2016-12-09 15:24:31 +01005035 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
5036 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005037}
5038
Tim Petersa9bc1682003-01-11 03:39:11 +00005039/* Return new datetime from date/datetime and time arguments. */
5040static PyObject *
5041datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
5042{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005043 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005044 PyObject *date;
5045 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005046 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005047 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00005048
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005049 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005050 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005051 &PyDateTime_TimeType, &time, &tzinfo)) {
5052 if (tzinfo == NULL) {
5053 if (HASTZINFO(time))
5054 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
5055 else
5056 tzinfo = Py_None;
5057 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005058 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
5059 GET_MONTH(date),
5060 GET_DAY(date),
5061 TIME_GET_HOUR(time),
5062 TIME_GET_MINUTE(time),
5063 TIME_GET_SECOND(time),
5064 TIME_GET_MICROSECOND(time),
5065 tzinfo,
5066 TIME_GET_FOLD(time),
5067 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005068 }
5069 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005070}
Tim Peters2a799bf2002-12-16 20:18:38 +00005071
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005072static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005073_sanitize_isoformat_str(PyObject *dtstr)
5074{
Paul Ganssle096329f2018-08-23 11:06:20 -04005075 // `fromisoformat` allows surrogate characters in exactly one position,
5076 // the separator; to allow datetime_fromisoformat to make the simplifying
5077 // assumption that all valid strings can be encoded in UTF-8, this function
5078 // replaces any surrogate character separators with `T`.
Paul Ganssle3df85402018-10-22 12:32:52 -04005079 //
5080 // The result of this, if not NULL, returns a new reference
Paul Ganssle096329f2018-08-23 11:06:20 -04005081 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005082 if (len < 0) {
5083 return NULL;
5084 }
5085
5086 if (len <= 10 ||
5087 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
5088 Py_INCREF(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005089 return dtstr;
5090 }
5091
Paul Ganssle3df85402018-10-22 12:32:52 -04005092 PyObject *str_out = _PyUnicode_Copy(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005093 if (str_out == NULL) {
5094 return NULL;
5095 }
5096
Paul Ganssle3df85402018-10-22 12:32:52 -04005097 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005098 Py_DECREF(str_out);
5099 return NULL;
5100 }
5101
Paul Ganssle096329f2018-08-23 11:06:20 -04005102 return str_out;
5103}
5104
5105static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005106datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5107{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005108 assert(dtstr != NULL);
5109
5110 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005111 PyErr_SetString(PyExc_TypeError,
5112 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005113 return NULL;
5114 }
5115
Paul Ganssle3df85402018-10-22 12:32:52 -04005116 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5117 if (dtstr_clean == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005118 goto error;
5119 }
5120
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005121 Py_ssize_t len;
Paul Ganssle3df85402018-10-22 12:32:52 -04005122 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04005123
5124 if (dt_ptr == NULL) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005125 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5126 // Encoding errors are invalid string errors at this point
5127 goto invalid_string_error;
5128 }
5129 else {
5130 goto error;
5131 }
Paul Ganssle096329f2018-08-23 11:06:20 -04005132 }
5133
5134 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005135
5136 int year = 0, month = 0, day = 0;
5137 int hour = 0, minute = 0, second = 0, microsecond = 0;
5138 int tzoffset = 0, tzusec = 0;
5139
5140 // date has a fixed length of 10
5141 int rv = parse_isoformat_date(p, &year, &month, &day);
5142
5143 if (!rv && len > 10) {
5144 // In UTF-8, the length of multi-byte characters is encoded in the MSB
5145 if ((p[10] & 0x80) == 0) {
5146 p += 11;
Paul Ganssle3df85402018-10-22 12:32:52 -04005147 }
5148 else {
5149 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005150 case 0xe0:
5151 p += 13;
5152 break;
5153 case 0xf0:
5154 p += 14;
5155 break;
5156 default:
5157 p += 12;
5158 break;
5159 }
5160 }
5161
5162 len -= (p - dt_ptr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005163 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5164 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005165 }
5166 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005167 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005168 }
5169
Paul Ganssle3df85402018-10-22 12:32:52 -04005170 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005171 if (tzinfo == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005172 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005173 }
5174
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005175 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5176 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005177
5178 Py_DECREF(tzinfo);
Paul Ganssle3df85402018-10-22 12:32:52 -04005179 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005180 return dt;
Paul Ganssle096329f2018-08-23 11:06:20 -04005181
5182invalid_string_error:
5183 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5184
5185error:
Paul Ganssle3df85402018-10-22 12:32:52 -04005186 Py_XDECREF(dtstr_clean);
Paul Ganssle096329f2018-08-23 11:06:20 -04005187
5188 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005189}
5190
Tim Peters2a799bf2002-12-16 20:18:38 +00005191/*
5192 * Destructor.
5193 */
5194
5195static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005196datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005197{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005198 if (HASTZINFO(self)) {
5199 Py_XDECREF(self->tzinfo);
5200 }
5201 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005202}
5203
5204/*
5205 * Indirect access to tzinfo methods.
5206 */
5207
Tim Peters2a799bf2002-12-16 20:18:38 +00005208/* These are all METH_NOARGS, so don't need to check the arglist. */
5209static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005210datetime_utcoffset(PyObject *self, PyObject *unused) {
5211 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005212}
5213
5214static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005215datetime_dst(PyObject *self, PyObject *unused) {
5216 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005217}
5218
5219static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005220datetime_tzname(PyObject *self, PyObject *unused) {
5221 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005222}
5223
5224/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005225 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005226 */
5227
Tim Petersa9bc1682003-01-11 03:39:11 +00005228/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5229 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005230 */
5231static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005232add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005233 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005235 /* Note that the C-level additions can't overflow, because of
5236 * invariant bounds on the member values.
5237 */
5238 int year = GET_YEAR(date);
5239 int month = GET_MONTH(date);
5240 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5241 int hour = DATE_GET_HOUR(date);
5242 int minute = DATE_GET_MINUTE(date);
5243 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5244 int microsecond = DATE_GET_MICROSECOND(date) +
5245 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005247 assert(factor == 1 || factor == -1);
5248 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005249 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005250 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005251 }
5252
Paul Ganssle89427cd2019-02-04 14:42:04 -05005253 return new_datetime_subclass_ex(year, month, day,
5254 hour, minute, second, microsecond,
5255 HASTZINFO(date) ? date->tzinfo : Py_None,
5256 (PyObject *)Py_TYPE(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00005257}
5258
5259static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005260datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005262 if (PyDateTime_Check(left)) {
5263 /* datetime + ??? */
5264 if (PyDelta_Check(right))
5265 /* datetime + delta */
5266 return add_datetime_timedelta(
5267 (PyDateTime_DateTime *)left,
5268 (PyDateTime_Delta *)right,
5269 1);
5270 }
5271 else if (PyDelta_Check(left)) {
5272 /* delta + datetime */
5273 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5274 (PyDateTime_Delta *) left,
5275 1);
5276 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005277 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005278}
5279
5280static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005281datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005282{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005283 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005285 if (PyDateTime_Check(left)) {
5286 /* datetime - ??? */
5287 if (PyDateTime_Check(right)) {
5288 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005289 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005290 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005291
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005292 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5293 offset2 = offset1 = Py_None;
5294 Py_INCREF(offset1);
5295 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005296 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005297 else {
5298 offset1 = datetime_utcoffset(left, NULL);
5299 if (offset1 == NULL)
5300 return NULL;
5301 offset2 = datetime_utcoffset(right, NULL);
5302 if (offset2 == NULL) {
5303 Py_DECREF(offset1);
5304 return NULL;
5305 }
5306 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5307 PyErr_SetString(PyExc_TypeError,
5308 "can't subtract offset-naive and "
5309 "offset-aware datetimes");
5310 Py_DECREF(offset1);
5311 Py_DECREF(offset2);
5312 return NULL;
5313 }
5314 }
5315 if ((offset1 != offset2) &&
5316 delta_cmp(offset1, offset2) != 0) {
5317 offdiff = delta_subtract(offset1, offset2);
5318 if (offdiff == NULL) {
5319 Py_DECREF(offset1);
5320 Py_DECREF(offset2);
5321 return NULL;
5322 }
5323 }
5324 Py_DECREF(offset1);
5325 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005326 delta_d = ymd_to_ord(GET_YEAR(left),
5327 GET_MONTH(left),
5328 GET_DAY(left)) -
5329 ymd_to_ord(GET_YEAR(right),
5330 GET_MONTH(right),
5331 GET_DAY(right));
5332 /* These can't overflow, since the values are
5333 * normalized. At most this gives the number of
5334 * seconds in one day.
5335 */
5336 delta_s = (DATE_GET_HOUR(left) -
5337 DATE_GET_HOUR(right)) * 3600 +
5338 (DATE_GET_MINUTE(left) -
5339 DATE_GET_MINUTE(right)) * 60 +
5340 (DATE_GET_SECOND(left) -
5341 DATE_GET_SECOND(right));
5342 delta_us = DATE_GET_MICROSECOND(left) -
5343 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005344 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005345 if (result == NULL)
5346 return NULL;
5347
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005348 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005349 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005350 Py_DECREF(offdiff);
5351 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005352 }
5353 else if (PyDelta_Check(right)) {
5354 /* datetime - delta */
5355 result = add_datetime_timedelta(
5356 (PyDateTime_DateTime *)left,
5357 (PyDateTime_Delta *)right,
5358 -1);
5359 }
5360 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005362 if (result == Py_NotImplemented)
5363 Py_INCREF(result);
5364 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005365}
5366
5367/* Various ways to turn a datetime into a string. */
5368
5369static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005370datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005372 const char *type_name = Py_TYPE(self)->tp_name;
5373 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005375 if (DATE_GET_MICROSECOND(self)) {
5376 baserepr = PyUnicode_FromFormat(
5377 "%s(%d, %d, %d, %d, %d, %d, %d)",
5378 type_name,
5379 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5380 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5381 DATE_GET_SECOND(self),
5382 DATE_GET_MICROSECOND(self));
5383 }
5384 else if (DATE_GET_SECOND(self)) {
5385 baserepr = PyUnicode_FromFormat(
5386 "%s(%d, %d, %d, %d, %d, %d)",
5387 type_name,
5388 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5389 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5390 DATE_GET_SECOND(self));
5391 }
5392 else {
5393 baserepr = PyUnicode_FromFormat(
5394 "%s(%d, %d, %d, %d, %d)",
5395 type_name,
5396 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5397 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5398 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005399 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5400 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005401 if (baserepr == NULL || ! HASTZINFO(self))
5402 return baserepr;
5403 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005404}
5405
Tim Petersa9bc1682003-01-11 03:39:11 +00005406static PyObject *
5407datetime_str(PyDateTime_DateTime *self)
5408{
Victor Stinner4c381542016-12-09 00:33:39 +01005409 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005410}
Tim Peters2a799bf2002-12-16 20:18:38 +00005411
5412static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005413datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005415 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005416 char *timespec = NULL;
5417 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005418 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005419 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005420 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005421 static char *specs[][2] = {
5422 {"hours", "%04d-%02d-%02d%c%02d"},
5423 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5424 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5425 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5426 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5427 };
5428 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005429
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005430 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005431 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005432
5433 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5434 if (us == 0) {
5435 /* seconds */
5436 given_spec = 2;
5437 }
5438 else {
5439 /* microseconds */
5440 given_spec = 4;
5441 }
5442 }
5443 else {
5444 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5445 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5446 if (given_spec == 3) {
5447 us = us / 1000;
5448 }
5449 break;
5450 }
5451 }
5452 }
5453
5454 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5455 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5456 return NULL;
5457 }
5458 else {
5459 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005460 GET_YEAR(self), GET_MONTH(self),
5461 GET_DAY(self), (int)sep,
5462 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5463 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005464 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005466 if (!result || !HASTZINFO(self))
5467 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005469 /* We need to append the UTC offset. */
5470 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5471 (PyObject *)self) < 0) {
5472 Py_DECREF(result);
5473 return NULL;
5474 }
5475 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5476 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005477}
5478
Tim Petersa9bc1682003-01-11 03:39:11 +00005479static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305480datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005482 return format_ctime((PyDateTime_Date *)self,
5483 DATE_GET_HOUR(self),
5484 DATE_GET_MINUTE(self),
5485 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005486}
5487
Tim Peters2a799bf2002-12-16 20:18:38 +00005488/* Miscellaneous methods. */
5489
Tim Petersa9bc1682003-01-11 03:39:11 +00005490static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005491flip_fold(PyObject *dt)
5492{
5493 return new_datetime_ex2(GET_YEAR(dt),
5494 GET_MONTH(dt),
5495 GET_DAY(dt),
5496 DATE_GET_HOUR(dt),
5497 DATE_GET_MINUTE(dt),
5498 DATE_GET_SECOND(dt),
5499 DATE_GET_MICROSECOND(dt),
5500 HASTZINFO(dt) ?
5501 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5502 !DATE_GET_FOLD(dt),
5503 Py_TYPE(dt));
5504}
5505
5506static PyObject *
5507get_flip_fold_offset(PyObject *dt)
5508{
5509 PyObject *result, *flip_dt;
5510
5511 flip_dt = flip_fold(dt);
5512 if (flip_dt == NULL)
5513 return NULL;
5514 result = datetime_utcoffset(flip_dt, NULL);
5515 Py_DECREF(flip_dt);
5516 return result;
5517}
5518
5519/* PEP 495 exception: Whenever one or both of the operands in
5520 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakabac2d5b2018-03-28 22:14:26 +03005521 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005522 *
5523 * Return 1 if exception applies, 0 if not, and -1 on error.
5524 */
5525static int
5526pep495_eq_exception(PyObject *self, PyObject *other,
5527 PyObject *offset_self, PyObject *offset_other)
5528{
5529 int result = 0;
5530 PyObject *flip_offset;
5531
5532 flip_offset = get_flip_fold_offset(self);
5533 if (flip_offset == NULL)
5534 return -1;
5535 if (flip_offset != offset_self &&
5536 delta_cmp(flip_offset, offset_self))
5537 {
5538 result = 1;
5539 goto done;
5540 }
5541 Py_DECREF(flip_offset);
5542
5543 flip_offset = get_flip_fold_offset(other);
5544 if (flip_offset == NULL)
5545 return -1;
5546 if (flip_offset != offset_other &&
5547 delta_cmp(flip_offset, offset_other))
5548 result = 1;
5549 done:
5550 Py_DECREF(flip_offset);
5551 return result;
5552}
5553
5554static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005555datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005556{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005557 PyObject *result = NULL;
5558 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005559 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005561 if (! PyDateTime_Check(other)) {
5562 if (PyDate_Check(other)) {
5563 /* Prevent invocation of date_richcompare. We want to
5564 return NotImplemented here to give the other object
5565 a chance. But since DateTime is a subclass of
5566 Date, if the other object is a Date, it would
5567 compute an ordering based on the date part alone,
5568 and we don't want that. So force unequal or
5569 uncomparable here in that case. */
5570 if (op == Py_EQ)
5571 Py_RETURN_FALSE;
5572 if (op == Py_NE)
5573 Py_RETURN_TRUE;
5574 return cmperror(self, other);
5575 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005576 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005577 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005578
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005579 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005580 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5581 ((PyDateTime_DateTime *)other)->data,
5582 _PyDateTime_DATETIME_DATASIZE);
5583 return diff_to_bool(diff, op);
5584 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005585 offset1 = datetime_utcoffset(self, NULL);
5586 if (offset1 == NULL)
5587 return NULL;
5588 offset2 = datetime_utcoffset(other, NULL);
5589 if (offset2 == NULL)
5590 goto done;
5591 /* If they're both naive, or both aware and have the same offsets,
5592 * we get off cheap. Note that if they're both naive, offset1 ==
5593 * offset2 == Py_None at this point.
5594 */
5595 if ((offset1 == offset2) ||
5596 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5597 delta_cmp(offset1, offset2) == 0)) {
5598 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5599 ((PyDateTime_DateTime *)other)->data,
5600 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005601 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5602 int ex = pep495_eq_exception(self, other, offset1, offset2);
5603 if (ex == -1)
5604 goto done;
5605 if (ex)
5606 diff = 1;
5607 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005608 result = diff_to_bool(diff, op);
5609 }
5610 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005611 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005612
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005613 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005614 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5615 other);
5616 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005617 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005618 diff = GET_TD_DAYS(delta);
5619 if (diff == 0)
5620 diff = GET_TD_SECONDS(delta) |
5621 GET_TD_MICROSECONDS(delta);
5622 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005623 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5624 int ex = pep495_eq_exception(self, other, offset1, offset2);
5625 if (ex == -1)
5626 goto done;
5627 if (ex)
5628 diff = 1;
5629 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005630 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005631 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005632 else if (op == Py_EQ) {
5633 result = Py_False;
5634 Py_INCREF(result);
5635 }
5636 else if (op == Py_NE) {
5637 result = Py_True;
5638 Py_INCREF(result);
5639 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005640 else {
5641 PyErr_SetString(PyExc_TypeError,
5642 "can't compare offset-naive and "
5643 "offset-aware datetimes");
5644 }
5645 done:
5646 Py_DECREF(offset1);
5647 Py_XDECREF(offset2);
5648 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005649}
5650
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005651static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005652datetime_hash(PyDateTime_DateTime *self)
5653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005654 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005655 PyObject *offset, *self0;
5656 if (DATE_GET_FOLD(self)) {
5657 self0 = new_datetime_ex2(GET_YEAR(self),
5658 GET_MONTH(self),
5659 GET_DAY(self),
5660 DATE_GET_HOUR(self),
5661 DATE_GET_MINUTE(self),
5662 DATE_GET_SECOND(self),
5663 DATE_GET_MICROSECOND(self),
5664 HASTZINFO(self) ? self->tzinfo : Py_None,
5665 0, Py_TYPE(self));
5666 if (self0 == NULL)
5667 return -1;
5668 }
5669 else {
5670 self0 = (PyObject *)self;
5671 Py_INCREF(self0);
5672 }
5673 offset = datetime_utcoffset(self0, NULL);
5674 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005675
5676 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005677 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005679 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005680 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005681 self->hashcode = generic_hash(
5682 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005683 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005684 PyObject *temp1, *temp2;
5685 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005687 assert(HASTZINFO(self));
5688 days = ymd_to_ord(GET_YEAR(self),
5689 GET_MONTH(self),
5690 GET_DAY(self));
5691 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005692 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005693 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005694 temp1 = new_delta(days, seconds,
5695 DATE_GET_MICROSECOND(self),
5696 1);
5697 if (temp1 == NULL) {
5698 Py_DECREF(offset);
5699 return -1;
5700 }
5701 temp2 = delta_subtract(temp1, offset);
5702 Py_DECREF(temp1);
5703 if (temp2 == NULL) {
5704 Py_DECREF(offset);
5705 return -1;
5706 }
5707 self->hashcode = PyObject_Hash(temp2);
5708 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005709 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005710 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005711 }
5712 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005713}
Tim Peters2a799bf2002-12-16 20:18:38 +00005714
5715static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005716datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005717{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005718 PyObject *clone;
5719 PyObject *tuple;
5720 int y = GET_YEAR(self);
5721 int m = GET_MONTH(self);
5722 int d = GET_DAY(self);
5723 int hh = DATE_GET_HOUR(self);
5724 int mm = DATE_GET_MINUTE(self);
5725 int ss = DATE_GET_SECOND(self);
5726 int us = DATE_GET_MICROSECOND(self);
5727 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005728 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005729
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005730 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005731 datetime_kws,
5732 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005733 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005734 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005735 if (fold != 0 && fold != 1) {
5736 PyErr_SetString(PyExc_ValueError,
5737 "fold must be either 0 or 1");
5738 return NULL;
5739 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005740 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5741 if (tuple == NULL)
5742 return NULL;
5743 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005744 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005745 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005746 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005747 Py_DECREF(tuple);
5748 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005749}
5750
5751static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005752local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005753{
5754 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005755 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005756 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005757 PyObject *nameo = NULL;
5758 const char *zone = NULL;
5759
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005760 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005761 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005762#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005763 zone = local_time_tm.tm_zone;
5764 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005765#else /* HAVE_STRUCT_TM_TM_ZONE */
5766 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005767 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005768 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005769 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005770 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005771 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005772 local_time = new_datetime(local_time_tm.tm_year + 1900,
5773 local_time_tm.tm_mon + 1,
5774 local_time_tm.tm_mday,
5775 local_time_tm.tm_hour,
5776 local_time_tm.tm_min,
5777 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005778 if (local_time == NULL) {
5779 return NULL;
5780 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005781 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005782 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005783 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5784 utc_time_tm.tm_mon + 1,
5785 utc_time_tm.tm_mday,
5786 utc_time_tm.tm_hour,
5787 utc_time_tm.tm_min,
5788 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005789 if (utc_time == NULL) {
5790 Py_DECREF(local_time);
5791 return NULL;
5792 }
5793 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005794 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005795 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005796 }
5797#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005798 if (delta == NULL) {
5799 return NULL;
5800 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005801 if (zone != NULL) {
5802 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5803 if (nameo == NULL)
5804 goto error;
5805 }
5806 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005807 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005808 error:
5809 Py_DECREF(delta);
5810 return result;
5811}
5812
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005813static PyObject *
5814local_timezone(PyDateTime_DateTime *utc_time)
5815{
5816 time_t timestamp;
5817 PyObject *delta;
5818 PyObject *one_second;
5819 PyObject *seconds;
5820
5821 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5822 if (delta == NULL)
5823 return NULL;
5824 one_second = new_delta(0, 1, 0, 0);
5825 if (one_second == NULL) {
5826 Py_DECREF(delta);
5827 return NULL;
5828 }
5829 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5830 (PyDateTime_Delta *)one_second);
5831 Py_DECREF(one_second);
5832 Py_DECREF(delta);
5833 if (seconds == NULL)
5834 return NULL;
5835 timestamp = _PyLong_AsTime_t(seconds);
5836 Py_DECREF(seconds);
5837 if (timestamp == -1 && PyErr_Occurred())
5838 return NULL;
5839 return local_timezone_from_timestamp(timestamp);
5840}
5841
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005842static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005843local_to_seconds(int year, int month, int day,
5844 int hour, int minute, int second, int fold);
5845
5846static PyObject *
5847local_timezone_from_local(PyDateTime_DateTime *local_dt)
5848{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005849 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005850 time_t timestamp;
5851 seconds = local_to_seconds(GET_YEAR(local_dt),
5852 GET_MONTH(local_dt),
5853 GET_DAY(local_dt),
5854 DATE_GET_HOUR(local_dt),
5855 DATE_GET_MINUTE(local_dt),
5856 DATE_GET_SECOND(local_dt),
5857 DATE_GET_FOLD(local_dt));
5858 if (seconds == -1)
5859 return NULL;
5860 /* XXX: add bounds check */
5861 timestamp = seconds - epoch;
5862 return local_timezone_from_timestamp(timestamp);
5863}
5864
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005865static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005866datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005867{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005868 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005869 PyObject *offset;
5870 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005871 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005872 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005873 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005874
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005875 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005876 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005877 return NULL;
5878
5879 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005880 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005881
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005882 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005883 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005884 self_tzinfo = local_timezone_from_local(self);
5885 if (self_tzinfo == NULL)
5886 return NULL;
5887 } else {
5888 self_tzinfo = self->tzinfo;
5889 Py_INCREF(self_tzinfo);
5890 }
Tim Peters521fc152002-12-31 17:36:56 +00005891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005892 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005893 if (self_tzinfo == tzinfo) {
5894 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005895 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005896 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005897 }
Tim Peters521fc152002-12-31 17:36:56 +00005898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005899 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005900 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5901 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005902 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005903 return NULL;
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005904 else if(offset == Py_None) {
5905 Py_DECREF(offset);
5906 goto naive;
5907 }
5908 else if (!PyDelta_Check(offset)) {
5909 Py_DECREF(offset);
5910 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5911 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5912 return NULL;
5913 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005914 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005915 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5916 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005917 Py_DECREF(offset);
5918 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005919 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005920
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005921 /* Make sure result is aware and UTC. */
5922 if (!HASTZINFO(result)) {
5923 temp = (PyObject *)result;
5924 result = (PyDateTime_DateTime *)
5925 new_datetime_ex2(GET_YEAR(result),
5926 GET_MONTH(result),
5927 GET_DAY(result),
5928 DATE_GET_HOUR(result),
5929 DATE_GET_MINUTE(result),
5930 DATE_GET_SECOND(result),
5931 DATE_GET_MICROSECOND(result),
5932 PyDateTime_TimeZone_UTC,
5933 DATE_GET_FOLD(result),
5934 Py_TYPE(result));
5935 Py_DECREF(temp);
5936 if (result == NULL)
5937 return NULL;
5938 }
5939 else {
5940 /* Result is already aware - just replace tzinfo. */
5941 temp = result->tzinfo;
5942 result->tzinfo = PyDateTime_TimeZone_UTC;
5943 Py_INCREF(result->tzinfo);
5944 Py_DECREF(temp);
5945 }
5946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005947 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005948 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005949 if (tzinfo == Py_None) {
5950 tzinfo = local_timezone(result);
5951 if (tzinfo == NULL) {
5952 Py_DECREF(result);
5953 return NULL;
5954 }
5955 }
5956 else
5957 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005958 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005959 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005960
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005961 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005962 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005963 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005964 Py_DECREF(temp);
5965
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005966 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005967}
5968
5969static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305970datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00005971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005972 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005974 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005975 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005976
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005977 dst = call_dst(self->tzinfo, (PyObject *)self);
5978 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005979 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005980
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005981 if (dst != Py_None)
5982 dstflag = delta_bool((PyDateTime_Delta *)dst);
5983 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005984 }
5985 return build_struct_time(GET_YEAR(self),
5986 GET_MONTH(self),
5987 GET_DAY(self),
5988 DATE_GET_HOUR(self),
5989 DATE_GET_MINUTE(self),
5990 DATE_GET_SECOND(self),
5991 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005992}
5993
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005994static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005995local_to_seconds(int year, int month, int day,
5996 int hour, int minute, int second, int fold)
5997{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005998 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005999 t = utc_to_seconds(year, month, day, hour, minute, second);
6000 /* Our goal is to solve t = local(u) for u. */
6001 lt = local(t);
6002 if (lt == -1)
6003 return -1;
6004 a = lt - t;
6005 u1 = t - a;
6006 t1 = local(u1);
6007 if (t1 == -1)
6008 return -1;
6009 if (t1 == t) {
6010 /* We found one solution, but it may not be the one we need.
6011 * Look for an earlier solution (if `fold` is 0), or a
6012 * later one (if `fold` is 1). */
6013 if (fold)
6014 u2 = u1 + max_fold_seconds;
6015 else
6016 u2 = u1 - max_fold_seconds;
6017 lt = local(u2);
6018 if (lt == -1)
6019 return -1;
6020 b = lt - u2;
6021 if (a == b)
6022 return u1;
6023 }
6024 else {
6025 b = t1 - u1;
6026 assert(a != b);
6027 }
6028 u2 = t - b;
6029 t2 = local(u2);
6030 if (t2 == -1)
6031 return -1;
6032 if (t2 == t)
6033 return u2;
6034 if (t1 == t)
6035 return u1;
6036 /* We have found both offsets a and b, but neither t - a nor t - b is
6037 * a solution. This means t is in the gap. */
6038 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
6039}
6040
6041/* date(1970,1,1).toordinal() == 719163 */
6042#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
6043
Tim Peters2a799bf2002-12-16 20:18:38 +00006044static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306045datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolskya4415142012-06-08 12:33:09 -04006046{
6047 PyObject *result;
6048
6049 if (HASTZINFO(self) && self->tzinfo != Py_None) {
6050 PyObject *delta;
6051 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
6052 if (delta == NULL)
6053 return NULL;
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306054 result = delta_total_seconds(delta, NULL);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006055 Py_DECREF(delta);
6056 }
6057 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006058 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006059 seconds = local_to_seconds(GET_YEAR(self),
6060 GET_MONTH(self),
6061 GET_DAY(self),
6062 DATE_GET_HOUR(self),
6063 DATE_GET_MINUTE(self),
6064 DATE_GET_SECOND(self),
6065 DATE_GET_FOLD(self));
6066 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04006067 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006068 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
6069 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006070 }
6071 return result;
6072}
6073
6074static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306075datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006077 return new_date(GET_YEAR(self),
6078 GET_MONTH(self),
6079 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006080}
6081
6082static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306083datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006085 return new_time(DATE_GET_HOUR(self),
6086 DATE_GET_MINUTE(self),
6087 DATE_GET_SECOND(self),
6088 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006089 Py_None,
6090 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006091}
6092
6093static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306094datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006096 return new_time(DATE_GET_HOUR(self),
6097 DATE_GET_MINUTE(self),
6098 DATE_GET_SECOND(self),
6099 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006100 GET_DT_TZINFO(self),
6101 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006102}
6103
6104static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306105datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006106{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006107 int y, m, d, hh, mm, ss;
6108 PyObject *tzinfo;
6109 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006110
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006111 tzinfo = GET_DT_TZINFO(self);
6112 if (tzinfo == Py_None) {
6113 utcself = self;
6114 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006115 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006116 else {
6117 PyObject *offset;
6118 offset = call_utcoffset(tzinfo, (PyObject *)self);
6119 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006120 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006121 if (offset == Py_None) {
6122 Py_DECREF(offset);
6123 utcself = self;
6124 Py_INCREF(utcself);
6125 }
6126 else {
6127 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6128 (PyDateTime_Delta *)offset, -1);
6129 Py_DECREF(offset);
6130 if (utcself == NULL)
6131 return NULL;
6132 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006133 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006134 y = GET_YEAR(utcself);
6135 m = GET_MONTH(utcself);
6136 d = GET_DAY(utcself);
6137 hh = DATE_GET_HOUR(utcself);
6138 mm = DATE_GET_MINUTE(utcself);
6139 ss = DATE_GET_SECOND(utcself);
6140
6141 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006142 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006143}
6144
Tim Peters371935f2003-02-01 01:52:50 +00006145/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006146
Tim Petersa9bc1682003-01-11 03:39:11 +00006147/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006148 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6149 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006150 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006151 */
6152static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006153datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006155 PyObject *basestate;
6156 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006158 basestate = PyBytes_FromStringAndSize((char *)self->data,
6159 _PyDateTime_DATETIME_DATASIZE);
6160 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006161 if (proto > 3 && DATE_GET_FOLD(self))
6162 /* Set the first bit of the third byte */
6163 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006164 if (! HASTZINFO(self) || self->tzinfo == Py_None)
6165 result = PyTuple_Pack(1, basestate);
6166 else
6167 result = PyTuple_Pack(2, basestate, self->tzinfo);
6168 Py_DECREF(basestate);
6169 }
6170 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00006171}
6172
6173static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006174datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006175{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006176 int proto;
6177 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006178 return NULL;
6179
6180 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006181}
6182
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006183static PyObject *
6184datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6185{
6186 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6187}
6188
Tim Petersa9bc1682003-01-11 03:39:11 +00006189static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006191 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006192
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006193 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006195 {"utcnow", (PyCFunction)datetime_utcnow,
6196 METH_NOARGS | METH_CLASS,
6197 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006198
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006199 {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006200 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6201 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006203 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6204 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006205 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006207 {"strptime", (PyCFunction)datetime_strptime,
6208 METH_VARARGS | METH_CLASS,
6209 PyDoc_STR("string, format -> new datetime parsed from a string "
6210 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006211
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006212 {"combine", (PyCFunction)(void(*)(void))datetime_combine,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006213 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6214 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006215
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006216 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6217 METH_O | METH_CLASS,
6218 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006220 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006222 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6223 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006225 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6226 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006228 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6229 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006231 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6232 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006234 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6235 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006236
Alexander Belopolskya4415142012-06-08 12:33:09 -04006237 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6238 PyDoc_STR("Return POSIX timestamp as float.")},
6239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006240 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6241 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006242
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006243 {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006244 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006245 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006246 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006247 "defaults to 'T'.\n"
6248 "timespec specifies what components of the time to include"
6249 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6250 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006252 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6253 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006255 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6256 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006258 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6259 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006260
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006261 {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006262 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006263
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006264 {"astimezone", (PyCFunction)(void(*)(void))datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006265 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006266
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006267 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006268 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006269
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006270 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6271 PyDoc_STR("__reduce__() -> (cls, state)")},
6272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006273 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006274};
6275
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006276static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006277PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6278\n\
6279The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006280instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006281
Tim Petersa9bc1682003-01-11 03:39:11 +00006282static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006283 datetime_add, /* nb_add */
6284 datetime_subtract, /* nb_subtract */
6285 0, /* nb_multiply */
6286 0, /* nb_remainder */
6287 0, /* nb_divmod */
6288 0, /* nb_power */
6289 0, /* nb_negative */
6290 0, /* nb_positive */
6291 0, /* nb_absolute */
6292 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006293};
6294
Neal Norwitz227b5332006-03-22 09:28:35 +00006295static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006296 PyVarObject_HEAD_INIT(NULL, 0)
6297 "datetime.datetime", /* tp_name */
6298 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6299 0, /* tp_itemsize */
6300 (destructor)datetime_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006301 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006302 0, /* tp_getattr */
6303 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006304 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006305 (reprfunc)datetime_repr, /* tp_repr */
6306 &datetime_as_number, /* tp_as_number */
6307 0, /* tp_as_sequence */
6308 0, /* tp_as_mapping */
6309 (hashfunc)datetime_hash, /* tp_hash */
6310 0, /* tp_call */
6311 (reprfunc)datetime_str, /* tp_str */
6312 PyObject_GenericGetAttr, /* tp_getattro */
6313 0, /* tp_setattro */
6314 0, /* tp_as_buffer */
6315 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6316 datetime_doc, /* tp_doc */
6317 0, /* tp_traverse */
6318 0, /* tp_clear */
6319 datetime_richcompare, /* tp_richcompare */
6320 0, /* tp_weaklistoffset */
6321 0, /* tp_iter */
6322 0, /* tp_iternext */
6323 datetime_methods, /* tp_methods */
6324 0, /* tp_members */
6325 datetime_getset, /* tp_getset */
6326 &PyDateTime_DateType, /* tp_base */
6327 0, /* tp_dict */
6328 0, /* tp_descr_get */
6329 0, /* tp_descr_set */
6330 0, /* tp_dictoffset */
6331 0, /* tp_init */
6332 datetime_alloc, /* tp_alloc */
6333 datetime_new, /* tp_new */
6334 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006335};
6336
6337/* ---------------------------------------------------------------------------
6338 * Module methods and initialization.
6339 */
6340
6341static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006342 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006343};
6344
Tim Peters9ddf40b2004-06-20 22:41:32 +00006345/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6346 * datetime.h.
6347 */
6348static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006349 &PyDateTime_DateType,
6350 &PyDateTime_DateTimeType,
6351 &PyDateTime_TimeType,
6352 &PyDateTime_DeltaType,
6353 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006354 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006355 new_date_ex,
6356 new_datetime_ex,
6357 new_time_ex,
6358 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006359 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006360 datetime_fromtimestamp,
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04006361 datetime_date_fromtimestamp_capi,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006362 new_datetime_ex2,
6363 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006364};
6365
6366
Martin v. Löwis1a214512008-06-11 05:26:20 +00006367
6368static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006369 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006370 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006371 "Fast implementation of the datetime type.",
6372 -1,
6373 module_methods,
6374 NULL,
6375 NULL,
6376 NULL,
6377 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006378};
6379
Tim Peters2a799bf2002-12-16 20:18:38 +00006380PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006381PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006383 PyObject *m; /* a module object */
6384 PyObject *d; /* its dict */
6385 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006386 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006388 m = PyModule_Create(&datetimemodule);
6389 if (m == NULL)
6390 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006392 if (PyType_Ready(&PyDateTime_DateType) < 0)
6393 return NULL;
6394 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6395 return NULL;
6396 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6397 return NULL;
6398 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6399 return NULL;
6400 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6401 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006402 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6403 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006405 /* timedelta values */
6406 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006408 x = new_delta(0, 0, 1, 0);
6409 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6410 return NULL;
6411 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006413 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6414 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6415 return NULL;
6416 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006418 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6419 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6420 return NULL;
6421 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006423 /* date values */
6424 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006426 x = new_date(1, 1, 1);
6427 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6428 return NULL;
6429 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006431 x = new_date(MAXYEAR, 12, 31);
6432 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6433 return NULL;
6434 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006436 x = new_delta(1, 0, 0, 0);
6437 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6438 return NULL;
6439 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006441 /* time values */
6442 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006443
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006444 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006445 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6446 return NULL;
6447 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006448
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006449 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006450 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6451 return NULL;
6452 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006454 x = new_delta(0, 0, 1, 0);
6455 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6456 return NULL;
6457 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006459 /* datetime values */
6460 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006461
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006462 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006463 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6464 return NULL;
6465 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006466
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006467 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006468 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6469 return NULL;
6470 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006472 x = new_delta(0, 0, 1, 0);
6473 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6474 return NULL;
6475 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006476
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006477 /* timezone values */
6478 d = PyDateTime_TimeZoneType.tp_dict;
6479
6480 delta = new_delta(0, 0, 0, 0);
6481 if (delta == NULL)
6482 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006483 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006484 Py_DECREF(delta);
6485 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6486 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006487 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006488 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006489
6490 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6491 if (delta == NULL)
6492 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006493 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006494 Py_DECREF(delta);
6495 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6496 return NULL;
6497 Py_DECREF(x);
6498
6499 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6500 if (delta == NULL)
6501 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006502 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006503 Py_DECREF(delta);
6504 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6505 return NULL;
6506 Py_DECREF(x);
6507
Alexander Belopolskya4415142012-06-08 12:33:09 -04006508 /* Epoch */
6509 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006510 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006511 if (PyDateTime_Epoch == NULL)
6512 return NULL;
6513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006514 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006515 PyModule_AddIntMacro(m, MINYEAR);
6516 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006518 Py_INCREF(&PyDateTime_DateType);
6519 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006521 Py_INCREF(&PyDateTime_DateTimeType);
6522 PyModule_AddObject(m, "datetime",
6523 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006525 Py_INCREF(&PyDateTime_TimeType);
6526 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006528 Py_INCREF(&PyDateTime_DeltaType);
6529 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006531 Py_INCREF(&PyDateTime_TZInfoType);
6532 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006533
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006534 Py_INCREF(&PyDateTime_TimeZoneType);
6535 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006537 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6538 if (x == NULL)
6539 return NULL;
6540 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006542 /* A 4-year cycle has an extra leap day over what we'd get from
6543 * pasting together 4 single years.
6544 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006545 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006546 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006548 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6549 * get from pasting together 4 100-year cycles.
6550 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006551 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006552 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006554 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6555 * pasting together 25 4-year cycles.
6556 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006557 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006558 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006560 us_per_ms = PyLong_FromLong(1000);
6561 us_per_second = PyLong_FromLong(1000000);
6562 us_per_minute = PyLong_FromLong(60000000);
6563 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006564 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006565 us_per_minute == NULL || seconds_per_day == NULL)
6566 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006568 /* The rest are too big for 32-bit ints, but even
6569 * us_per_week fits in 40 bits, so doubles should be exact.
6570 */
6571 us_per_hour = PyLong_FromDouble(3600000000.0);
6572 us_per_day = PyLong_FromDouble(86400000000.0);
6573 us_per_week = PyLong_FromDouble(604800000000.0);
6574 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6575 return NULL;
6576 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006577}
Tim Petersf3615152003-01-01 21:51:37 +00006578
6579/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006580Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006581 x.n = x stripped of its timezone -- its naive time.
6582 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006583 return None
Tim Petersf3615152003-01-01 21:51:37 +00006584 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006585 return None
Tim Petersf3615152003-01-01 21:51:37 +00006586 x.s = x's standard offset, x.o - x.d
6587
6588Now some derived rules, where k is a duration (timedelta).
6589
65901. x.o = x.s + x.d
6591 This follows from the definition of x.s.
6592
Tim Petersc5dc4da2003-01-02 17:55:03 +000065932. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006594 This is actually a requirement, an assumption we need to make about
6595 sane tzinfo classes.
6596
65973. The naive UTC time corresponding to x is x.n - x.o.
6598 This is again a requirement for a sane tzinfo class.
6599
66004. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006601 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006602
Tim Petersc5dc4da2003-01-02 17:55:03 +000066035. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006604 Again follows from how arithmetic is defined.
6605
Tim Peters8bb5ad22003-01-24 02:44:45 +00006606Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006607(meaning that the various tzinfo methods exist, and don't blow up or return
6608None when called).
6609
Tim Petersa9bc1682003-01-11 03:39:11 +00006610The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006611x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006612
6613By #3, we want
6614
Tim Peters8bb5ad22003-01-24 02:44:45 +00006615 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006616
6617The algorithm starts by attaching tz to x.n, and calling that y. So
6618x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6619becomes true; in effect, we want to solve [2] for k:
6620
Tim Peters8bb5ad22003-01-24 02:44:45 +00006621 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006622
6623By #1, this is the same as
6624
Tim Peters8bb5ad22003-01-24 02:44:45 +00006625 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006626
6627By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6628Substituting that into [3],
6629
Tim Peters8bb5ad22003-01-24 02:44:45 +00006630 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6631 k - (y+k).s - (y+k).d = 0; rearranging,
6632 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6633 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006634
Tim Peters8bb5ad22003-01-24 02:44:45 +00006635On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6636approximate k by ignoring the (y+k).d term at first. Note that k can't be
6637very large, since all offset-returning methods return a duration of magnitude
6638less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6639be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006640
6641In any case, the new value is
6642
Tim Peters8bb5ad22003-01-24 02:44:45 +00006643 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006644
Tim Peters8bb5ad22003-01-24 02:44:45 +00006645It's helpful to step back at look at [4] from a higher level: it's simply
6646mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006647
6648At this point, if
6649
Tim Peters8bb5ad22003-01-24 02:44:45 +00006650 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006651
6652we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006653at the start of daylight time. Picture US Eastern for concreteness. The wall
6654time 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 +00006655sense then. The docs ask that an Eastern tzinfo class consider such a time to
6656be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6657on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006658the only spelling that makes sense on the local wall clock.
6659
Tim Petersc5dc4da2003-01-02 17:55:03 +00006660In fact, if [5] holds at this point, we do have the standard-time spelling,
6661but that takes a bit of proof. We first prove a stronger result. What's the
6662difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006663
Tim Peters8bb5ad22003-01-24 02:44:45 +00006664 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006665
Tim Petersc5dc4da2003-01-02 17:55:03 +00006666Now
6667 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006668 (y + y.s).n = by #5
6669 y.n + y.s = since y.n = x.n
6670 x.n + y.s = since z and y are have the same tzinfo member,
6671 y.s = z.s by #2
6672 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006673
Tim Petersc5dc4da2003-01-02 17:55:03 +00006674Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006675
Tim Petersc5dc4da2003-01-02 17:55:03 +00006676 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006677 x.n - ((x.n + z.s) - z.o) = expanding
6678 x.n - x.n - z.s + z.o = cancelling
6679 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006680 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006681
Tim Petersc5dc4da2003-01-02 17:55:03 +00006682So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006683
Tim Petersc5dc4da2003-01-02 17:55:03 +00006684If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006685spelling we wanted in the endcase described above. We're done. Contrarily,
6686if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006687
Tim Petersc5dc4da2003-01-02 17:55:03 +00006688If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6689add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006690local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006691
Tim Petersc5dc4da2003-01-02 17:55:03 +00006692Let
Tim Petersf3615152003-01-01 21:51:37 +00006693
Tim Peters4fede1a2003-01-04 00:26:59 +00006694 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006695
Tim Peters4fede1a2003-01-04 00:26:59 +00006696and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006697
Tim Peters8bb5ad22003-01-24 02:44:45 +00006698 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006699
Tim Peters8bb5ad22003-01-24 02:44:45 +00006700If so, we're done. If not, the tzinfo class is insane, according to the
6701assumptions we've made. This also requires a bit of proof. As before, let's
6702compute the difference between the LHS and RHS of [8] (and skipping some of
6703the justifications for the kinds of substitutions we've done several times
6704already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006705
Tim Peters8bb5ad22003-01-24 02:44:45 +00006706 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006707 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6708 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6709 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6710 - z.n + z.n - z.o + z'.o = cancel z.n
6711 - z.o + z'.o = #1 twice
6712 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6713 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006714
6715So 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 +00006716we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6717return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006718
Tim Peters8bb5ad22003-01-24 02:44:45 +00006719How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6720a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6721would have to change the result dst() returns: we start in DST, and moving
6722a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006723
Tim Peters8bb5ad22003-01-24 02:44:45 +00006724There isn't a sane case where this can happen. The closest it gets is at
6725the end of DST, where there's an hour in UTC with no spelling in a hybrid
6726tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6727that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6728UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6729time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6730clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6731standard time. Since that's what the local clock *does*, we want to map both
6732UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006733in local time, but so it goes -- it's the way the local clock works.
6734
Tim Peters8bb5ad22003-01-24 02:44:45 +00006735When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6736so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6737z' = 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 +00006738(correctly) concludes that z' is not UTC-equivalent to x.
6739
6740Because we know z.d said z was in daylight time (else [5] would have held and
6741we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006742and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006743return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6744but the reasoning doesn't depend on the example -- it depends on there being
6745two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006746z' must be in standard time, and is the spelling we want in this case.
6747
6748Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6749concerned (because it takes z' as being in standard time rather than the
6750daylight time we intend here), but returning it gives the real-life "local
6751clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6752tz.
6753
6754When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6755the 1:MM standard time spelling we want.
6756
6757So how can this break? One of the assumptions must be violated. Two
6758possibilities:
6759
67601) [2] effectively says that y.s is invariant across all y belong to a given
6761 time zone. This isn't true if, for political reasons or continental drift,
6762 a region decides to change its base offset from UTC.
6763
67642) There may be versions of "double daylight" time where the tail end of
6765 the analysis gives up a step too early. I haven't thought about that
6766 enough to say.
6767
6768In any case, it's clear that the default fromutc() is strong enough to handle
6769"almost all" time zones: so long as the standard offset is invariant, it
6770doesn't matter if daylight time transition points change from year to year, or
6771if daylight time is skipped in some years; it doesn't matter how large or
6772small dst() may get within its bounds; and it doesn't even matter if some
6773perverse time zone returns a negative dst()). So a breaking case must be
6774pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006775--------------------------------------------------------------------------- */