blob: 7997758908bb4dcdd64bd954b8b7c03dd057811d [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
Mark Dickinsone94c6792009-02-02 20:36:42 +00001707/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001708 * The comparisons here all most naturally compute a cmp()-like result.
1709 * This little helper turns that into a bool result for rich comparisons.
1710 */
1711static PyObject *
1712diff_to_bool(int diff, int op)
1713{
stratakise8b19652017-11-02 11:32:54 +01001714 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001715}
1716
Tim Peters07534a62003-02-07 22:50:28 +00001717/* Raises a "can't compare" TypeError and returns NULL. */
1718static PyObject *
1719cmperror(PyObject *a, PyObject *b)
1720{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001721 PyErr_Format(PyExc_TypeError,
1722 "can't compare %s to %s",
1723 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1724 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001725}
1726
Tim Peters2a799bf2002-12-16 20:18:38 +00001727/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001728 * Cached Python objects; these are set by the module init function.
1729 */
1730
1731/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732static PyObject *us_per_ms = NULL; /* 1000 */
1733static PyObject *us_per_second = NULL; /* 1000000 */
1734static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001735static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1736static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1737static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001738static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1739
Tim Peters2a799bf2002-12-16 20:18:38 +00001740/* ---------------------------------------------------------------------------
1741 * Class implementations.
1742 */
1743
1744/*
1745 * PyDateTime_Delta implementation.
1746 */
1747
1748/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001750 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001751 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1752 * due to ubiquitous overflow possibilities.
1753 */
1754static PyObject *
1755delta_to_microseconds(PyDateTime_Delta *self)
1756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 PyObject *x1 = NULL;
1758 PyObject *x2 = NULL;
1759 PyObject *x3 = NULL;
1760 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1763 if (x1 == NULL)
1764 goto Done;
1765 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1766 if (x2 == NULL)
1767 goto Done;
1768 Py_DECREF(x1);
1769 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 /* x2 has days in seconds */
1772 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1773 if (x1 == NULL)
1774 goto Done;
1775 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1776 if (x3 == NULL)
1777 goto Done;
1778 Py_DECREF(x1);
1779 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001780 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 /* x3 has days+seconds in seconds */
1783 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1784 if (x1 == NULL)
1785 goto Done;
1786 Py_DECREF(x3);
1787 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 /* x1 has days+seconds in us */
1790 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1791 if (x2 == NULL)
1792 goto Done;
1793 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001794 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001795
1796Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 Py_XDECREF(x1);
1798 Py_XDECREF(x2);
1799 Py_XDECREF(x3);
1800 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001801}
1802
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001803static PyObject *
1804checked_divmod(PyObject *a, PyObject *b)
1805{
1806 PyObject *result = PyNumber_Divmod(a, b);
1807 if (result != NULL) {
1808 if (!PyTuple_Check(result)) {
1809 PyErr_Format(PyExc_TypeError,
1810 "divmod() returned non-tuple (type %.200s)",
1811 result->ob_type->tp_name);
1812 Py_DECREF(result);
1813 return NULL;
1814 }
1815 if (PyTuple_GET_SIZE(result) != 2) {
1816 PyErr_Format(PyExc_TypeError,
1817 "divmod() returned a tuple of size %zd",
1818 PyTuple_GET_SIZE(result));
1819 Py_DECREF(result);
1820 return NULL;
1821 }
1822 }
1823 return result;
1824}
1825
Serhiy Storchaka95949422013-08-27 19:40:23 +03001826/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001827 */
1828static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001829microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 int us;
1832 int s;
1833 int d;
Tim Peters2a799bf2002-12-16 20:18:38 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 PyObject *tuple = NULL;
1836 PyObject *num = NULL;
1837 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001838
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001839 tuple = checked_divmod(pyus, us_per_second);
1840 if (tuple == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 goto Done;
1842 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001843
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001844 num = PyTuple_GET_ITEM(tuple, 1); /* us */
1845 us = _PyLong_AsInt(num);
1846 num = NULL;
1847 if (us == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 goto Done;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001849 }
1850 if (!(0 <= us && us < 1000000)) {
1851 goto BadDivmod;
1852 }
1853
1854 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 Py_INCREF(num);
1856 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001857
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001858 tuple = checked_divmod(num, seconds_per_day);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 if (tuple == NULL)
1860 goto Done;
1861 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001862
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001863 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */
1864 s = _PyLong_AsInt(num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 num = NULL;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001866 if (s == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 goto Done;
1868 }
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001869 if (!(0 <= s && s < 24*3600)) {
1870 goto BadDivmod;
1871 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001872
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001873 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 Py_INCREF(num);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001875 d = _PyLong_AsInt(num);
1876 if (d == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 goto Done;
1878 }
1879 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001880
1881Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 Py_XDECREF(tuple);
1883 Py_XDECREF(num);
1884 return result;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001885
1886BadDivmod:
1887 PyErr_SetString(PyExc_TypeError,
1888 "divmod() returned a value out of range");
1889 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001890}
1891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892#define microseconds_to_delta(pymicros) \
1893 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001894
Tim Peters2a799bf2002-12-16 20:18:38 +00001895static PyObject *
1896multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 PyObject *pyus_in;
1899 PyObject *pyus_out;
1900 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 pyus_in = delta_to_microseconds(delta);
1903 if (pyus_in == NULL)
1904 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001905
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001906 pyus_out = PyNumber_Multiply(intobj, pyus_in);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 Py_DECREF(pyus_in);
1908 if (pyus_out == NULL)
1909 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 result = microseconds_to_delta(pyus_out);
1912 Py_DECREF(pyus_out);
1913 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001914}
1915
1916static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001917get_float_as_integer_ratio(PyObject *floatobj)
1918{
1919 PyObject *ratio;
1920
1921 assert(floatobj && PyFloat_Check(floatobj));
1922 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1923 if (ratio == NULL) {
1924 return NULL;
1925 }
1926 if (!PyTuple_Check(ratio)) {
1927 PyErr_Format(PyExc_TypeError,
1928 "unexpected return type from as_integer_ratio(): "
1929 "expected tuple, got '%.200s'",
1930 Py_TYPE(ratio)->tp_name);
1931 Py_DECREF(ratio);
1932 return NULL;
1933 }
1934 if (PyTuple_Size(ratio) != 2) {
1935 PyErr_SetString(PyExc_ValueError,
1936 "as_integer_ratio() must return a 2-tuple");
1937 Py_DECREF(ratio);
1938 return NULL;
1939 }
1940 return ratio;
1941}
1942
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001943/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001944static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001945multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001946{
1947 PyObject *result = NULL;
1948 PyObject *pyus_in = NULL, *temp, *pyus_out;
1949 PyObject *ratio = NULL;
1950
1951 pyus_in = delta_to_microseconds(delta);
1952 if (pyus_in == NULL)
1953 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001954 ratio = get_float_as_integer_ratio(floatobj);
1955 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001956 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001957 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001958 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001959 Py_DECREF(pyus_in);
1960 pyus_in = NULL;
1961 if (temp == NULL)
1962 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001963 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001964 Py_DECREF(temp);
1965 if (pyus_out == NULL)
1966 goto error;
1967 result = microseconds_to_delta(pyus_out);
1968 Py_DECREF(pyus_out);
1969 error:
1970 Py_XDECREF(pyus_in);
1971 Py_XDECREF(ratio);
1972
1973 return result;
1974}
1975
1976static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001977divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1978{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 PyObject *pyus_in;
1980 PyObject *pyus_out;
1981 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 pyus_in = delta_to_microseconds(delta);
1984 if (pyus_in == NULL)
1985 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1988 Py_DECREF(pyus_in);
1989 if (pyus_out == NULL)
1990 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 result = microseconds_to_delta(pyus_out);
1993 Py_DECREF(pyus_out);
1994 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001995}
1996
1997static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001998divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1999{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002000 PyObject *pyus_left;
2001 PyObject *pyus_right;
2002 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 pyus_left = delta_to_microseconds(left);
2005 if (pyus_left == NULL)
2006 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 pyus_right = delta_to_microseconds(right);
2009 if (pyus_right == NULL) {
2010 Py_DECREF(pyus_left);
2011 return NULL;
2012 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 result = PyNumber_FloorDivide(pyus_left, pyus_right);
2015 Py_DECREF(pyus_left);
2016 Py_DECREF(pyus_right);
2017 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002018}
2019
2020static PyObject *
2021truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 PyObject *pyus_left;
2024 PyObject *pyus_right;
2025 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 pyus_left = delta_to_microseconds(left);
2028 if (pyus_left == NULL)
2029 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 pyus_right = delta_to_microseconds(right);
2032 if (pyus_right == NULL) {
2033 Py_DECREF(pyus_left);
2034 return NULL;
2035 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2038 Py_DECREF(pyus_left);
2039 Py_DECREF(pyus_right);
2040 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002041}
2042
2043static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002044truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2045{
2046 PyObject *result;
2047 PyObject *pyus_in, *pyus_out;
2048 pyus_in = delta_to_microseconds(delta);
2049 if (pyus_in == NULL)
2050 return NULL;
2051 pyus_out = divide_nearest(pyus_in, i);
2052 Py_DECREF(pyus_in);
2053 if (pyus_out == NULL)
2054 return NULL;
2055 result = microseconds_to_delta(pyus_out);
2056 Py_DECREF(pyus_out);
2057
2058 return result;
2059}
2060
2061static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002062delta_add(PyObject *left, PyObject *right)
2063{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2067 /* delta + delta */
2068 /* The C-level additions can't overflow because of the
2069 * invariant bounds.
2070 */
2071 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2072 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2073 int microseconds = GET_TD_MICROSECONDS(left) +
2074 GET_TD_MICROSECONDS(right);
2075 result = new_delta(days, seconds, microseconds, 1);
2076 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 if (result == Py_NotImplemented)
2079 Py_INCREF(result);
2080 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002081}
2082
2083static PyObject *
2084delta_negative(PyDateTime_Delta *self)
2085{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 return new_delta(-GET_TD_DAYS(self),
2087 -GET_TD_SECONDS(self),
2088 -GET_TD_MICROSECONDS(self),
2089 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002090}
2091
2092static PyObject *
2093delta_positive(PyDateTime_Delta *self)
2094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 /* Could optimize this (by returning self) if this isn't a
2096 * subclass -- but who uses unary + ? Approximately nobody.
2097 */
2098 return new_delta(GET_TD_DAYS(self),
2099 GET_TD_SECONDS(self),
2100 GET_TD_MICROSECONDS(self),
2101 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002102}
2103
2104static PyObject *
2105delta_abs(PyDateTime_Delta *self)
2106{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 assert(GET_TD_MICROSECONDS(self) >= 0);
2110 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 if (GET_TD_DAYS(self) < 0)
2113 result = delta_negative(self);
2114 else
2115 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002118}
2119
2120static PyObject *
2121delta_subtract(PyObject *left, PyObject *right)
2122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002125 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2126 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002127 /* The C-level additions can't overflow because of the
2128 * invariant bounds.
2129 */
2130 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2131 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2132 int microseconds = GET_TD_MICROSECONDS(left) -
2133 GET_TD_MICROSECONDS(right);
2134 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 if (result == Py_NotImplemented)
2138 Py_INCREF(result);
2139 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002140}
2141
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002142static int
2143delta_cmp(PyObject *self, PyObject *other)
2144{
2145 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2146 if (diff == 0) {
2147 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2148 if (diff == 0)
2149 diff = GET_TD_MICROSECONDS(self) -
2150 GET_TD_MICROSECONDS(other);
2151 }
2152 return diff;
2153}
2154
Tim Peters2a799bf2002-12-16 20:18:38 +00002155static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002156delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002159 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 return diff_to_bool(diff, op);
2161 }
2162 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002163 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002165}
2166
2167static PyObject *delta_getstate(PyDateTime_Delta *self);
2168
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002169static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002170delta_hash(PyDateTime_Delta *self)
2171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 if (self->hashcode == -1) {
2173 PyObject *temp = delta_getstate(self);
2174 if (temp != NULL) {
2175 self->hashcode = PyObject_Hash(temp);
2176 Py_DECREF(temp);
2177 }
2178 }
2179 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002180}
2181
2182static PyObject *
2183delta_multiply(PyObject *left, PyObject *right)
2184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 if (PyDelta_Check(left)) {
2188 /* delta * ??? */
2189 if (PyLong_Check(right))
2190 result = multiply_int_timedelta(right,
2191 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002192 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002193 result = multiply_truedivide_timedelta_float(
2194 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002195 }
2196 else if (PyLong_Check(left))
2197 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002198 (PyDateTime_Delta *) right);
2199 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002200 result = multiply_truedivide_timedelta_float(
2201 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002203 if (result == Py_NotImplemented)
2204 Py_INCREF(result);
2205 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002206}
2207
2208static PyObject *
2209delta_divide(PyObject *left, PyObject *right)
2210{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002211 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 if (PyDelta_Check(left)) {
2214 /* delta * ??? */
2215 if (PyLong_Check(right))
2216 result = divide_timedelta_int(
2217 (PyDateTime_Delta *)left,
2218 right);
2219 else if (PyDelta_Check(right))
2220 result = divide_timedelta_timedelta(
2221 (PyDateTime_Delta *)left,
2222 (PyDateTime_Delta *)right);
2223 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 if (result == Py_NotImplemented)
2226 Py_INCREF(result);
2227 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002228}
2229
Mark Dickinson7c186e22010-04-20 22:32:49 +00002230static PyObject *
2231delta_truedivide(PyObject *left, PyObject *right)
2232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 if (PyDelta_Check(left)) {
2236 if (PyDelta_Check(right))
2237 result = truedivide_timedelta_timedelta(
2238 (PyDateTime_Delta *)left,
2239 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002240 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002241 result = multiply_truedivide_timedelta_float(
2242 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002243 else if (PyLong_Check(right))
2244 result = truedivide_timedelta_int(
2245 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 if (result == Py_NotImplemented)
2249 Py_INCREF(result);
2250 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002251}
2252
2253static PyObject *
2254delta_remainder(PyObject *left, PyObject *right)
2255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 PyObject *pyus_left;
2257 PyObject *pyus_right;
2258 PyObject *pyus_remainder;
2259 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002260
Brian Curtindfc80e32011-08-10 20:28:54 -05002261 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2262 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2265 if (pyus_left == NULL)
2266 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2269 if (pyus_right == NULL) {
2270 Py_DECREF(pyus_left);
2271 return NULL;
2272 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2275 Py_DECREF(pyus_left);
2276 Py_DECREF(pyus_right);
2277 if (pyus_remainder == NULL)
2278 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 remainder = microseconds_to_delta(pyus_remainder);
2281 Py_DECREF(pyus_remainder);
2282 if (remainder == NULL)
2283 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002286}
2287
2288static PyObject *
2289delta_divmod(PyObject *left, PyObject *right)
2290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 PyObject *pyus_left;
2292 PyObject *pyus_right;
2293 PyObject *divmod;
2294 PyObject *delta;
2295 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002296
Brian Curtindfc80e32011-08-10 20:28:54 -05002297 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2298 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002300 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2301 if (pyus_left == NULL)
2302 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2305 if (pyus_right == NULL) {
2306 Py_DECREF(pyus_left);
2307 return NULL;
2308 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002309
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002310 divmod = checked_divmod(pyus_left, pyus_right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002311 Py_DECREF(pyus_left);
2312 Py_DECREF(pyus_right);
2313 if (divmod == NULL)
2314 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002316 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2317 if (delta == NULL) {
2318 Py_DECREF(divmod);
2319 return NULL;
2320 }
2321 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2322 Py_DECREF(delta);
2323 Py_DECREF(divmod);
2324 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002325}
2326
Tim Peters2a799bf2002-12-16 20:18:38 +00002327/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2328 * timedelta constructor. sofar is the # of microseconds accounted for
2329 * so far, and there are factor microseconds per current unit, the number
2330 * of which is given by num. num * factor is added to sofar in a
2331 * numerically careful way, and that's the result. Any fractional
2332 * microseconds left over (this can happen if num is a float type) are
2333 * added into *leftover.
2334 * Note that there are many ways this can give an error (NULL) return.
2335 */
2336static PyObject *
2337accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2338 double *leftover)
2339{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002340 PyObject *prod;
2341 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002343 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 if (PyLong_Check(num)) {
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002346 prod = PyNumber_Multiply(num, factor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 if (prod == NULL)
2348 return NULL;
2349 sum = PyNumber_Add(sofar, prod);
2350 Py_DECREF(prod);
2351 return sum;
2352 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002354 if (PyFloat_Check(num)) {
2355 double dnum;
2356 double fracpart;
2357 double intpart;
2358 PyObject *x;
2359 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 /* The Plan: decompose num into an integer part and a
2362 * fractional part, num = intpart + fracpart.
2363 * Then num * factor ==
2364 * intpart * factor + fracpart * factor
2365 * and the LHS can be computed exactly in long arithmetic.
2366 * The RHS is again broken into an int part and frac part.
2367 * and the frac part is added into *leftover.
2368 */
2369 dnum = PyFloat_AsDouble(num);
2370 if (dnum == -1.0 && PyErr_Occurred())
2371 return NULL;
2372 fracpart = modf(dnum, &intpart);
2373 x = PyLong_FromDouble(intpart);
2374 if (x == NULL)
2375 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 prod = PyNumber_Multiply(x, factor);
2378 Py_DECREF(x);
2379 if (prod == NULL)
2380 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 sum = PyNumber_Add(sofar, prod);
2383 Py_DECREF(prod);
2384 if (sum == NULL)
2385 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 if (fracpart == 0.0)
2388 return sum;
2389 /* So far we've lost no information. Dealing with the
2390 * fractional part requires float arithmetic, and may
2391 * lose a little info.
2392 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002393 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 dnum *= fracpart;
2397 fracpart = modf(dnum, &intpart);
2398 x = PyLong_FromDouble(intpart);
2399 if (x == NULL) {
2400 Py_DECREF(sum);
2401 return NULL;
2402 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 y = PyNumber_Add(sum, x);
2405 Py_DECREF(sum);
2406 Py_DECREF(x);
2407 *leftover += fracpart;
2408 return y;
2409 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 PyErr_Format(PyExc_TypeError,
2412 "unsupported type for timedelta %s component: %s",
2413 tag, Py_TYPE(num)->tp_name);
2414 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002415}
2416
2417static PyObject *
2418delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2419{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002420 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 /* Argument objects. */
2423 PyObject *day = NULL;
2424 PyObject *second = NULL;
2425 PyObject *us = NULL;
2426 PyObject *ms = NULL;
2427 PyObject *minute = NULL;
2428 PyObject *hour = NULL;
2429 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 PyObject *x = NULL; /* running sum of microseconds */
2432 PyObject *y = NULL; /* temp sum of microseconds */
2433 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 static char *keywords[] = {
2436 "days", "seconds", "microseconds", "milliseconds",
2437 "minutes", "hours", "weeks", NULL
2438 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002440 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2441 keywords,
2442 &day, &second, &us,
2443 &ms, &minute, &hour, &week) == 0)
2444 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 x = PyLong_FromLong(0);
2447 if (x == NULL)
2448 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450#define CLEANUP \
2451 Py_DECREF(x); \
2452 x = y; \
2453 if (x == NULL) \
2454 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002456 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002457 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002458 CLEANUP;
2459 }
2460 if (ms) {
2461 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2462 CLEANUP;
2463 }
2464 if (second) {
2465 y = accum("seconds", x, second, us_per_second, &leftover_us);
2466 CLEANUP;
2467 }
2468 if (minute) {
2469 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2470 CLEANUP;
2471 }
2472 if (hour) {
2473 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2474 CLEANUP;
2475 }
2476 if (day) {
2477 y = accum("days", x, day, us_per_day, &leftover_us);
2478 CLEANUP;
2479 }
2480 if (week) {
2481 y = accum("weeks", x, week, us_per_week, &leftover_us);
2482 CLEANUP;
2483 }
2484 if (leftover_us) {
2485 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002486 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002487 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002488 PyObject *temp;
2489
Victor Stinner69cc4872015-09-08 23:58:54 +02002490 whole_us = round(leftover_us);
2491 if (fabs(whole_us - leftover_us) == 0.5) {
2492 /* We're exactly halfway between two integers. In order
2493 * to do round-half-to-even, we must determine whether x
2494 * is odd. Note that x is odd when it's last bit is 1. The
2495 * code below uses bitwise and operation to check the last
2496 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002497 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002498 if (temp == NULL) {
2499 Py_DECREF(x);
2500 goto Done;
2501 }
2502 x_is_odd = PyObject_IsTrue(temp);
2503 Py_DECREF(temp);
2504 if (x_is_odd == -1) {
2505 Py_DECREF(x);
2506 goto Done;
2507 }
2508 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2509 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002510
Victor Stinner36a5a062013-08-28 01:53:39 +02002511 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002513 if (temp == NULL) {
2514 Py_DECREF(x);
2515 goto Done;
2516 }
2517 y = PyNumber_Add(x, temp);
2518 Py_DECREF(temp);
2519 CLEANUP;
2520 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 self = microseconds_to_delta_ex(x, type);
2523 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002524Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002525 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002526
2527#undef CLEANUP
2528}
2529
2530static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002531delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002533 return (GET_TD_DAYS(self) != 0
2534 || GET_TD_SECONDS(self) != 0
2535 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002536}
2537
2538static PyObject *
2539delta_repr(PyDateTime_Delta *self)
2540{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002541 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002542
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002543 if (args == NULL) {
2544 return NULL;
2545 }
2546
2547 const char *sep = "";
2548
2549 if (GET_TD_DAYS(self) != 0) {
2550 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2551 if (args == NULL) {
2552 return NULL;
2553 }
2554 sep = ", ";
2555 }
2556
2557 if (GET_TD_SECONDS(self) != 0) {
2558 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2559 GET_TD_SECONDS(self)));
2560 if (args == NULL) {
2561 return NULL;
2562 }
2563 sep = ", ";
2564 }
2565
2566 if (GET_TD_MICROSECONDS(self) != 0) {
2567 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2568 GET_TD_MICROSECONDS(self)));
2569 if (args == NULL) {
2570 return NULL;
2571 }
2572 }
2573
2574 if (PyUnicode_GET_LENGTH(args) == 0) {
2575 Py_SETREF(args, PyUnicode_FromString("0"));
2576 if (args == NULL) {
2577 return NULL;
2578 }
2579 }
2580
2581 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2582 args);
2583 Py_DECREF(args);
2584 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002585}
2586
2587static PyObject *
2588delta_str(PyDateTime_Delta *self)
2589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002590 int us = GET_TD_MICROSECONDS(self);
2591 int seconds = GET_TD_SECONDS(self);
2592 int minutes = divmod(seconds, 60, &seconds);
2593 int hours = divmod(minutes, 60, &minutes);
2594 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002596 if (days) {
2597 if (us)
2598 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2599 days, (days == 1 || days == -1) ? "" : "s",
2600 hours, minutes, seconds, us);
2601 else
2602 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2603 days, (days == 1 || days == -1) ? "" : "s",
2604 hours, minutes, seconds);
2605 } else {
2606 if (us)
2607 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2608 hours, minutes, seconds, us);
2609 else
2610 return PyUnicode_FromFormat("%d:%02d:%02d",
2611 hours, minutes, seconds);
2612 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002613
Tim Peters2a799bf2002-12-16 20:18:38 +00002614}
2615
Tim Peters371935f2003-02-01 01:52:50 +00002616/* Pickle support, a simple use of __reduce__. */
2617
Tim Petersb57f8f02003-02-01 02:54:15 +00002618/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002619static PyObject *
2620delta_getstate(PyDateTime_Delta *self)
2621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 return Py_BuildValue("iii", GET_TD_DAYS(self),
2623 GET_TD_SECONDS(self),
2624 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002625}
2626
Tim Peters2a799bf2002-12-16 20:18:38 +00002627static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302628delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitroube6859d2009-11-25 23:02:32 +00002629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 PyObject *total_seconds;
2631 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2634 if (total_microseconds == NULL)
2635 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002636
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002637 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002640 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002641}
2642
2643static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302644delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00002645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002647}
2648
2649#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2650
2651static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 {"days", T_INT, OFFSET(days), READONLY,
2654 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002656 {"seconds", T_INT, OFFSET(seconds), READONLY,
2657 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2660 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2661 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002662};
2663
2664static PyMethodDef delta_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302665 {"total_seconds", delta_total_seconds, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002666 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002668 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2669 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002672};
2673
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002674static const char delta_doc[] =
Chris Barkerd6a61f22018-10-19 15:43:24 -07002675PyDoc_STR("Difference between two datetime values.\n\n"
2676 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2677 "minutes=0, hours=0, weeks=0)\n\n"
2678 "All arguments are optional and default to 0.\n"
2679 "Arguments may be integers or floats, and may be positive or negative.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002680
2681static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002682 delta_add, /* nb_add */
2683 delta_subtract, /* nb_subtract */
2684 delta_multiply, /* nb_multiply */
2685 delta_remainder, /* nb_remainder */
2686 delta_divmod, /* nb_divmod */
2687 0, /* nb_power */
2688 (unaryfunc)delta_negative, /* nb_negative */
2689 (unaryfunc)delta_positive, /* nb_positive */
2690 (unaryfunc)delta_abs, /* nb_absolute */
2691 (inquiry)delta_bool, /* nb_bool */
2692 0, /*nb_invert*/
2693 0, /*nb_lshift*/
2694 0, /*nb_rshift*/
2695 0, /*nb_and*/
2696 0, /*nb_xor*/
2697 0, /*nb_or*/
2698 0, /*nb_int*/
2699 0, /*nb_reserved*/
2700 0, /*nb_float*/
2701 0, /*nb_inplace_add*/
2702 0, /*nb_inplace_subtract*/
2703 0, /*nb_inplace_multiply*/
2704 0, /*nb_inplace_remainder*/
2705 0, /*nb_inplace_power*/
2706 0, /*nb_inplace_lshift*/
2707 0, /*nb_inplace_rshift*/
2708 0, /*nb_inplace_and*/
2709 0, /*nb_inplace_xor*/
2710 0, /*nb_inplace_or*/
2711 delta_divide, /* nb_floor_divide */
2712 delta_truedivide, /* nb_true_divide */
2713 0, /* nb_inplace_floor_divide */
2714 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002715};
2716
2717static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 PyVarObject_HEAD_INIT(NULL, 0)
2719 "datetime.timedelta", /* tp_name */
2720 sizeof(PyDateTime_Delta), /* tp_basicsize */
2721 0, /* tp_itemsize */
2722 0, /* tp_dealloc */
2723 0, /* tp_print */
2724 0, /* tp_getattr */
2725 0, /* tp_setattr */
2726 0, /* tp_reserved */
2727 (reprfunc)delta_repr, /* tp_repr */
2728 &delta_as_number, /* tp_as_number */
2729 0, /* tp_as_sequence */
2730 0, /* tp_as_mapping */
2731 (hashfunc)delta_hash, /* tp_hash */
2732 0, /* tp_call */
2733 (reprfunc)delta_str, /* tp_str */
2734 PyObject_GenericGetAttr, /* tp_getattro */
2735 0, /* tp_setattro */
2736 0, /* tp_as_buffer */
2737 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2738 delta_doc, /* tp_doc */
2739 0, /* tp_traverse */
2740 0, /* tp_clear */
2741 delta_richcompare, /* tp_richcompare */
2742 0, /* tp_weaklistoffset */
2743 0, /* tp_iter */
2744 0, /* tp_iternext */
2745 delta_methods, /* tp_methods */
2746 delta_members, /* tp_members */
2747 0, /* tp_getset */
2748 0, /* tp_base */
2749 0, /* tp_dict */
2750 0, /* tp_descr_get */
2751 0, /* tp_descr_set */
2752 0, /* tp_dictoffset */
2753 0, /* tp_init */
2754 0, /* tp_alloc */
2755 delta_new, /* tp_new */
2756 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002757};
2758
2759/*
2760 * PyDateTime_Date implementation.
2761 */
2762
2763/* Accessor properties. */
2764
2765static PyObject *
2766date_year(PyDateTime_Date *self, void *unused)
2767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002768 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002769}
2770
2771static PyObject *
2772date_month(PyDateTime_Date *self, void *unused)
2773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002774 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002775}
2776
2777static PyObject *
2778date_day(PyDateTime_Date *self, void *unused)
2779{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002780 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002781}
2782
2783static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002784 {"year", (getter)date_year},
2785 {"month", (getter)date_month},
2786 {"day", (getter)date_day},
2787 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002788};
2789
2790/* Constructors. */
2791
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002792static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002793
Tim Peters2a799bf2002-12-16 20:18:38 +00002794static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002795date_from_pickle(PyTypeObject *type, PyObject *state)
2796{
2797 PyDateTime_Date *me;
2798
2799 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2800 if (me != NULL) {
2801 const char *pdata = PyBytes_AS_STRING(state);
2802 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2803 me->hashcode = -1;
2804 }
2805 return (PyObject *)me;
2806}
2807
2808static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002809date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2810{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002811 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002812 int year;
2813 int month;
2814 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002816 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka1133a8c2018-12-07 16:48:21 +02002817 if (PyTuple_GET_SIZE(args) == 1) {
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002818 PyObject *state = PyTuple_GET_ITEM(args, 0);
2819 if (PyBytes_Check(state)) {
2820 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2821 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2822 {
2823 return date_from_pickle(type, state);
Victor Stinnerb37672d2018-11-22 03:37:50 +01002824 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002825 }
2826 else if (PyUnicode_Check(state)) {
2827 if (PyUnicode_READY(state)) {
2828 return NULL;
2829 }
2830 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
2831 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
2832 {
2833 state = PyUnicode_AsLatin1String(state);
2834 if (state == NULL) {
2835 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
2836 /* More informative error message. */
2837 PyErr_SetString(PyExc_ValueError,
2838 "Failed to encode latin1 string when unpickling "
2839 "a date object. "
2840 "pickle.load(data, encoding='latin1') is assumed.");
2841 }
2842 return NULL;
2843 }
2844 self = date_from_pickle(type, state);
2845 Py_DECREF(state);
2846 return self;
2847 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002848 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2852 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 self = new_date_ex(year, month, day, type);
2854 }
2855 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002856}
2857
Tim Peters2a799bf2002-12-16 20:18:38 +00002858static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002859date_fromtimestamp(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002860{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002861 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002863
Victor Stinnere4a994d2015-03-30 01:10:14 +02002864 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002865 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002866
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002867 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002868 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002869
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002870 return new_date_subclass_ex(tm.tm_year + 1900,
2871 tm.tm_mon + 1,
2872 tm.tm_mday,
2873 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002874}
2875
2876/* Return new date from current time.
2877 * We say this is equivalent to fromtimestamp(time.time()), and the
2878 * only way to be sure of that is to *call* time.time(). That's not
2879 * generally the same as calling C's time.
2880 */
2881static PyObject *
2882date_today(PyObject *cls, PyObject *dummy)
2883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 PyObject *time;
2885 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002886 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002888 time = time_time();
2889 if (time == NULL)
2890 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002892 /* Note well: today() is a class method, so this may not call
2893 * date.fromtimestamp. For example, it may call
2894 * datetime.fromtimestamp. That's why we need all the accuracy
2895 * time.time() delivers; if someone were gonzo about optimization,
2896 * date.today() could get away with plain C time().
2897 */
Victor Stinner20401de2016-12-09 15:24:31 +01002898 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2899 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002900 Py_DECREF(time);
2901 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002902}
2903
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002904/*[clinic input]
2905@classmethod
2906datetime.date.fromtimestamp
2907
2908 timestamp: object
2909 /
2910
2911Create a date from a POSIX timestamp.
2912
2913The timestamp is a number, e.g. created via time.time(), that is interpreted
2914as local time.
2915[clinic start generated code]*/
2916
Tim Peters2a799bf2002-12-16 20:18:38 +00002917static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002918datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp)
2919/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00002920{
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002921 return date_fromtimestamp((PyObject *) type, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002922}
2923
2924/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2925 * the ordinal is out of range.
2926 */
2927static PyObject *
2928date_fromordinal(PyObject *cls, PyObject *args)
2929{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002930 PyObject *result = NULL;
2931 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002933 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2934 int year;
2935 int month;
2936 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002938 if (ordinal < 1)
2939 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2940 ">= 1");
2941 else {
2942 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002943 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002944 }
2945 }
2946 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002947}
2948
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002949/* Return the new date from a string as generated by date.isoformat() */
2950static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04002951date_fromisoformat(PyObject *cls, PyObject *dtstr)
2952{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002953 assert(dtstr != NULL);
2954
2955 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04002956 PyErr_SetString(PyExc_TypeError,
2957 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002958 return NULL;
2959 }
2960
2961 Py_ssize_t len;
2962
Paul Ganssle3df85402018-10-22 12:32:52 -04002963 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04002964 if (dt_ptr == NULL) {
2965 goto invalid_string_error;
2966 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002967
2968 int year = 0, month = 0, day = 0;
2969
2970 int rv;
2971 if (len == 10) {
2972 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
Paul Ganssle3df85402018-10-22 12:32:52 -04002973 }
2974 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002975 rv = -1;
2976 }
2977
2978 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04002979 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002980 }
2981
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002982 return new_date_subclass_ex(year, month, day, cls);
Paul Ganssle096329f2018-08-23 11:06:20 -04002983
2984invalid_string_error:
Paul Ganssle3df85402018-10-22 12:32:52 -04002985 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04002986 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002987}
2988
Tim Peters2a799bf2002-12-16 20:18:38 +00002989/*
2990 * Date arithmetic.
2991 */
2992
2993/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2994 * instead.
2995 */
2996static PyObject *
2997add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002999 PyObject *result = NULL;
3000 int year = GET_YEAR(date);
3001 int month = GET_MONTH(date);
3002 int deltadays = GET_TD_DAYS(delta);
3003 /* C-level overflow is impossible because |deltadays| < 1e9. */
3004 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00003005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003006 if (normalize_date(&year, &month, &day) >= 0)
3007 result = new_date(year, month, day);
3008 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003009}
3010
3011static PyObject *
3012date_add(PyObject *left, PyObject *right)
3013{
Brian Curtindfc80e32011-08-10 20:28:54 -05003014 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3015 Py_RETURN_NOTIMPLEMENTED;
3016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003017 if (PyDate_Check(left)) {
3018 /* date + ??? */
3019 if (PyDelta_Check(right))
3020 /* date + delta */
3021 return add_date_timedelta((PyDateTime_Date *) left,
3022 (PyDateTime_Delta *) right,
3023 0);
3024 }
3025 else {
3026 /* ??? + date
3027 * 'right' must be one of us, or we wouldn't have been called
3028 */
3029 if (PyDelta_Check(left))
3030 /* delta + date */
3031 return add_date_timedelta((PyDateTime_Date *) right,
3032 (PyDateTime_Delta *) left,
3033 0);
3034 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003035 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003036}
3037
3038static PyObject *
3039date_subtract(PyObject *left, PyObject *right)
3040{
Brian Curtindfc80e32011-08-10 20:28:54 -05003041 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3042 Py_RETURN_NOTIMPLEMENTED;
3043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003044 if (PyDate_Check(left)) {
3045 if (PyDate_Check(right)) {
3046 /* date - date */
3047 int left_ord = ymd_to_ord(GET_YEAR(left),
3048 GET_MONTH(left),
3049 GET_DAY(left));
3050 int right_ord = ymd_to_ord(GET_YEAR(right),
3051 GET_MONTH(right),
3052 GET_DAY(right));
3053 return new_delta(left_ord - right_ord, 0, 0, 0);
3054 }
3055 if (PyDelta_Check(right)) {
3056 /* date - delta */
3057 return add_date_timedelta((PyDateTime_Date *) left,
3058 (PyDateTime_Delta *) right,
3059 1);
3060 }
3061 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003062 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003063}
3064
3065
3066/* Various ways to turn a date into a string. */
3067
3068static PyObject *
3069date_repr(PyDateTime_Date *self)
3070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003071 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3072 Py_TYPE(self)->tp_name,
3073 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003074}
3075
3076static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303077date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003079 return PyUnicode_FromFormat("%04d-%02d-%02d",
3080 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003081}
3082
Tim Peterse2df5ff2003-05-02 18:39:55 +00003083/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003084static PyObject *
3085date_str(PyDateTime_Date *self)
3086{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003087 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003088}
3089
3090
3091static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303092date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003094 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003095}
3096
3097static PyObject *
3098date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003100 /* This method can be inherited, and needs to call the
3101 * timetuple() method appropriate to self's class.
3102 */
3103 PyObject *result;
3104 PyObject *tuple;
3105 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003106 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003107 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003109 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3110 &format))
3111 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003112
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003113 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003114 if (tuple == NULL)
3115 return NULL;
3116 result = wrap_strftime((PyObject *)self, format, tuple,
3117 (PyObject *)self);
3118 Py_DECREF(tuple);
3119 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003120}
3121
Eric Smith1ba31142007-09-11 18:06:02 +00003122static PyObject *
3123date_format(PyDateTime_Date *self, PyObject *args)
3124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003127 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3128 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003130 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003131 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003132 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003133
Victor Stinner20401de2016-12-09 15:24:31 +01003134 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3135 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003136}
3137
Tim Peters2a799bf2002-12-16 20:18:38 +00003138/* ISO methods. */
3139
3140static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303141date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003145 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003146}
3147
3148static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303149date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003151 int year = GET_YEAR(self);
3152 int week1_monday = iso_week1_monday(year);
3153 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3154 int week;
3155 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003157 week = divmod(today - week1_monday, 7, &day);
3158 if (week < 0) {
3159 --year;
3160 week1_monday = iso_week1_monday(year);
3161 week = divmod(today - week1_monday, 7, &day);
3162 }
3163 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3164 ++year;
3165 week = 0;
3166 }
3167 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003168}
3169
3170/* Miscellaneous methods. */
3171
Tim Peters2a799bf2002-12-16 20:18:38 +00003172static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003173date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003175 if (PyDate_Check(other)) {
3176 int diff = memcmp(((PyDateTime_Date *)self)->data,
3177 ((PyDateTime_Date *)other)->data,
3178 _PyDateTime_DATE_DATASIZE);
3179 return diff_to_bool(diff, op);
3180 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003181 else
3182 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003183}
3184
3185static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303186date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003188 return build_struct_time(GET_YEAR(self),
3189 GET_MONTH(self),
3190 GET_DAY(self),
3191 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003192}
3193
Tim Peters12bf3392002-12-24 05:41:27 +00003194static PyObject *
3195date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003197 PyObject *clone;
3198 PyObject *tuple;
3199 int year = GET_YEAR(self);
3200 int month = GET_MONTH(self);
3201 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003203 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3204 &year, &month, &day))
3205 return NULL;
3206 tuple = Py_BuildValue("iii", year, month, day);
3207 if (tuple == NULL)
3208 return NULL;
3209 clone = date_new(Py_TYPE(self), tuple, NULL);
3210 Py_DECREF(tuple);
3211 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003212}
3213
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003214static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003215generic_hash(unsigned char *data, int len)
3216{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003217 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003218}
3219
3220
3221static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003222
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003223static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003224date_hash(PyDateTime_Date *self)
3225{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003226 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003227 self->hashcode = generic_hash(
3228 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003229 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003231 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003232}
3233
3234static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303235date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003237 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3238 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003239}
3240
3241static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303242date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003244 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003246 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003247}
3248
Tim Peters371935f2003-02-01 01:52:50 +00003249/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003250
Tim Petersb57f8f02003-02-01 02:54:15 +00003251/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003252static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003253date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003255 PyObject* field;
3256 field = PyBytes_FromStringAndSize((char*)self->data,
3257 _PyDateTime_DATE_DATASIZE);
3258 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003259}
3260
3261static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003262date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003264 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003265}
3266
3267static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003269 /* Class methods: */
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02003270 DATETIME_DATE_FROMTIMESTAMP_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00003271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003272 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3273 METH_CLASS,
3274 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3275 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003276
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003277 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3278 METH_CLASS,
3279 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003281 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3282 PyDoc_STR("Current date or datetime: same as "
3283 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003285 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003287 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3288 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003289
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003290 {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003291 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003293 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3294 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003296 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3297 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003299 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3300 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3301 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003303 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3304 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003306 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3307 PyDoc_STR("Return the day of the week represented by the date.\n"
3308 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003310 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3311 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3312 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003314 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3315 PyDoc_STR("Return the day of the week represented by the date.\n"
3316 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003317
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003318 {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003319 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003321 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3322 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003324 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003325};
3326
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003327static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003328PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003329
3330static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003331 date_add, /* nb_add */
3332 date_subtract, /* nb_subtract */
3333 0, /* nb_multiply */
3334 0, /* nb_remainder */
3335 0, /* nb_divmod */
3336 0, /* nb_power */
3337 0, /* nb_negative */
3338 0, /* nb_positive */
3339 0, /* nb_absolute */
3340 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003341};
3342
3343static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003344 PyVarObject_HEAD_INIT(NULL, 0)
3345 "datetime.date", /* tp_name */
3346 sizeof(PyDateTime_Date), /* tp_basicsize */
3347 0, /* tp_itemsize */
3348 0, /* tp_dealloc */
3349 0, /* tp_print */
3350 0, /* tp_getattr */
3351 0, /* tp_setattr */
3352 0, /* tp_reserved */
3353 (reprfunc)date_repr, /* tp_repr */
3354 &date_as_number, /* tp_as_number */
3355 0, /* tp_as_sequence */
3356 0, /* tp_as_mapping */
3357 (hashfunc)date_hash, /* tp_hash */
3358 0, /* tp_call */
3359 (reprfunc)date_str, /* tp_str */
3360 PyObject_GenericGetAttr, /* tp_getattro */
3361 0, /* tp_setattro */
3362 0, /* tp_as_buffer */
3363 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3364 date_doc, /* tp_doc */
3365 0, /* tp_traverse */
3366 0, /* tp_clear */
3367 date_richcompare, /* tp_richcompare */
3368 0, /* tp_weaklistoffset */
3369 0, /* tp_iter */
3370 0, /* tp_iternext */
3371 date_methods, /* tp_methods */
3372 0, /* tp_members */
3373 date_getset, /* tp_getset */
3374 0, /* tp_base */
3375 0, /* tp_dict */
3376 0, /* tp_descr_get */
3377 0, /* tp_descr_set */
3378 0, /* tp_dictoffset */
3379 0, /* tp_init */
3380 0, /* tp_alloc */
3381 date_new, /* tp_new */
3382 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003383};
3384
3385/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003386 * PyDateTime_TZInfo implementation.
3387 */
3388
3389/* This is a pure abstract base class, so doesn't do anything beyond
3390 * raising NotImplemented exceptions. Real tzinfo classes need
3391 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003392 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003393 * be subclasses of this tzinfo class, which is easy and quick to check).
3394 *
3395 * Note: For reasons having to do with pickling of subclasses, we have
3396 * to allow tzinfo objects to be instantiated. This wasn't an issue
3397 * in the Python implementation (__init__() could raise NotImplementedError
3398 * there without ill effect), but doing so in the C implementation hit a
3399 * brick wall.
3400 */
3401
3402static PyObject *
3403tzinfo_nogo(const char* methodname)
3404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003405 PyErr_Format(PyExc_NotImplementedError,
3406 "a tzinfo subclass must implement %s()",
3407 methodname);
3408 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003409}
3410
3411/* Methods. A subclass must implement these. */
3412
Tim Peters52dcce22003-01-23 16:36:11 +00003413static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003414tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003416 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003417}
3418
Tim Peters52dcce22003-01-23 16:36:11 +00003419static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003420tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003422 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003423}
3424
Tim Peters52dcce22003-01-23 16:36:11 +00003425static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003426tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003428 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003429}
3430
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003431
3432static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3433 PyDateTime_Delta *delta,
3434 int factor);
3435static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3436static PyObject *datetime_dst(PyObject *self, PyObject *);
3437
Tim Peters52dcce22003-01-23 16:36:11 +00003438static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003439tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003440{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003441 PyObject *result = NULL;
3442 PyObject *off = NULL, *dst = NULL;
3443 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003444
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003445 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003446 PyErr_SetString(PyExc_TypeError,
3447 "fromutc: argument must be a datetime");
3448 return NULL;
3449 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003450 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003451 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3452 "is not self");
3453 return NULL;
3454 }
Tim Peters52dcce22003-01-23 16:36:11 +00003455
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003456 off = datetime_utcoffset(dt, NULL);
3457 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003458 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003459 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003460 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3461 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003462 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003463 }
Tim Peters52dcce22003-01-23 16:36:11 +00003464
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003465 dst = datetime_dst(dt, NULL);
3466 if (dst == NULL)
3467 goto Fail;
3468 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003469 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3470 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003471 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003472 }
Tim Peters52dcce22003-01-23 16:36:11 +00003473
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003474 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3475 if (delta == NULL)
3476 goto Fail;
3477 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003478 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003479 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003480
3481 Py_DECREF(dst);
3482 dst = call_dst(GET_DT_TZINFO(dt), result);
3483 if (dst == NULL)
3484 goto Fail;
3485 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003486 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003487 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003488 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003489 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003490 if (result == NULL)
3491 goto Fail;
3492 }
3493 Py_DECREF(delta);
3494 Py_DECREF(dst);
3495 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003496 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003497
3498Inconsistent:
Serhiy Storchaka34fd4c22018-11-05 16:20:25 +02003499 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003500 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003501
Leo Ariasc3d95082018-02-03 18:36:10 -06003502 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003503Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003504 Py_XDECREF(off);
3505 Py_XDECREF(dst);
3506 Py_XDECREF(delta);
3507 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003509}
3510
Tim Peters2a799bf2002-12-16 20:18:38 +00003511/*
3512 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003513 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003514 */
3515
Guido van Rossum177e41a2003-01-30 22:06:23 +00003516static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303517tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003518{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003519 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003520 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003521 _Py_IDENTIFIER(__getinitargs__);
3522 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003523
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003524 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003525 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003526 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003527 Py_DECREF(getinitargs);
3528 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003529 return NULL;
3530 }
3531 }
3532 else {
3533 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003534
3535 args = PyTuple_New(0);
3536 if (args == NULL) {
3537 return NULL;
3538 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003539 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003540
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003541 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003542 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003543 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003544 Py_DECREF(getstate);
3545 if (state == NULL) {
3546 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003547 return NULL;
3548 }
3549 }
3550 else {
3551 PyObject **dictptr;
3552 PyErr_Clear();
3553 state = Py_None;
3554 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003555 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003556 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003557 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003558 Py_INCREF(state);
3559 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003561 if (state == Py_None) {
3562 Py_DECREF(state);
3563 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3564 }
3565 else
3566 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003567}
Tim Peters2a799bf2002-12-16 20:18:38 +00003568
3569static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003571 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3572 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003574 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003575 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3576 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003578 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003579 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003581 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003582 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003583
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303584 {"__reduce__", tzinfo_reduce, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003585 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003587 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003588};
3589
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003590static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003591PyDoc_STR("Abstract base class for time zone info objects.");
3592
Neal Norwitz227b5332006-03-22 09:28:35 +00003593static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003594 PyVarObject_HEAD_INIT(NULL, 0)
3595 "datetime.tzinfo", /* tp_name */
3596 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3597 0, /* tp_itemsize */
3598 0, /* tp_dealloc */
3599 0, /* tp_print */
3600 0, /* tp_getattr */
3601 0, /* tp_setattr */
3602 0, /* tp_reserved */
3603 0, /* tp_repr */
3604 0, /* tp_as_number */
3605 0, /* tp_as_sequence */
3606 0, /* tp_as_mapping */
3607 0, /* tp_hash */
3608 0, /* tp_call */
3609 0, /* tp_str */
3610 PyObject_GenericGetAttr, /* tp_getattro */
3611 0, /* tp_setattro */
3612 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003613 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003614 tzinfo_doc, /* tp_doc */
3615 0, /* tp_traverse */
3616 0, /* tp_clear */
3617 0, /* tp_richcompare */
3618 0, /* tp_weaklistoffset */
3619 0, /* tp_iter */
3620 0, /* tp_iternext */
3621 tzinfo_methods, /* tp_methods */
3622 0, /* tp_members */
3623 0, /* tp_getset */
3624 0, /* tp_base */
3625 0, /* tp_dict */
3626 0, /* tp_descr_get */
3627 0, /* tp_descr_set */
3628 0, /* tp_dictoffset */
3629 0, /* tp_init */
3630 0, /* tp_alloc */
3631 PyType_GenericNew, /* tp_new */
3632 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003633};
3634
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003635static char *timezone_kws[] = {"offset", "name", NULL};
3636
3637static PyObject *
3638timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3639{
3640 PyObject *offset;
3641 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003642 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3643 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003644 return new_timezone(offset, name);
3645
3646 return NULL;
3647}
3648
3649static void
3650timezone_dealloc(PyDateTime_TimeZone *self)
3651{
3652 Py_CLEAR(self->offset);
3653 Py_CLEAR(self->name);
3654 Py_TYPE(self)->tp_free((PyObject *)self);
3655}
3656
3657static PyObject *
3658timezone_richcompare(PyDateTime_TimeZone *self,
3659 PyDateTime_TimeZone *other, int op)
3660{
Brian Curtindfc80e32011-08-10 20:28:54 -05003661 if (op != Py_EQ && op != Py_NE)
3662 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003663 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003664 if (op == Py_EQ)
3665 Py_RETURN_FALSE;
3666 else
3667 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003668 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003669 return delta_richcompare(self->offset, other->offset, op);
3670}
3671
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003672static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003673timezone_hash(PyDateTime_TimeZone *self)
3674{
3675 return delta_hash((PyDateTime_Delta *)self->offset);
3676}
3677
3678/* Check argument type passed to tzname, utcoffset, or dst methods.
3679 Returns 0 for good argument. Returns -1 and sets exception info
3680 otherwise.
3681 */
3682static int
3683_timezone_check_argument(PyObject *dt, const char *meth)
3684{
3685 if (dt == Py_None || PyDateTime_Check(dt))
3686 return 0;
3687 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3688 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3689 return -1;
3690}
3691
3692static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003693timezone_repr(PyDateTime_TimeZone *self)
3694{
3695 /* Note that although timezone is not subclassable, it is convenient
3696 to use Py_TYPE(self)->tp_name here. */
3697 const char *type_name = Py_TYPE(self)->tp_name;
3698
3699 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3700 return PyUnicode_FromFormat("%s.utc", type_name);
3701
3702 if (self->name == NULL)
3703 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3704
3705 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3706 self->name);
3707}
3708
3709
3710static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003711timezone_str(PyDateTime_TimeZone *self)
3712{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003713 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003714 PyObject *offset;
3715 char sign;
3716
3717 if (self->name != NULL) {
3718 Py_INCREF(self->name);
3719 return self->name;
3720 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003721 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003722 (GET_TD_DAYS(self->offset) == 0 &&
3723 GET_TD_SECONDS(self->offset) == 0 &&
3724 GET_TD_MICROSECONDS(self->offset) == 0))
3725 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003726 /* Offset is normalized, so it is negative if days < 0 */
3727 if (GET_TD_DAYS(self->offset) < 0) {
3728 sign = '-';
3729 offset = delta_negative((PyDateTime_Delta *)self->offset);
3730 if (offset == NULL)
3731 return NULL;
3732 }
3733 else {
3734 sign = '+';
3735 offset = self->offset;
3736 Py_INCREF(offset);
3737 }
3738 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003739 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003740 seconds = GET_TD_SECONDS(offset);
3741 Py_DECREF(offset);
3742 minutes = divmod(seconds, 60, &seconds);
3743 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003744 if (microseconds != 0) {
3745 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3746 sign, hours, minutes,
3747 seconds, microseconds);
3748 }
3749 if (seconds != 0) {
3750 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3751 sign, hours, minutes, seconds);
3752 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003753 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003754}
3755
3756static PyObject *
3757timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3758{
3759 if (_timezone_check_argument(dt, "tzname") == -1)
3760 return NULL;
3761
3762 return timezone_str(self);
3763}
3764
3765static PyObject *
3766timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3767{
3768 if (_timezone_check_argument(dt, "utcoffset") == -1)
3769 return NULL;
3770
3771 Py_INCREF(self->offset);
3772 return self->offset;
3773}
3774
3775static PyObject *
3776timezone_dst(PyObject *self, PyObject *dt)
3777{
3778 if (_timezone_check_argument(dt, "dst") == -1)
3779 return NULL;
3780
3781 Py_RETURN_NONE;
3782}
3783
3784static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003785timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3786{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003787 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003788 PyErr_SetString(PyExc_TypeError,
3789 "fromutc: argument must be a datetime");
3790 return NULL;
3791 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003792 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003793 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3794 "is not self");
3795 return NULL;
3796 }
3797
3798 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3799}
3800
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003801static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303802timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003803{
3804 if (self->name == NULL)
3805 return Py_BuildValue("(O)", self->offset);
3806 return Py_BuildValue("(OO)", self->offset, self->name);
3807}
3808
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003809static PyMethodDef timezone_methods[] = {
3810 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3811 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003812 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003813
3814 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003815 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003816
3817 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003818 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003819
3820 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3821 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3822
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003823 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3824 PyDoc_STR("pickle support")},
3825
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003826 {NULL, NULL}
3827};
3828
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003829static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003830PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3831
3832static PyTypeObject PyDateTime_TimeZoneType = {
3833 PyVarObject_HEAD_INIT(NULL, 0)
3834 "datetime.timezone", /* tp_name */
3835 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3836 0, /* tp_itemsize */
3837 (destructor)timezone_dealloc, /* tp_dealloc */
3838 0, /* tp_print */
3839 0, /* tp_getattr */
3840 0, /* tp_setattr */
3841 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003842 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003843 0, /* tp_as_number */
3844 0, /* tp_as_sequence */
3845 0, /* tp_as_mapping */
3846 (hashfunc)timezone_hash, /* tp_hash */
3847 0, /* tp_call */
3848 (reprfunc)timezone_str, /* tp_str */
3849 0, /* tp_getattro */
3850 0, /* tp_setattro */
3851 0, /* tp_as_buffer */
3852 Py_TPFLAGS_DEFAULT, /* tp_flags */
3853 timezone_doc, /* tp_doc */
3854 0, /* tp_traverse */
3855 0, /* tp_clear */
3856 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3857 0, /* tp_weaklistoffset */
3858 0, /* tp_iter */
3859 0, /* tp_iternext */
3860 timezone_methods, /* tp_methods */
3861 0, /* tp_members */
3862 0, /* tp_getset */
3863 &PyDateTime_TZInfoType, /* tp_base */
3864 0, /* tp_dict */
3865 0, /* tp_descr_get */
3866 0, /* tp_descr_set */
3867 0, /* tp_dictoffset */
3868 0, /* tp_init */
3869 0, /* tp_alloc */
3870 timezone_new, /* tp_new */
3871};
3872
Tim Peters2a799bf2002-12-16 20:18:38 +00003873/*
Tim Peters37f39822003-01-10 03:49:02 +00003874 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003875 */
3876
Tim Peters37f39822003-01-10 03:49:02 +00003877/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003878 */
3879
3880static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003881time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003884}
3885
Tim Peters37f39822003-01-10 03:49:02 +00003886static PyObject *
3887time_minute(PyDateTime_Time *self, void *unused)
3888{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003889 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003890}
3891
3892/* The name time_second conflicted with some platform header file. */
3893static PyObject *
3894py_time_second(PyDateTime_Time *self, void *unused)
3895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003896 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003897}
3898
3899static PyObject *
3900time_microsecond(PyDateTime_Time *self, void *unused)
3901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003902 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003903}
3904
3905static PyObject *
3906time_tzinfo(PyDateTime_Time *self, void *unused)
3907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003908 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3909 Py_INCREF(result);
3910 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003911}
3912
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003913static PyObject *
3914time_fold(PyDateTime_Time *self, void *unused)
3915{
3916 return PyLong_FromLong(TIME_GET_FOLD(self));
3917}
3918
Tim Peters37f39822003-01-10 03:49:02 +00003919static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003920 {"hour", (getter)time_hour},
3921 {"minute", (getter)time_minute},
3922 {"second", (getter)py_time_second},
3923 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003924 {"tzinfo", (getter)time_tzinfo},
3925 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003926 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003927};
3928
3929/*
3930 * Constructors.
3931 */
3932
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003933static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003934 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003935
Tim Peters2a799bf2002-12-16 20:18:38 +00003936static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02003937time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
3938{
3939 PyDateTime_Time *me;
3940 char aware = (char)(tzinfo != Py_None);
3941
3942 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
3943 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
3944 return NULL;
3945 }
3946
3947 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3948 if (me != NULL) {
3949 const char *pdata = PyBytes_AS_STRING(state);
3950
3951 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3952 me->hashcode = -1;
3953 me->hastzinfo = aware;
3954 if (aware) {
3955 Py_INCREF(tzinfo);
3956 me->tzinfo = tzinfo;
3957 }
3958 if (pdata[0] & (1 << 7)) {
3959 me->data[0] -= 128;
3960 me->fold = 1;
3961 }
3962 else {
3963 me->fold = 0;
3964 }
3965 }
3966 return (PyObject *)me;
3967}
3968
3969static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003970time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003972 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003973 int hour = 0;
3974 int minute = 0;
3975 int second = 0;
3976 int usecond = 0;
3977 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003978 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02003981 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
3982 PyObject *state = PyTuple_GET_ITEM(args, 0);
3983 if (PyTuple_GET_SIZE(args) == 2) {
3984 tzinfo = PyTuple_GET_ITEM(args, 1);
3985 }
3986 if (PyBytes_Check(state)) {
3987 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3988 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
3989 {
3990 return time_from_pickle(type, state, tzinfo);
3991 }
3992 }
3993 else if (PyUnicode_Check(state)) {
3994 if (PyUnicode_READY(state)) {
3995 return NULL;
3996 }
3997 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
3998 (0x7F & PyUnicode_READ_CHAR(state, 2)) < 24)
3999 {
4000 state = PyUnicode_AsLatin1String(state);
4001 if (state == NULL) {
4002 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4003 /* More informative error message. */
4004 PyErr_SetString(PyExc_ValueError,
4005 "Failed to encode latin1 string when unpickling "
4006 "a time object. "
4007 "pickle.load(data, encoding='latin1') is assumed.");
4008 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004009 return NULL;
4010 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004011 self = time_from_pickle(type, state, tzinfo);
4012 Py_DECREF(state);
4013 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004014 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004015 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004016 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004017 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004018
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004019 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004020 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004021 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004022 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4023 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004024 }
4025 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004026}
4027
4028/*
4029 * Destructor.
4030 */
4031
4032static void
Tim Peters37f39822003-01-10 03:49:02 +00004033time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004035 if (HASTZINFO(self)) {
4036 Py_XDECREF(self->tzinfo);
4037 }
4038 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004039}
4040
4041/*
Tim Peters855fe882002-12-22 03:43:39 +00004042 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004043 */
4044
Tim Peters2a799bf2002-12-16 20:18:38 +00004045/* These are all METH_NOARGS, so don't need to check the arglist. */
4046static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004047time_utcoffset(PyObject *self, PyObject *unused) {
4048 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004049}
4050
4051static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004052time_dst(PyObject *self, PyObject *unused) {
4053 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004054}
4055
4056static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004057time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004058 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004059}
4060
4061/*
Tim Peters37f39822003-01-10 03:49:02 +00004062 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004063 */
4064
4065static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004066time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004068 const char *type_name = Py_TYPE(self)->tp_name;
4069 int h = TIME_GET_HOUR(self);
4070 int m = TIME_GET_MINUTE(self);
4071 int s = TIME_GET_SECOND(self);
4072 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004073 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004074 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004076 if (us)
4077 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4078 type_name, h, m, s, us);
4079 else if (s)
4080 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4081 type_name, h, m, s);
4082 else
4083 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4084 if (result != NULL && HASTZINFO(self))
4085 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004086 if (result != NULL && fold)
4087 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004088 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004089}
4090
Tim Peters37f39822003-01-10 03:49:02 +00004091static PyObject *
4092time_str(PyDateTime_Time *self)
4093{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07004094 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00004095}
Tim Peters2a799bf2002-12-16 20:18:38 +00004096
4097static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004098time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004100 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004101 char *timespec = NULL;
4102 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004103 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004104 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004105 static char *specs[][2] = {
4106 {"hours", "%02d"},
4107 {"minutes", "%02d:%02d"},
4108 {"seconds", "%02d:%02d:%02d"},
4109 {"milliseconds", "%02d:%02d:%02d.%03d"},
4110 {"microseconds", "%02d:%02d:%02d.%06d"},
4111 };
4112 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004113
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004114 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4115 return NULL;
4116
4117 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4118 if (us == 0) {
4119 /* seconds */
4120 given_spec = 2;
4121 }
4122 else {
4123 /* microseconds */
4124 given_spec = 4;
4125 }
4126 }
4127 else {
4128 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4129 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4130 if (given_spec == 3) {
4131 /* milliseconds */
4132 us = us / 1000;
4133 }
4134 break;
4135 }
4136 }
4137 }
4138
4139 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4140 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4141 return NULL;
4142 }
4143 else {
4144 result = PyUnicode_FromFormat(specs[given_spec][1],
4145 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4146 TIME_GET_SECOND(self), us);
4147 }
Tim Peters37f39822003-01-10 03:49:02 +00004148
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004149 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004150 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004152 /* We need to append the UTC offset. */
4153 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4154 Py_None) < 0) {
4155 Py_DECREF(result);
4156 return NULL;
4157 }
4158 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4159 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004160}
4161
Tim Peters37f39822003-01-10 03:49:02 +00004162static PyObject *
4163time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004165 PyObject *result;
4166 PyObject *tuple;
4167 PyObject *format;
4168 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004170 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4171 &format))
4172 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004174 /* Python's strftime does insane things with the year part of the
4175 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004176 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 */
4178 tuple = Py_BuildValue("iiiiiiiii",
4179 1900, 1, 1, /* year, month, day */
4180 TIME_GET_HOUR(self),
4181 TIME_GET_MINUTE(self),
4182 TIME_GET_SECOND(self),
4183 0, 1, -1); /* weekday, daynum, dst */
4184 if (tuple == NULL)
4185 return NULL;
4186 assert(PyTuple_Size(tuple) == 9);
4187 result = wrap_strftime((PyObject *)self, format, tuple,
4188 Py_None);
4189 Py_DECREF(tuple);
4190 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004191}
Tim Peters2a799bf2002-12-16 20:18:38 +00004192
4193/*
4194 * Miscellaneous methods.
4195 */
4196
Tim Peters37f39822003-01-10 03:49:02 +00004197static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004198time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004199{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004200 PyObject *result = NULL;
4201 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004202 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004203
Brian Curtindfc80e32011-08-10 20:28:54 -05004204 if (! PyTime_Check(other))
4205 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004206
4207 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004208 diff = memcmp(((PyDateTime_Time *)self)->data,
4209 ((PyDateTime_Time *)other)->data,
4210 _PyDateTime_TIME_DATASIZE);
4211 return diff_to_bool(diff, op);
4212 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004213 offset1 = time_utcoffset(self, NULL);
4214 if (offset1 == NULL)
4215 return NULL;
4216 offset2 = time_utcoffset(other, NULL);
4217 if (offset2 == NULL)
4218 goto done;
4219 /* If they're both naive, or both aware and have the same offsets,
4220 * we get off cheap. Note that if they're both naive, offset1 ==
4221 * offset2 == Py_None at this point.
4222 */
4223 if ((offset1 == offset2) ||
4224 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4225 delta_cmp(offset1, offset2) == 0)) {
4226 diff = memcmp(((PyDateTime_Time *)self)->data,
4227 ((PyDateTime_Time *)other)->data,
4228 _PyDateTime_TIME_DATASIZE);
4229 result = diff_to_bool(diff, op);
4230 }
4231 /* The hard case: both aware with different UTC offsets */
4232 else if (offset1 != Py_None && offset2 != Py_None) {
4233 int offsecs1, offsecs2;
4234 assert(offset1 != offset2); /* else last "if" handled it */
4235 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4236 TIME_GET_MINUTE(self) * 60 +
4237 TIME_GET_SECOND(self) -
4238 GET_TD_DAYS(offset1) * 86400 -
4239 GET_TD_SECONDS(offset1);
4240 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4241 TIME_GET_MINUTE(other) * 60 +
4242 TIME_GET_SECOND(other) -
4243 GET_TD_DAYS(offset2) * 86400 -
4244 GET_TD_SECONDS(offset2);
4245 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004246 if (diff == 0)
4247 diff = TIME_GET_MICROSECOND(self) -
4248 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004249 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004250 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004251 else if (op == Py_EQ) {
4252 result = Py_False;
4253 Py_INCREF(result);
4254 }
4255 else if (op == Py_NE) {
4256 result = Py_True;
4257 Py_INCREF(result);
4258 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004259 else {
4260 PyErr_SetString(PyExc_TypeError,
4261 "can't compare offset-naive and "
4262 "offset-aware times");
4263 }
4264 done:
4265 Py_DECREF(offset1);
4266 Py_XDECREF(offset2);
4267 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004268}
4269
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004270static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004271time_hash(PyDateTime_Time *self)
4272{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004273 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004274 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004275 if (TIME_GET_FOLD(self)) {
4276 self0 = new_time_ex2(TIME_GET_HOUR(self),
4277 TIME_GET_MINUTE(self),
4278 TIME_GET_SECOND(self),
4279 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004280 HASTZINFO(self) ? self->tzinfo : Py_None,
4281 0, Py_TYPE(self));
4282 if (self0 == NULL)
4283 return -1;
4284 }
4285 else {
4286 self0 = (PyObject *)self;
4287 Py_INCREF(self0);
4288 }
4289 offset = time_utcoffset(self0, NULL);
4290 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004291
4292 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004293 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004295 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004296 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004297 self->hashcode = generic_hash(
4298 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004299 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004300 PyObject *temp1, *temp2;
4301 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004302 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004303 seconds = TIME_GET_HOUR(self) * 3600 +
4304 TIME_GET_MINUTE(self) * 60 +
4305 TIME_GET_SECOND(self);
4306 microseconds = TIME_GET_MICROSECOND(self);
4307 temp1 = new_delta(0, seconds, microseconds, 1);
4308 if (temp1 == NULL) {
4309 Py_DECREF(offset);
4310 return -1;
4311 }
4312 temp2 = delta_subtract(temp1, offset);
4313 Py_DECREF(temp1);
4314 if (temp2 == NULL) {
4315 Py_DECREF(offset);
4316 return -1;
4317 }
4318 self->hashcode = PyObject_Hash(temp2);
4319 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004320 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004321 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004322 }
4323 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004324}
Tim Peters2a799bf2002-12-16 20:18:38 +00004325
Tim Peters12bf3392002-12-24 05:41:27 +00004326static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004327time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004329 PyObject *clone;
4330 PyObject *tuple;
4331 int hh = TIME_GET_HOUR(self);
4332 int mm = TIME_GET_MINUTE(self);
4333 int ss = TIME_GET_SECOND(self);
4334 int us = TIME_GET_MICROSECOND(self);
4335 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004336 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004337
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004338 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004339 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004340 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004341 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004342 if (fold != 0 && fold != 1) {
4343 PyErr_SetString(PyExc_ValueError,
4344 "fold must be either 0 or 1");
4345 return NULL;
4346 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004347 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4348 if (tuple == NULL)
4349 return NULL;
4350 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004351 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004352 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004353 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004354 Py_DECREF(tuple);
4355 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004356}
4357
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004358static PyObject *
4359time_fromisoformat(PyObject *cls, PyObject *tstr) {
4360 assert(tstr != NULL);
4361
4362 if (!PyUnicode_Check(tstr)) {
4363 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4364 return NULL;
4365 }
4366
4367 Py_ssize_t len;
4368 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4369
Paul Ganssle096329f2018-08-23 11:06:20 -04004370 if (p == NULL) {
4371 goto invalid_string_error;
4372 }
4373
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004374 int hour = 0, minute = 0, second = 0, microsecond = 0;
4375 int tzoffset, tzimicrosecond = 0;
4376 int rv = parse_isoformat_time(p, len,
4377 &hour, &minute, &second, &microsecond,
4378 &tzoffset, &tzimicrosecond);
4379
4380 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04004381 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004382 }
4383
4384 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4385 tzimicrosecond);
4386
4387 if (tzinfo == NULL) {
4388 return NULL;
4389 }
4390
4391 PyObject *t;
4392 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4393 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4394 } else {
4395 t = PyObject_CallFunction(cls, "iiiiO",
4396 hour, minute, second, microsecond, tzinfo);
4397 }
4398
4399 Py_DECREF(tzinfo);
4400 return t;
Paul Ganssle096329f2018-08-23 11:06:20 -04004401
4402invalid_string_error:
4403 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4404 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004405}
4406
4407
Tim Peters371935f2003-02-01 01:52:50 +00004408/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004409
Tim Peters33e0f382003-01-10 02:05:14 +00004410/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004411 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4412 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004413 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004414 */
4415static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004416time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004418 PyObject *basestate;
4419 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004421 basestate = PyBytes_FromStringAndSize((char *)self->data,
4422 _PyDateTime_TIME_DATASIZE);
4423 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004424 if (proto > 3 && TIME_GET_FOLD(self))
4425 /* Set the first bit of the first byte */
4426 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004427 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4428 result = PyTuple_Pack(1, basestate);
4429 else
4430 result = PyTuple_Pack(2, basestate, self->tzinfo);
4431 Py_DECREF(basestate);
4432 }
4433 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004434}
4435
4436static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004437time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004438{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004439 int proto;
4440 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004441 return NULL;
4442
4443 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004444}
4445
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004446static PyObject *
4447time_reduce(PyDateTime_Time *self, PyObject *arg)
4448{
4449 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4450}
4451
Tim Peters37f39822003-01-10 03:49:02 +00004452static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004453
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004454 {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS,
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004455 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4456 "[+HH:MM].\n\n"
4457 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004458
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004459 {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004460 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004462 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4463 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004465 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4466 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004468 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4469 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004471 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4472 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004473
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004474 {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004475 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004476
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004477 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4478 PyDoc_STR("string -> time from time.isoformat() output")},
4479
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004480 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004481 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004482
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004483 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4484 PyDoc_STR("__reduce__() -> (cls, state)")},
4485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004486 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004487};
4488
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004489static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004490PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4491\n\
4492All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004493a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004494
Neal Norwitz227b5332006-03-22 09:28:35 +00004495static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004496 PyVarObject_HEAD_INIT(NULL, 0)
4497 "datetime.time", /* tp_name */
4498 sizeof(PyDateTime_Time), /* tp_basicsize */
4499 0, /* tp_itemsize */
4500 (destructor)time_dealloc, /* tp_dealloc */
4501 0, /* tp_print */
4502 0, /* tp_getattr */
4503 0, /* tp_setattr */
4504 0, /* tp_reserved */
4505 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004506 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004507 0, /* tp_as_sequence */
4508 0, /* tp_as_mapping */
4509 (hashfunc)time_hash, /* tp_hash */
4510 0, /* tp_call */
4511 (reprfunc)time_str, /* tp_str */
4512 PyObject_GenericGetAttr, /* tp_getattro */
4513 0, /* tp_setattro */
4514 0, /* tp_as_buffer */
4515 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4516 time_doc, /* tp_doc */
4517 0, /* tp_traverse */
4518 0, /* tp_clear */
4519 time_richcompare, /* tp_richcompare */
4520 0, /* tp_weaklistoffset */
4521 0, /* tp_iter */
4522 0, /* tp_iternext */
4523 time_methods, /* tp_methods */
4524 0, /* tp_members */
4525 time_getset, /* tp_getset */
4526 0, /* tp_base */
4527 0, /* tp_dict */
4528 0, /* tp_descr_get */
4529 0, /* tp_descr_set */
4530 0, /* tp_dictoffset */
4531 0, /* tp_init */
4532 time_alloc, /* tp_alloc */
4533 time_new, /* tp_new */
4534 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004535};
4536
4537/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004538 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004539 */
4540
Tim Petersa9bc1682003-01-11 03:39:11 +00004541/* Accessor properties. Properties for day, month, and year are inherited
4542 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004543 */
4544
4545static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004546datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004548 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004549}
4550
Tim Petersa9bc1682003-01-11 03:39:11 +00004551static PyObject *
4552datetime_minute(PyDateTime_DateTime *self, void *unused)
4553{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004554 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004555}
4556
4557static PyObject *
4558datetime_second(PyDateTime_DateTime *self, void *unused)
4559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004560 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004561}
4562
4563static PyObject *
4564datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4565{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004566 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004567}
4568
4569static PyObject *
4570datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4571{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004572 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4573 Py_INCREF(result);
4574 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004575}
4576
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004577static PyObject *
4578datetime_fold(PyDateTime_DateTime *self, void *unused)
4579{
4580 return PyLong_FromLong(DATE_GET_FOLD(self));
4581}
4582
Tim Petersa9bc1682003-01-11 03:39:11 +00004583static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004584 {"hour", (getter)datetime_hour},
4585 {"minute", (getter)datetime_minute},
4586 {"second", (getter)datetime_second},
4587 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004588 {"tzinfo", (getter)datetime_tzinfo},
4589 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004590 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004591};
4592
4593/*
4594 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004595 */
4596
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004597static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004598 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004599 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004600};
4601
Tim Peters2a799bf2002-12-16 20:18:38 +00004602static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004603datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4604{
4605 PyDateTime_DateTime *me;
4606 char aware = (char)(tzinfo != Py_None);
4607
4608 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4609 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4610 return NULL;
4611 }
4612
4613 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4614 if (me != NULL) {
4615 const char *pdata = PyBytes_AS_STRING(state);
4616
4617 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4618 me->hashcode = -1;
4619 me->hastzinfo = aware;
4620 if (aware) {
4621 Py_INCREF(tzinfo);
4622 me->tzinfo = tzinfo;
4623 }
4624 if (pdata[2] & (1 << 7)) {
4625 me->data[2] -= 128;
4626 me->fold = 1;
4627 }
4628 else {
4629 me->fold = 0;
4630 }
4631 }
4632 return (PyObject *)me;
4633}
4634
4635static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004636datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004638 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 int year;
4640 int month;
4641 int day;
4642 int hour = 0;
4643 int minute = 0;
4644 int second = 0;
4645 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004646 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004647 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004649 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004650 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4651 PyObject *state = PyTuple_GET_ITEM(args, 0);
4652 if (PyTuple_GET_SIZE(args) == 2) {
4653 tzinfo = PyTuple_GET_ITEM(args, 1);
4654 }
4655 if (PyBytes_Check(state)) {
4656 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4657 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4658 {
4659 return datetime_from_pickle(type, state, tzinfo);
4660 }
4661 }
4662 else if (PyUnicode_Check(state)) {
4663 if (PyUnicode_READY(state)) {
4664 return NULL;
4665 }
4666 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4667 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4668 {
4669 state = PyUnicode_AsLatin1String(state);
4670 if (state == NULL) {
4671 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4672 /* More informative error message. */
4673 PyErr_SetString(PyExc_ValueError,
4674 "Failed to encode latin1 string when unpickling "
4675 "a datetime object. "
4676 "pickle.load(data, encoding='latin1') is assumed.");
4677 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004678 return NULL;
4679 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004680 self = datetime_from_pickle(type, state, tzinfo);
4681 Py_DECREF(state);
4682 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004684 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004685 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004686 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004687
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004688 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004689 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004690 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004691 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004692 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004693 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004694 }
4695 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004696}
4697
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004698/* TM_FUNC is the shared type of _PyTime_localtime() and
4699 * _PyTime_gmtime(). */
4700typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004701
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004702/* As of version 2015f max fold in IANA database is
4703 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004704static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004705/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004706static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004707
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004708static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004709utc_to_seconds(int year, int month, int day,
4710 int hour, int minute, int second)
4711{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004712 long long ordinal;
4713
4714 /* ymd_to_ord() doesn't support year <= 0 */
4715 if (year < MINYEAR || year > MAXYEAR) {
4716 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4717 return -1;
4718 }
4719
4720 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004721 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4722}
4723
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004724static long long
4725local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004726{
4727 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004728 time_t t;
4729 u -= epoch;
4730 t = u;
4731 if (t != u) {
4732 PyErr_SetString(PyExc_OverflowError,
4733 "timestamp out of range for platform time_t");
4734 return -1;
4735 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004736 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004737 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004738 return utc_to_seconds(local_time.tm_year + 1900,
4739 local_time.tm_mon + 1,
4740 local_time.tm_mday,
4741 local_time.tm_hour,
4742 local_time.tm_min,
4743 local_time.tm_sec);
4744}
4745
Tim Petersa9bc1682003-01-11 03:39:11 +00004746/* Internal helper.
4747 * Build datetime from a time_t and a distinct count of microseconds.
4748 * Pass localtime or gmtime for f, to control the interpretation of timet.
4749 */
4750static PyObject *
4751datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004752 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004753{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004754 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004755 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004756
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004757 if (f(timet, &tm) != 0)
4758 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004759
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004760 year = tm.tm_year + 1900;
4761 month = tm.tm_mon + 1;
4762 day = tm.tm_mday;
4763 hour = tm.tm_hour;
4764 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004765 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004766 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004767 * except to the extent that passing them on to the datetime
4768 * constructor would raise ValueError for a reason that
4769 * made no sense to the user.
4770 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004771 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004772
Victor Stinnerb67f0962017-02-10 10:34:02 +01004773 /* local timezone requires to compute fold */
Ammar Askar96d1e692018-07-25 09:54:58 -07004774 if (tzinfo == Py_None && f == _PyTime_localtime
4775 /* On Windows, passing a negative value to local results
4776 * in an OSError because localtime_s on Windows does
4777 * not support negative timestamps. Unfortunately this
4778 * means that fold detection for time values between
4779 * 0 and max_fold_seconds will result in an identical
4780 * error since we subtract max_fold_seconds to detect a
4781 * fold. However, since we know there haven't been any
4782 * folds in the interval [0, max_fold_seconds) in any
4783 * timezone, we can hackily just forego fold detection
4784 * for this time range.
4785 */
4786#ifdef MS_WINDOWS
4787 && (timet - max_fold_seconds > 0)
4788#endif
4789 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004790 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004791
4792 result_seconds = utc_to_seconds(year, month, day,
4793 hour, minute, second);
4794 /* Probe max_fold_seconds to detect a fold. */
4795 probe_seconds = local(epoch + timet - max_fold_seconds);
4796 if (probe_seconds == -1)
4797 return NULL;
4798 transition = result_seconds - probe_seconds - max_fold_seconds;
4799 if (transition < 0) {
4800 probe_seconds = local(epoch + timet + transition);
4801 if (probe_seconds == -1)
4802 return NULL;
4803 if (probe_seconds == result_seconds)
4804 fold = 1;
4805 }
4806 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004807 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4808 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004809}
4810
4811/* Internal helper.
4812 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4813 * to control the interpretation of the timestamp. Since a double doesn't
4814 * have enough bits to cover a datetime's full range of precision, it's
4815 * better to call datetime_from_timet_and_us provided you have a way
4816 * to get that much precision (e.g., C time() isn't good enough).
4817 */
4818static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004819datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004820 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004822 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004823 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004824
Victor Stinnere4a994d2015-03-30 01:10:14 +02004825 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004826 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004827 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004828
Victor Stinner21f58932012-03-14 00:15:40 +01004829 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004830}
4831
4832/* Internal helper.
4833 * Build most accurate possible datetime for current time. Pass localtime or
4834 * gmtime for f as appropriate.
4835 */
4836static PyObject *
4837datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4838{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004839 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004840 time_t secs;
4841 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004842
Victor Stinner1e2b6882015-09-18 13:23:02 +02004843 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004844 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004845 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004846
Victor Stinner1e2b6882015-09-18 13:23:02 +02004847 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004848}
4849
Larry Hastings61272b72014-01-07 12:41:53 -08004850/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004851
4852@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004853datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004854
4855 tz: object = None
4856 Timezone object.
4857
4858Returns new datetime object representing current time local to tz.
4859
4860If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004861[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004862
Larry Hastings31826802013-10-19 00:09:25 -07004863static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004864datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004865/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004866{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004867 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004868
Larry Hastings31826802013-10-19 00:09:25 -07004869 /* Return best possible local time -- this isn't constrained by the
4870 * precision of a timestamp.
4871 */
4872 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004873 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004874
Larry Hastings5c661892014-01-24 06:17:25 -08004875 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004876 tz == Py_None ? _PyTime_localtime :
4877 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004878 tz);
4879 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004880 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004881 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 }
4883 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004884}
4885
Tim Petersa9bc1682003-01-11 03:39:11 +00004886/* Return best possible UTC time -- this isn't constrained by the
4887 * precision of a timestamp.
4888 */
4889static PyObject *
4890datetime_utcnow(PyObject *cls, PyObject *dummy)
4891{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004892 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004893}
4894
Tim Peters2a799bf2002-12-16 20:18:38 +00004895/* Return new local datetime from timestamp (Python timestamp -- a double). */
4896static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004897datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004898{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004899 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004900 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004901 PyObject *tzinfo = Py_None;
4902 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004903
Victor Stinner5d272cc2012-03-13 13:35:55 +01004904 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004905 keywords, &timestamp, &tzinfo))
4906 return NULL;
4907 if (check_tzinfo_subclass(tzinfo) < 0)
4908 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004910 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004911 tzinfo == Py_None ? _PyTime_localtime :
4912 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004913 timestamp,
4914 tzinfo);
4915 if (self != NULL && tzinfo != Py_None) {
4916 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004917 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004918 }
4919 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004920}
4921
Tim Petersa9bc1682003-01-11 03:39:11 +00004922/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4923static PyObject *
4924datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4925{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004926 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004927 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004928
Victor Stinner5d272cc2012-03-13 13:35:55 +01004929 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004930 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004931 Py_None);
4932 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004933}
4934
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004935/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004936static PyObject *
4937datetime_strptime(PyObject *cls, PyObject *args)
4938{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004939 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004940 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004941 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004942
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004943 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004944 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004945
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004946 if (module == NULL) {
4947 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004948 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004949 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004950 }
Victor Stinner20401de2016-12-09 15:24:31 +01004951 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4952 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004953}
4954
Tim Petersa9bc1682003-01-11 03:39:11 +00004955/* Return new datetime from date/datetime and time arguments. */
4956static PyObject *
4957datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4958{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004959 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004960 PyObject *date;
4961 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004962 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004963 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004964
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004965 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004966 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004967 &PyDateTime_TimeType, &time, &tzinfo)) {
4968 if (tzinfo == NULL) {
4969 if (HASTZINFO(time))
4970 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4971 else
4972 tzinfo = Py_None;
4973 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004974 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
4975 GET_MONTH(date),
4976 GET_DAY(date),
4977 TIME_GET_HOUR(time),
4978 TIME_GET_MINUTE(time),
4979 TIME_GET_SECOND(time),
4980 TIME_GET_MICROSECOND(time),
4981 tzinfo,
4982 TIME_GET_FOLD(time),
4983 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004984 }
4985 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004986}
Tim Peters2a799bf2002-12-16 20:18:38 +00004987
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004988static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04004989_sanitize_isoformat_str(PyObject *dtstr)
4990{
Paul Ganssle096329f2018-08-23 11:06:20 -04004991 // `fromisoformat` allows surrogate characters in exactly one position,
4992 // the separator; to allow datetime_fromisoformat to make the simplifying
4993 // assumption that all valid strings can be encoded in UTF-8, this function
4994 // replaces any surrogate character separators with `T`.
Paul Ganssle3df85402018-10-22 12:32:52 -04004995 //
4996 // The result of this, if not NULL, returns a new reference
Paul Ganssle096329f2018-08-23 11:06:20 -04004997 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Paul Ganssle3df85402018-10-22 12:32:52 -04004998 if (len < 0) {
4999 return NULL;
5000 }
5001
5002 if (len <= 10 ||
5003 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
5004 Py_INCREF(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005005 return dtstr;
5006 }
5007
Paul Ganssle3df85402018-10-22 12:32:52 -04005008 PyObject *str_out = _PyUnicode_Copy(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005009 if (str_out == NULL) {
5010 return NULL;
5011 }
5012
Paul Ganssle3df85402018-10-22 12:32:52 -04005013 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005014 Py_DECREF(str_out);
5015 return NULL;
5016 }
5017
Paul Ganssle096329f2018-08-23 11:06:20 -04005018 return str_out;
5019}
5020
5021static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005022datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5023{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005024 assert(dtstr != NULL);
5025
5026 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005027 PyErr_SetString(PyExc_TypeError,
5028 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005029 return NULL;
5030 }
5031
Paul Ganssle3df85402018-10-22 12:32:52 -04005032 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5033 if (dtstr_clean == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005034 goto error;
5035 }
5036
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005037 Py_ssize_t len;
Paul Ganssle3df85402018-10-22 12:32:52 -04005038 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04005039
5040 if (dt_ptr == NULL) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005041 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5042 // Encoding errors are invalid string errors at this point
5043 goto invalid_string_error;
5044 }
5045 else {
5046 goto error;
5047 }
Paul Ganssle096329f2018-08-23 11:06:20 -04005048 }
5049
5050 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005051
5052 int year = 0, month = 0, day = 0;
5053 int hour = 0, minute = 0, second = 0, microsecond = 0;
5054 int tzoffset = 0, tzusec = 0;
5055
5056 // date has a fixed length of 10
5057 int rv = parse_isoformat_date(p, &year, &month, &day);
5058
5059 if (!rv && len > 10) {
5060 // In UTF-8, the length of multi-byte characters is encoded in the MSB
5061 if ((p[10] & 0x80) == 0) {
5062 p += 11;
Paul Ganssle3df85402018-10-22 12:32:52 -04005063 }
5064 else {
5065 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005066 case 0xe0:
5067 p += 13;
5068 break;
5069 case 0xf0:
5070 p += 14;
5071 break;
5072 default:
5073 p += 12;
5074 break;
5075 }
5076 }
5077
5078 len -= (p - dt_ptr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005079 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5080 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005081 }
5082 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005083 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005084 }
5085
Paul Ganssle3df85402018-10-22 12:32:52 -04005086 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005087 if (tzinfo == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005088 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005089 }
5090
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005091 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5092 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005093
5094 Py_DECREF(tzinfo);
Paul Ganssle3df85402018-10-22 12:32:52 -04005095 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005096 return dt;
Paul Ganssle096329f2018-08-23 11:06:20 -04005097
5098invalid_string_error:
5099 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5100
5101error:
Paul Ganssle3df85402018-10-22 12:32:52 -04005102 Py_XDECREF(dtstr_clean);
Paul Ganssle096329f2018-08-23 11:06:20 -04005103
5104 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005105}
5106
Tim Peters2a799bf2002-12-16 20:18:38 +00005107/*
5108 * Destructor.
5109 */
5110
5111static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005112datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005113{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005114 if (HASTZINFO(self)) {
5115 Py_XDECREF(self->tzinfo);
5116 }
5117 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005118}
5119
5120/*
5121 * Indirect access to tzinfo methods.
5122 */
5123
Tim Peters2a799bf2002-12-16 20:18:38 +00005124/* These are all METH_NOARGS, so don't need to check the arglist. */
5125static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005126datetime_utcoffset(PyObject *self, PyObject *unused) {
5127 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005128}
5129
5130static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005131datetime_dst(PyObject *self, PyObject *unused) {
5132 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005133}
5134
5135static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005136datetime_tzname(PyObject *self, PyObject *unused) {
5137 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005138}
5139
5140/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005141 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005142 */
5143
Tim Petersa9bc1682003-01-11 03:39:11 +00005144/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5145 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005146 */
5147static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005148add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005149 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005151 /* Note that the C-level additions can't overflow, because of
5152 * invariant bounds on the member values.
5153 */
5154 int year = GET_YEAR(date);
5155 int month = GET_MONTH(date);
5156 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5157 int hour = DATE_GET_HOUR(date);
5158 int minute = DATE_GET_MINUTE(date);
5159 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5160 int microsecond = DATE_GET_MICROSECOND(date) +
5161 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005163 assert(factor == 1 || factor == -1);
5164 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005165 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005166 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005167 }
5168
5169 return new_datetime(year, month, day,
5170 hour, minute, second, microsecond,
5171 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005172}
5173
5174static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005175datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005177 if (PyDateTime_Check(left)) {
5178 /* datetime + ??? */
5179 if (PyDelta_Check(right))
5180 /* datetime + delta */
5181 return add_datetime_timedelta(
5182 (PyDateTime_DateTime *)left,
5183 (PyDateTime_Delta *)right,
5184 1);
5185 }
5186 else if (PyDelta_Check(left)) {
5187 /* delta + datetime */
5188 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5189 (PyDateTime_Delta *) left,
5190 1);
5191 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005192 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005193}
5194
5195static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005196datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005197{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005198 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005200 if (PyDateTime_Check(left)) {
5201 /* datetime - ??? */
5202 if (PyDateTime_Check(right)) {
5203 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005204 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005205 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005206
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005207 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5208 offset2 = offset1 = Py_None;
5209 Py_INCREF(offset1);
5210 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005211 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005212 else {
5213 offset1 = datetime_utcoffset(left, NULL);
5214 if (offset1 == NULL)
5215 return NULL;
5216 offset2 = datetime_utcoffset(right, NULL);
5217 if (offset2 == NULL) {
5218 Py_DECREF(offset1);
5219 return NULL;
5220 }
5221 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5222 PyErr_SetString(PyExc_TypeError,
5223 "can't subtract offset-naive and "
5224 "offset-aware datetimes");
5225 Py_DECREF(offset1);
5226 Py_DECREF(offset2);
5227 return NULL;
5228 }
5229 }
5230 if ((offset1 != offset2) &&
5231 delta_cmp(offset1, offset2) != 0) {
5232 offdiff = delta_subtract(offset1, offset2);
5233 if (offdiff == NULL) {
5234 Py_DECREF(offset1);
5235 Py_DECREF(offset2);
5236 return NULL;
5237 }
5238 }
5239 Py_DECREF(offset1);
5240 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005241 delta_d = ymd_to_ord(GET_YEAR(left),
5242 GET_MONTH(left),
5243 GET_DAY(left)) -
5244 ymd_to_ord(GET_YEAR(right),
5245 GET_MONTH(right),
5246 GET_DAY(right));
5247 /* These can't overflow, since the values are
5248 * normalized. At most this gives the number of
5249 * seconds in one day.
5250 */
5251 delta_s = (DATE_GET_HOUR(left) -
5252 DATE_GET_HOUR(right)) * 3600 +
5253 (DATE_GET_MINUTE(left) -
5254 DATE_GET_MINUTE(right)) * 60 +
5255 (DATE_GET_SECOND(left) -
5256 DATE_GET_SECOND(right));
5257 delta_us = DATE_GET_MICROSECOND(left) -
5258 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005259 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005260 if (result == NULL)
5261 return NULL;
5262
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005263 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005264 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005265 Py_DECREF(offdiff);
5266 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005267 }
5268 else if (PyDelta_Check(right)) {
5269 /* datetime - delta */
5270 result = add_datetime_timedelta(
5271 (PyDateTime_DateTime *)left,
5272 (PyDateTime_Delta *)right,
5273 -1);
5274 }
5275 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005277 if (result == Py_NotImplemented)
5278 Py_INCREF(result);
5279 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005280}
5281
5282/* Various ways to turn a datetime into a string. */
5283
5284static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005285datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005286{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005287 const char *type_name = Py_TYPE(self)->tp_name;
5288 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005290 if (DATE_GET_MICROSECOND(self)) {
5291 baserepr = PyUnicode_FromFormat(
5292 "%s(%d, %d, %d, %d, %d, %d, %d)",
5293 type_name,
5294 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5295 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5296 DATE_GET_SECOND(self),
5297 DATE_GET_MICROSECOND(self));
5298 }
5299 else if (DATE_GET_SECOND(self)) {
5300 baserepr = PyUnicode_FromFormat(
5301 "%s(%d, %d, %d, %d, %d, %d)",
5302 type_name,
5303 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5304 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5305 DATE_GET_SECOND(self));
5306 }
5307 else {
5308 baserepr = PyUnicode_FromFormat(
5309 "%s(%d, %d, %d, %d, %d)",
5310 type_name,
5311 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5312 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5313 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005314 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5315 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005316 if (baserepr == NULL || ! HASTZINFO(self))
5317 return baserepr;
5318 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005319}
5320
Tim Petersa9bc1682003-01-11 03:39:11 +00005321static PyObject *
5322datetime_str(PyDateTime_DateTime *self)
5323{
Victor Stinner4c381542016-12-09 00:33:39 +01005324 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005325}
Tim Peters2a799bf2002-12-16 20:18:38 +00005326
5327static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005328datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005330 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005331 char *timespec = NULL;
5332 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005333 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005334 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005335 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005336 static char *specs[][2] = {
5337 {"hours", "%04d-%02d-%02d%c%02d"},
5338 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5339 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5340 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5341 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5342 };
5343 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005344
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005345 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005346 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005347
5348 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5349 if (us == 0) {
5350 /* seconds */
5351 given_spec = 2;
5352 }
5353 else {
5354 /* microseconds */
5355 given_spec = 4;
5356 }
5357 }
5358 else {
5359 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5360 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5361 if (given_spec == 3) {
5362 us = us / 1000;
5363 }
5364 break;
5365 }
5366 }
5367 }
5368
5369 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5370 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5371 return NULL;
5372 }
5373 else {
5374 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005375 GET_YEAR(self), GET_MONTH(self),
5376 GET_DAY(self), (int)sep,
5377 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5378 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005379 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005381 if (!result || !HASTZINFO(self))
5382 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005384 /* We need to append the UTC offset. */
5385 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5386 (PyObject *)self) < 0) {
5387 Py_DECREF(result);
5388 return NULL;
5389 }
5390 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5391 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005392}
5393
Tim Petersa9bc1682003-01-11 03:39:11 +00005394static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305395datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005397 return format_ctime((PyDateTime_Date *)self,
5398 DATE_GET_HOUR(self),
5399 DATE_GET_MINUTE(self),
5400 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005401}
5402
Tim Peters2a799bf2002-12-16 20:18:38 +00005403/* Miscellaneous methods. */
5404
Tim Petersa9bc1682003-01-11 03:39:11 +00005405static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005406flip_fold(PyObject *dt)
5407{
5408 return new_datetime_ex2(GET_YEAR(dt),
5409 GET_MONTH(dt),
5410 GET_DAY(dt),
5411 DATE_GET_HOUR(dt),
5412 DATE_GET_MINUTE(dt),
5413 DATE_GET_SECOND(dt),
5414 DATE_GET_MICROSECOND(dt),
5415 HASTZINFO(dt) ?
5416 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5417 !DATE_GET_FOLD(dt),
5418 Py_TYPE(dt));
5419}
5420
5421static PyObject *
5422get_flip_fold_offset(PyObject *dt)
5423{
5424 PyObject *result, *flip_dt;
5425
5426 flip_dt = flip_fold(dt);
5427 if (flip_dt == NULL)
5428 return NULL;
5429 result = datetime_utcoffset(flip_dt, NULL);
5430 Py_DECREF(flip_dt);
5431 return result;
5432}
5433
5434/* PEP 495 exception: Whenever one or both of the operands in
5435 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakabac2d5b2018-03-28 22:14:26 +03005436 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005437 *
5438 * Return 1 if exception applies, 0 if not, and -1 on error.
5439 */
5440static int
5441pep495_eq_exception(PyObject *self, PyObject *other,
5442 PyObject *offset_self, PyObject *offset_other)
5443{
5444 int result = 0;
5445 PyObject *flip_offset;
5446
5447 flip_offset = get_flip_fold_offset(self);
5448 if (flip_offset == NULL)
5449 return -1;
5450 if (flip_offset != offset_self &&
5451 delta_cmp(flip_offset, offset_self))
5452 {
5453 result = 1;
5454 goto done;
5455 }
5456 Py_DECREF(flip_offset);
5457
5458 flip_offset = get_flip_fold_offset(other);
5459 if (flip_offset == NULL)
5460 return -1;
5461 if (flip_offset != offset_other &&
5462 delta_cmp(flip_offset, offset_other))
5463 result = 1;
5464 done:
5465 Py_DECREF(flip_offset);
5466 return result;
5467}
5468
5469static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005470datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005471{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005472 PyObject *result = NULL;
5473 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005474 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005476 if (! PyDateTime_Check(other)) {
5477 if (PyDate_Check(other)) {
5478 /* Prevent invocation of date_richcompare. We want to
5479 return NotImplemented here to give the other object
5480 a chance. But since DateTime is a subclass of
5481 Date, if the other object is a Date, it would
5482 compute an ordering based on the date part alone,
5483 and we don't want that. So force unequal or
5484 uncomparable here in that case. */
5485 if (op == Py_EQ)
5486 Py_RETURN_FALSE;
5487 if (op == Py_NE)
5488 Py_RETURN_TRUE;
5489 return cmperror(self, other);
5490 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005491 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005492 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005493
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005494 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005495 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5496 ((PyDateTime_DateTime *)other)->data,
5497 _PyDateTime_DATETIME_DATASIZE);
5498 return diff_to_bool(diff, op);
5499 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005500 offset1 = datetime_utcoffset(self, NULL);
5501 if (offset1 == NULL)
5502 return NULL;
5503 offset2 = datetime_utcoffset(other, NULL);
5504 if (offset2 == NULL)
5505 goto done;
5506 /* If they're both naive, or both aware and have the same offsets,
5507 * we get off cheap. Note that if they're both naive, offset1 ==
5508 * offset2 == Py_None at this point.
5509 */
5510 if ((offset1 == offset2) ||
5511 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5512 delta_cmp(offset1, offset2) == 0)) {
5513 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5514 ((PyDateTime_DateTime *)other)->data,
5515 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005516 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5517 int ex = pep495_eq_exception(self, other, offset1, offset2);
5518 if (ex == -1)
5519 goto done;
5520 if (ex)
5521 diff = 1;
5522 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005523 result = diff_to_bool(diff, op);
5524 }
5525 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005526 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005527
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005528 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005529 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5530 other);
5531 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005532 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005533 diff = GET_TD_DAYS(delta);
5534 if (diff == 0)
5535 diff = GET_TD_SECONDS(delta) |
5536 GET_TD_MICROSECONDS(delta);
5537 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005538 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5539 int ex = pep495_eq_exception(self, other, offset1, offset2);
5540 if (ex == -1)
5541 goto done;
5542 if (ex)
5543 diff = 1;
5544 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005545 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005546 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005547 else if (op == Py_EQ) {
5548 result = Py_False;
5549 Py_INCREF(result);
5550 }
5551 else if (op == Py_NE) {
5552 result = Py_True;
5553 Py_INCREF(result);
5554 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005555 else {
5556 PyErr_SetString(PyExc_TypeError,
5557 "can't compare offset-naive and "
5558 "offset-aware datetimes");
5559 }
5560 done:
5561 Py_DECREF(offset1);
5562 Py_XDECREF(offset2);
5563 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005564}
5565
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005566static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005567datetime_hash(PyDateTime_DateTime *self)
5568{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005569 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005570 PyObject *offset, *self0;
5571 if (DATE_GET_FOLD(self)) {
5572 self0 = new_datetime_ex2(GET_YEAR(self),
5573 GET_MONTH(self),
5574 GET_DAY(self),
5575 DATE_GET_HOUR(self),
5576 DATE_GET_MINUTE(self),
5577 DATE_GET_SECOND(self),
5578 DATE_GET_MICROSECOND(self),
5579 HASTZINFO(self) ? self->tzinfo : Py_None,
5580 0, Py_TYPE(self));
5581 if (self0 == NULL)
5582 return -1;
5583 }
5584 else {
5585 self0 = (PyObject *)self;
5586 Py_INCREF(self0);
5587 }
5588 offset = datetime_utcoffset(self0, NULL);
5589 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005590
5591 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005592 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005594 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005595 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005596 self->hashcode = generic_hash(
5597 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005598 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005599 PyObject *temp1, *temp2;
5600 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005602 assert(HASTZINFO(self));
5603 days = ymd_to_ord(GET_YEAR(self),
5604 GET_MONTH(self),
5605 GET_DAY(self));
5606 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005607 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005608 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005609 temp1 = new_delta(days, seconds,
5610 DATE_GET_MICROSECOND(self),
5611 1);
5612 if (temp1 == NULL) {
5613 Py_DECREF(offset);
5614 return -1;
5615 }
5616 temp2 = delta_subtract(temp1, offset);
5617 Py_DECREF(temp1);
5618 if (temp2 == NULL) {
5619 Py_DECREF(offset);
5620 return -1;
5621 }
5622 self->hashcode = PyObject_Hash(temp2);
5623 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005624 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005625 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005626 }
5627 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005628}
Tim Peters2a799bf2002-12-16 20:18:38 +00005629
5630static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005631datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005633 PyObject *clone;
5634 PyObject *tuple;
5635 int y = GET_YEAR(self);
5636 int m = GET_MONTH(self);
5637 int d = GET_DAY(self);
5638 int hh = DATE_GET_HOUR(self);
5639 int mm = DATE_GET_MINUTE(self);
5640 int ss = DATE_GET_SECOND(self);
5641 int us = DATE_GET_MICROSECOND(self);
5642 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005643 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005644
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005645 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005646 datetime_kws,
5647 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005648 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005649 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005650 if (fold != 0 && fold != 1) {
5651 PyErr_SetString(PyExc_ValueError,
5652 "fold must be either 0 or 1");
5653 return NULL;
5654 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005655 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5656 if (tuple == NULL)
5657 return NULL;
5658 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005659 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005660 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005661 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005662 Py_DECREF(tuple);
5663 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005664}
5665
5666static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005667local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005668{
5669 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005670 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005671 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005672 PyObject *nameo = NULL;
5673 const char *zone = NULL;
5674
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005675 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005676 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005677#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005678 zone = local_time_tm.tm_zone;
5679 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005680#else /* HAVE_STRUCT_TM_TM_ZONE */
5681 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005682 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005683 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005684 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005685 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005686 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005687 local_time = new_datetime(local_time_tm.tm_year + 1900,
5688 local_time_tm.tm_mon + 1,
5689 local_time_tm.tm_mday,
5690 local_time_tm.tm_hour,
5691 local_time_tm.tm_min,
5692 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005693 if (local_time == NULL) {
5694 return NULL;
5695 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005696 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005697 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005698 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5699 utc_time_tm.tm_mon + 1,
5700 utc_time_tm.tm_mday,
5701 utc_time_tm.tm_hour,
5702 utc_time_tm.tm_min,
5703 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005704 if (utc_time == NULL) {
5705 Py_DECREF(local_time);
5706 return NULL;
5707 }
5708 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005709 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005710 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005711 }
5712#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005713 if (delta == NULL) {
5714 return NULL;
5715 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005716 if (zone != NULL) {
5717 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5718 if (nameo == NULL)
5719 goto error;
5720 }
5721 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005722 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005723 error:
5724 Py_DECREF(delta);
5725 return result;
5726}
5727
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005728static PyObject *
5729local_timezone(PyDateTime_DateTime *utc_time)
5730{
5731 time_t timestamp;
5732 PyObject *delta;
5733 PyObject *one_second;
5734 PyObject *seconds;
5735
5736 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5737 if (delta == NULL)
5738 return NULL;
5739 one_second = new_delta(0, 1, 0, 0);
5740 if (one_second == NULL) {
5741 Py_DECREF(delta);
5742 return NULL;
5743 }
5744 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5745 (PyDateTime_Delta *)one_second);
5746 Py_DECREF(one_second);
5747 Py_DECREF(delta);
5748 if (seconds == NULL)
5749 return NULL;
5750 timestamp = _PyLong_AsTime_t(seconds);
5751 Py_DECREF(seconds);
5752 if (timestamp == -1 && PyErr_Occurred())
5753 return NULL;
5754 return local_timezone_from_timestamp(timestamp);
5755}
5756
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005757static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005758local_to_seconds(int year, int month, int day,
5759 int hour, int minute, int second, int fold);
5760
5761static PyObject *
5762local_timezone_from_local(PyDateTime_DateTime *local_dt)
5763{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005764 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005765 time_t timestamp;
5766 seconds = local_to_seconds(GET_YEAR(local_dt),
5767 GET_MONTH(local_dt),
5768 GET_DAY(local_dt),
5769 DATE_GET_HOUR(local_dt),
5770 DATE_GET_MINUTE(local_dt),
5771 DATE_GET_SECOND(local_dt),
5772 DATE_GET_FOLD(local_dt));
5773 if (seconds == -1)
5774 return NULL;
5775 /* XXX: add bounds check */
5776 timestamp = seconds - epoch;
5777 return local_timezone_from_timestamp(timestamp);
5778}
5779
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005780static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005781datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005782{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005783 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005784 PyObject *offset;
5785 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005786 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005787 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005788 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005789
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005790 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005791 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005792 return NULL;
5793
5794 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005795 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005796
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005797 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005798 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005799 self_tzinfo = local_timezone_from_local(self);
5800 if (self_tzinfo == NULL)
5801 return NULL;
5802 } else {
5803 self_tzinfo = self->tzinfo;
5804 Py_INCREF(self_tzinfo);
5805 }
Tim Peters521fc152002-12-31 17:36:56 +00005806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005807 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005808 if (self_tzinfo == tzinfo) {
5809 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005810 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005811 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005812 }
Tim Peters521fc152002-12-31 17:36:56 +00005813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005814 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005815 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5816 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005817 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005818 return NULL;
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005819 else if(offset == Py_None) {
5820 Py_DECREF(offset);
5821 goto naive;
5822 }
5823 else if (!PyDelta_Check(offset)) {
5824 Py_DECREF(offset);
5825 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5826 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5827 return NULL;
5828 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005829 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005830 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5831 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005832 Py_DECREF(offset);
5833 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005834 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005835
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005836 /* Make sure result is aware and UTC. */
5837 if (!HASTZINFO(result)) {
5838 temp = (PyObject *)result;
5839 result = (PyDateTime_DateTime *)
5840 new_datetime_ex2(GET_YEAR(result),
5841 GET_MONTH(result),
5842 GET_DAY(result),
5843 DATE_GET_HOUR(result),
5844 DATE_GET_MINUTE(result),
5845 DATE_GET_SECOND(result),
5846 DATE_GET_MICROSECOND(result),
5847 PyDateTime_TimeZone_UTC,
5848 DATE_GET_FOLD(result),
5849 Py_TYPE(result));
5850 Py_DECREF(temp);
5851 if (result == NULL)
5852 return NULL;
5853 }
5854 else {
5855 /* Result is already aware - just replace tzinfo. */
5856 temp = result->tzinfo;
5857 result->tzinfo = PyDateTime_TimeZone_UTC;
5858 Py_INCREF(result->tzinfo);
5859 Py_DECREF(temp);
5860 }
5861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005862 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005863 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005864 if (tzinfo == Py_None) {
5865 tzinfo = local_timezone(result);
5866 if (tzinfo == NULL) {
5867 Py_DECREF(result);
5868 return NULL;
5869 }
5870 }
5871 else
5872 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005873 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005874 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005875
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005876 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005877 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005878 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005879 Py_DECREF(temp);
5880
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005881 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005882}
5883
5884static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305885datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00005886{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005887 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005889 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005890 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005891
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005892 dst = call_dst(self->tzinfo, (PyObject *)self);
5893 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005894 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005895
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005896 if (dst != Py_None)
5897 dstflag = delta_bool((PyDateTime_Delta *)dst);
5898 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005899 }
5900 return build_struct_time(GET_YEAR(self),
5901 GET_MONTH(self),
5902 GET_DAY(self),
5903 DATE_GET_HOUR(self),
5904 DATE_GET_MINUTE(self),
5905 DATE_GET_SECOND(self),
5906 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005907}
5908
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005909static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005910local_to_seconds(int year, int month, int day,
5911 int hour, int minute, int second, int fold)
5912{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005913 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005914 t = utc_to_seconds(year, month, day, hour, minute, second);
5915 /* Our goal is to solve t = local(u) for u. */
5916 lt = local(t);
5917 if (lt == -1)
5918 return -1;
5919 a = lt - t;
5920 u1 = t - a;
5921 t1 = local(u1);
5922 if (t1 == -1)
5923 return -1;
5924 if (t1 == t) {
5925 /* We found one solution, but it may not be the one we need.
5926 * Look for an earlier solution (if `fold` is 0), or a
5927 * later one (if `fold` is 1). */
5928 if (fold)
5929 u2 = u1 + max_fold_seconds;
5930 else
5931 u2 = u1 - max_fold_seconds;
5932 lt = local(u2);
5933 if (lt == -1)
5934 return -1;
5935 b = lt - u2;
5936 if (a == b)
5937 return u1;
5938 }
5939 else {
5940 b = t1 - u1;
5941 assert(a != b);
5942 }
5943 u2 = t - b;
5944 t2 = local(u2);
5945 if (t2 == -1)
5946 return -1;
5947 if (t2 == t)
5948 return u2;
5949 if (t1 == t)
5950 return u1;
5951 /* We have found both offsets a and b, but neither t - a nor t - b is
5952 * a solution. This means t is in the gap. */
5953 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5954}
5955
5956/* date(1970,1,1).toordinal() == 719163 */
5957#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5958
Tim Peters2a799bf2002-12-16 20:18:38 +00005959static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305960datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolskya4415142012-06-08 12:33:09 -04005961{
5962 PyObject *result;
5963
5964 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5965 PyObject *delta;
5966 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5967 if (delta == NULL)
5968 return NULL;
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305969 result = delta_total_seconds(delta, NULL);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005970 Py_DECREF(delta);
5971 }
5972 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005973 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005974 seconds = local_to_seconds(GET_YEAR(self),
5975 GET_MONTH(self),
5976 GET_DAY(self),
5977 DATE_GET_HOUR(self),
5978 DATE_GET_MINUTE(self),
5979 DATE_GET_SECOND(self),
5980 DATE_GET_FOLD(self));
5981 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005982 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005983 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5984 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005985 }
5986 return result;
5987}
5988
5989static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305990datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005992 return new_date(GET_YEAR(self),
5993 GET_MONTH(self),
5994 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005995}
5996
5997static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305998datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005999{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006000 return new_time(DATE_GET_HOUR(self),
6001 DATE_GET_MINUTE(self),
6002 DATE_GET_SECOND(self),
6003 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006004 Py_None,
6005 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006006}
6007
6008static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306009datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006010{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006011 return new_time(DATE_GET_HOUR(self),
6012 DATE_GET_MINUTE(self),
6013 DATE_GET_SECOND(self),
6014 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006015 GET_DT_TZINFO(self),
6016 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006017}
6018
6019static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306020datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006021{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006022 int y, m, d, hh, mm, ss;
6023 PyObject *tzinfo;
6024 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006025
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006026 tzinfo = GET_DT_TZINFO(self);
6027 if (tzinfo == Py_None) {
6028 utcself = self;
6029 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006030 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006031 else {
6032 PyObject *offset;
6033 offset = call_utcoffset(tzinfo, (PyObject *)self);
6034 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006035 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006036 if (offset == Py_None) {
6037 Py_DECREF(offset);
6038 utcself = self;
6039 Py_INCREF(utcself);
6040 }
6041 else {
6042 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6043 (PyDateTime_Delta *)offset, -1);
6044 Py_DECREF(offset);
6045 if (utcself == NULL)
6046 return NULL;
6047 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006048 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006049 y = GET_YEAR(utcself);
6050 m = GET_MONTH(utcself);
6051 d = GET_DAY(utcself);
6052 hh = DATE_GET_HOUR(utcself);
6053 mm = DATE_GET_MINUTE(utcself);
6054 ss = DATE_GET_SECOND(utcself);
6055
6056 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006057 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006058}
6059
Tim Peters371935f2003-02-01 01:52:50 +00006060/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006061
Tim Petersa9bc1682003-01-11 03:39:11 +00006062/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006063 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6064 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006065 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006066 */
6067static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006068datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006070 PyObject *basestate;
6071 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006073 basestate = PyBytes_FromStringAndSize((char *)self->data,
6074 _PyDateTime_DATETIME_DATASIZE);
6075 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006076 if (proto > 3 && DATE_GET_FOLD(self))
6077 /* Set the first bit of the third byte */
6078 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006079 if (! HASTZINFO(self) || self->tzinfo == Py_None)
6080 result = PyTuple_Pack(1, basestate);
6081 else
6082 result = PyTuple_Pack(2, basestate, self->tzinfo);
6083 Py_DECREF(basestate);
6084 }
6085 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00006086}
6087
6088static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006089datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006090{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006091 int proto;
6092 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006093 return NULL;
6094
6095 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006096}
6097
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006098static PyObject *
6099datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6100{
6101 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6102}
6103
Tim Petersa9bc1682003-01-11 03:39:11 +00006104static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006106 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006107
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006108 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006110 {"utcnow", (PyCFunction)datetime_utcnow,
6111 METH_NOARGS | METH_CLASS,
6112 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006113
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006114 {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006115 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6116 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006118 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6119 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006120 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006122 {"strptime", (PyCFunction)datetime_strptime,
6123 METH_VARARGS | METH_CLASS,
6124 PyDoc_STR("string, format -> new datetime parsed from a string "
6125 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006126
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006127 {"combine", (PyCFunction)(void(*)(void))datetime_combine,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006128 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6129 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006130
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006131 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6132 METH_O | METH_CLASS,
6133 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006135 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006137 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6138 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006140 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6141 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006143 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6144 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006146 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6147 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006149 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6150 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006151
Alexander Belopolskya4415142012-06-08 12:33:09 -04006152 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6153 PyDoc_STR("Return POSIX timestamp as float.")},
6154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006155 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6156 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006157
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006158 {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006159 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006160 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006161 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006162 "defaults to 'T'.\n"
6163 "timespec specifies what components of the time to include"
6164 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6165 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006167 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6168 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006170 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6171 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006173 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6174 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006175
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006176 {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006177 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006178
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006179 {"astimezone", (PyCFunction)(void(*)(void))datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006180 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006181
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006182 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006183 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006184
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006185 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6186 PyDoc_STR("__reduce__() -> (cls, state)")},
6187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006188 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006189};
6190
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006191static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006192PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6193\n\
6194The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006195instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006196
Tim Petersa9bc1682003-01-11 03:39:11 +00006197static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006198 datetime_add, /* nb_add */
6199 datetime_subtract, /* nb_subtract */
6200 0, /* nb_multiply */
6201 0, /* nb_remainder */
6202 0, /* nb_divmod */
6203 0, /* nb_power */
6204 0, /* nb_negative */
6205 0, /* nb_positive */
6206 0, /* nb_absolute */
6207 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006208};
6209
Neal Norwitz227b5332006-03-22 09:28:35 +00006210static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006211 PyVarObject_HEAD_INIT(NULL, 0)
6212 "datetime.datetime", /* tp_name */
6213 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6214 0, /* tp_itemsize */
6215 (destructor)datetime_dealloc, /* tp_dealloc */
6216 0, /* tp_print */
6217 0, /* tp_getattr */
6218 0, /* tp_setattr */
6219 0, /* tp_reserved */
6220 (reprfunc)datetime_repr, /* tp_repr */
6221 &datetime_as_number, /* tp_as_number */
6222 0, /* tp_as_sequence */
6223 0, /* tp_as_mapping */
6224 (hashfunc)datetime_hash, /* tp_hash */
6225 0, /* tp_call */
6226 (reprfunc)datetime_str, /* tp_str */
6227 PyObject_GenericGetAttr, /* tp_getattro */
6228 0, /* tp_setattro */
6229 0, /* tp_as_buffer */
6230 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6231 datetime_doc, /* tp_doc */
6232 0, /* tp_traverse */
6233 0, /* tp_clear */
6234 datetime_richcompare, /* tp_richcompare */
6235 0, /* tp_weaklistoffset */
6236 0, /* tp_iter */
6237 0, /* tp_iternext */
6238 datetime_methods, /* tp_methods */
6239 0, /* tp_members */
6240 datetime_getset, /* tp_getset */
6241 &PyDateTime_DateType, /* tp_base */
6242 0, /* tp_dict */
6243 0, /* tp_descr_get */
6244 0, /* tp_descr_set */
6245 0, /* tp_dictoffset */
6246 0, /* tp_init */
6247 datetime_alloc, /* tp_alloc */
6248 datetime_new, /* tp_new */
6249 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006250};
6251
6252/* ---------------------------------------------------------------------------
6253 * Module methods and initialization.
6254 */
6255
6256static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006257 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006258};
6259
Tim Peters9ddf40b2004-06-20 22:41:32 +00006260/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6261 * datetime.h.
6262 */
6263static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006264 &PyDateTime_DateType,
6265 &PyDateTime_DateTimeType,
6266 &PyDateTime_TimeType,
6267 &PyDateTime_DeltaType,
6268 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006269 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006270 new_date_ex,
6271 new_datetime_ex,
6272 new_time_ex,
6273 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006274 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006275 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006276 date_fromtimestamp,
6277 new_datetime_ex2,
6278 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006279};
6280
6281
Martin v. Löwis1a214512008-06-11 05:26:20 +00006282
6283static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006284 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006285 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006286 "Fast implementation of the datetime type.",
6287 -1,
6288 module_methods,
6289 NULL,
6290 NULL,
6291 NULL,
6292 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006293};
6294
Tim Peters2a799bf2002-12-16 20:18:38 +00006295PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006296PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006298 PyObject *m; /* a module object */
6299 PyObject *d; /* its dict */
6300 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006301 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006303 m = PyModule_Create(&datetimemodule);
6304 if (m == NULL)
6305 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006307 if (PyType_Ready(&PyDateTime_DateType) < 0)
6308 return NULL;
6309 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6310 return NULL;
6311 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6312 return NULL;
6313 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6314 return NULL;
6315 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6316 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006317 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6318 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006320 /* timedelta values */
6321 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006323 x = new_delta(0, 0, 1, 0);
6324 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6325 return NULL;
6326 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006328 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6329 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6330 return NULL;
6331 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006333 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6334 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6335 return NULL;
6336 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006338 /* date values */
6339 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006341 x = new_date(1, 1, 1);
6342 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6343 return NULL;
6344 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006346 x = new_date(MAXYEAR, 12, 31);
6347 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6348 return NULL;
6349 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006351 x = new_delta(1, 0, 0, 0);
6352 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6353 return NULL;
6354 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006356 /* time values */
6357 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006358
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006359 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006360 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6361 return NULL;
6362 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006363
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006364 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006365 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6366 return NULL;
6367 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006369 x = new_delta(0, 0, 1, 0);
6370 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6371 return NULL;
6372 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006374 /* datetime values */
6375 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006376
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006377 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006378 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6379 return NULL;
6380 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006381
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006382 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006383 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6384 return NULL;
6385 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006387 x = new_delta(0, 0, 1, 0);
6388 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6389 return NULL;
6390 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006391
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006392 /* timezone values */
6393 d = PyDateTime_TimeZoneType.tp_dict;
6394
6395 delta = new_delta(0, 0, 0, 0);
6396 if (delta == NULL)
6397 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006398 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006399 Py_DECREF(delta);
6400 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6401 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006402 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006403 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006404
6405 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6406 if (delta == NULL)
6407 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006408 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006409 Py_DECREF(delta);
6410 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6411 return NULL;
6412 Py_DECREF(x);
6413
6414 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6415 if (delta == NULL)
6416 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006417 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006418 Py_DECREF(delta);
6419 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6420 return NULL;
6421 Py_DECREF(x);
6422
Alexander Belopolskya4415142012-06-08 12:33:09 -04006423 /* Epoch */
6424 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006425 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006426 if (PyDateTime_Epoch == NULL)
6427 return NULL;
6428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006429 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006430 PyModule_AddIntMacro(m, MINYEAR);
6431 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006433 Py_INCREF(&PyDateTime_DateType);
6434 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006436 Py_INCREF(&PyDateTime_DateTimeType);
6437 PyModule_AddObject(m, "datetime",
6438 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006440 Py_INCREF(&PyDateTime_TimeType);
6441 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006443 Py_INCREF(&PyDateTime_DeltaType);
6444 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006446 Py_INCREF(&PyDateTime_TZInfoType);
6447 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006448
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006449 Py_INCREF(&PyDateTime_TimeZoneType);
6450 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006452 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6453 if (x == NULL)
6454 return NULL;
6455 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006457 /* A 4-year cycle has an extra leap day over what we'd get from
6458 * pasting together 4 single years.
6459 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006460 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006461 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006463 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6464 * get from pasting together 4 100-year cycles.
6465 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006466 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006467 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006469 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6470 * pasting together 25 4-year cycles.
6471 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006472 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006473 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006475 us_per_ms = PyLong_FromLong(1000);
6476 us_per_second = PyLong_FromLong(1000000);
6477 us_per_minute = PyLong_FromLong(60000000);
6478 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006479 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006480 us_per_minute == NULL || seconds_per_day == NULL)
6481 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006483 /* The rest are too big for 32-bit ints, but even
6484 * us_per_week fits in 40 bits, so doubles should be exact.
6485 */
6486 us_per_hour = PyLong_FromDouble(3600000000.0);
6487 us_per_day = PyLong_FromDouble(86400000000.0);
6488 us_per_week = PyLong_FromDouble(604800000000.0);
6489 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6490 return NULL;
6491 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006492}
Tim Petersf3615152003-01-01 21:51:37 +00006493
6494/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006495Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006496 x.n = x stripped of its timezone -- its naive time.
6497 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006498 return None
Tim Petersf3615152003-01-01 21:51:37 +00006499 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006500 return None
Tim Petersf3615152003-01-01 21:51:37 +00006501 x.s = x's standard offset, x.o - x.d
6502
6503Now some derived rules, where k is a duration (timedelta).
6504
65051. x.o = x.s + x.d
6506 This follows from the definition of x.s.
6507
Tim Petersc5dc4da2003-01-02 17:55:03 +000065082. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006509 This is actually a requirement, an assumption we need to make about
6510 sane tzinfo classes.
6511
65123. The naive UTC time corresponding to x is x.n - x.o.
6513 This is again a requirement for a sane tzinfo class.
6514
65154. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006516 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006517
Tim Petersc5dc4da2003-01-02 17:55:03 +000065185. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006519 Again follows from how arithmetic is defined.
6520
Tim Peters8bb5ad22003-01-24 02:44:45 +00006521Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006522(meaning that the various tzinfo methods exist, and don't blow up or return
6523None when called).
6524
Tim Petersa9bc1682003-01-11 03:39:11 +00006525The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006526x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006527
6528By #3, we want
6529
Tim Peters8bb5ad22003-01-24 02:44:45 +00006530 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006531
6532The algorithm starts by attaching tz to x.n, and calling that y. So
6533x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6534becomes true; in effect, we want to solve [2] for k:
6535
Tim Peters8bb5ad22003-01-24 02:44:45 +00006536 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006537
6538By #1, this is the same as
6539
Tim Peters8bb5ad22003-01-24 02:44:45 +00006540 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006541
6542By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6543Substituting that into [3],
6544
Tim Peters8bb5ad22003-01-24 02:44:45 +00006545 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6546 k - (y+k).s - (y+k).d = 0; rearranging,
6547 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6548 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006549
Tim Peters8bb5ad22003-01-24 02:44:45 +00006550On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6551approximate k by ignoring the (y+k).d term at first. Note that k can't be
6552very large, since all offset-returning methods return a duration of magnitude
6553less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6554be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006555
6556In any case, the new value is
6557
Tim Peters8bb5ad22003-01-24 02:44:45 +00006558 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006559
Tim Peters8bb5ad22003-01-24 02:44:45 +00006560It's helpful to step back at look at [4] from a higher level: it's simply
6561mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006562
6563At this point, if
6564
Tim Peters8bb5ad22003-01-24 02:44:45 +00006565 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006566
6567we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006568at the start of daylight time. Picture US Eastern for concreteness. The wall
6569time 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 +00006570sense then. The docs ask that an Eastern tzinfo class consider such a time to
6571be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6572on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006573the only spelling that makes sense on the local wall clock.
6574
Tim Petersc5dc4da2003-01-02 17:55:03 +00006575In fact, if [5] holds at this point, we do have the standard-time spelling,
6576but that takes a bit of proof. We first prove a stronger result. What's the
6577difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006578
Tim Peters8bb5ad22003-01-24 02:44:45 +00006579 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006580
Tim Petersc5dc4da2003-01-02 17:55:03 +00006581Now
6582 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006583 (y + y.s).n = by #5
6584 y.n + y.s = since y.n = x.n
6585 x.n + y.s = since z and y are have the same tzinfo member,
6586 y.s = z.s by #2
6587 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006588
Tim Petersc5dc4da2003-01-02 17:55:03 +00006589Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006590
Tim Petersc5dc4da2003-01-02 17:55:03 +00006591 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006592 x.n - ((x.n + z.s) - z.o) = expanding
6593 x.n - x.n - z.s + z.o = cancelling
6594 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006595 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006596
Tim Petersc5dc4da2003-01-02 17:55:03 +00006597So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006598
Tim Petersc5dc4da2003-01-02 17:55:03 +00006599If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006600spelling we wanted in the endcase described above. We're done. Contrarily,
6601if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006602
Tim Petersc5dc4da2003-01-02 17:55:03 +00006603If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6604add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006605local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006606
Tim Petersc5dc4da2003-01-02 17:55:03 +00006607Let
Tim Petersf3615152003-01-01 21:51:37 +00006608
Tim Peters4fede1a2003-01-04 00:26:59 +00006609 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006610
Tim Peters4fede1a2003-01-04 00:26:59 +00006611and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006612
Tim Peters8bb5ad22003-01-24 02:44:45 +00006613 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006614
Tim Peters8bb5ad22003-01-24 02:44:45 +00006615If so, we're done. If not, the tzinfo class is insane, according to the
6616assumptions we've made. This also requires a bit of proof. As before, let's
6617compute the difference between the LHS and RHS of [8] (and skipping some of
6618the justifications for the kinds of substitutions we've done several times
6619already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006620
Tim Peters8bb5ad22003-01-24 02:44:45 +00006621 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006622 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6623 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6624 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6625 - z.n + z.n - z.o + z'.o = cancel z.n
6626 - z.o + z'.o = #1 twice
6627 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6628 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006629
6630So 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 +00006631we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6632return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006633
Tim Peters8bb5ad22003-01-24 02:44:45 +00006634How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6635a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6636would have to change the result dst() returns: we start in DST, and moving
6637a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006638
Tim Peters8bb5ad22003-01-24 02:44:45 +00006639There isn't a sane case where this can happen. The closest it gets is at
6640the end of DST, where there's an hour in UTC with no spelling in a hybrid
6641tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6642that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6643UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6644time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6645clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6646standard time. Since that's what the local clock *does*, we want to map both
6647UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006648in local time, but so it goes -- it's the way the local clock works.
6649
Tim Peters8bb5ad22003-01-24 02:44:45 +00006650When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6651so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6652z' = 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 +00006653(correctly) concludes that z' is not UTC-equivalent to x.
6654
6655Because we know z.d said z was in daylight time (else [5] would have held and
6656we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006657and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006658return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6659but the reasoning doesn't depend on the example -- it depends on there being
6660two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006661z' must be in standard time, and is the spelling we want in this case.
6662
6663Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6664concerned (because it takes z' as being in standard time rather than the
6665daylight time we intend here), but returning it gives the real-life "local
6666clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6667tz.
6668
6669When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6670the 1:MM standard time spelling we want.
6671
6672So how can this break? One of the assumptions must be violated. Two
6673possibilities:
6674
66751) [2] effectively says that y.s is invariant across all y belong to a given
6676 time zone. This isn't true if, for political reasons or continental drift,
6677 a region decides to change its base offset from UTC.
6678
66792) There may be versions of "double daylight" time where the tail end of
6680 the analysis gives up a step too early. I haven't thought about that
6681 enough to say.
6682
6683In any case, it's clear that the default fromutc() is strong enough to handle
6684"almost all" time zones: so long as the standard offset is invariant, it
6685doesn't matter if daylight time transition points change from year to year, or
6686if daylight time is skipped in some years; it doesn't matter how large or
6687small dst() may get within its bounds; and it doesn't even matter if some
6688perverse time zone returns a negative dst()). So a breaking case must be
6689pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006690--------------------------------------------------------------------------- */