blob: c1557b5e6f491dfe69803daca83d28d162eac267 [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)
Paul Ganssle89427cd2019-02-04 14:42:04 -05003007 result = new_date_subclass_ex(year, month, day,
3008 (PyObject* )Py_TYPE(date));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003009 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003010}
3011
3012static PyObject *
3013date_add(PyObject *left, PyObject *right)
3014{
Brian Curtindfc80e32011-08-10 20:28:54 -05003015 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3016 Py_RETURN_NOTIMPLEMENTED;
3017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003018 if (PyDate_Check(left)) {
3019 /* date + ??? */
3020 if (PyDelta_Check(right))
3021 /* date + delta */
3022 return add_date_timedelta((PyDateTime_Date *) left,
3023 (PyDateTime_Delta *) right,
3024 0);
3025 }
3026 else {
3027 /* ??? + date
3028 * 'right' must be one of us, or we wouldn't have been called
3029 */
3030 if (PyDelta_Check(left))
3031 /* delta + date */
3032 return add_date_timedelta((PyDateTime_Date *) right,
3033 (PyDateTime_Delta *) left,
3034 0);
3035 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003036 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003037}
3038
3039static PyObject *
3040date_subtract(PyObject *left, PyObject *right)
3041{
Brian Curtindfc80e32011-08-10 20:28:54 -05003042 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3043 Py_RETURN_NOTIMPLEMENTED;
3044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003045 if (PyDate_Check(left)) {
3046 if (PyDate_Check(right)) {
3047 /* date - date */
3048 int left_ord = ymd_to_ord(GET_YEAR(left),
3049 GET_MONTH(left),
3050 GET_DAY(left));
3051 int right_ord = ymd_to_ord(GET_YEAR(right),
3052 GET_MONTH(right),
3053 GET_DAY(right));
3054 return new_delta(left_ord - right_ord, 0, 0, 0);
3055 }
3056 if (PyDelta_Check(right)) {
3057 /* date - delta */
3058 return add_date_timedelta((PyDateTime_Date *) left,
3059 (PyDateTime_Delta *) right,
3060 1);
3061 }
3062 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003063 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003064}
3065
3066
3067/* Various ways to turn a date into a string. */
3068
3069static PyObject *
3070date_repr(PyDateTime_Date *self)
3071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003072 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3073 Py_TYPE(self)->tp_name,
3074 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003075}
3076
3077static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303078date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003080 return PyUnicode_FromFormat("%04d-%02d-%02d",
3081 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003082}
3083
Tim Peterse2df5ff2003-05-02 18:39:55 +00003084/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003085static PyObject *
3086date_str(PyDateTime_Date *self)
3087{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003088 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003089}
3090
3091
3092static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303093date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003095 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003096}
3097
3098static PyObject *
3099date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003101 /* This method can be inherited, and needs to call the
3102 * timetuple() method appropriate to self's class.
3103 */
3104 PyObject *result;
3105 PyObject *tuple;
3106 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003107 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003108 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3111 &format))
3112 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003113
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003114 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003115 if (tuple == NULL)
3116 return NULL;
3117 result = wrap_strftime((PyObject *)self, format, tuple,
3118 (PyObject *)self);
3119 Py_DECREF(tuple);
3120 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003121}
3122
Eric Smith1ba31142007-09-11 18:06:02 +00003123static PyObject *
3124date_format(PyDateTime_Date *self, PyObject *args)
3125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003126 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3129 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003131 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003132 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003133 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003134
Victor Stinner20401de2016-12-09 15:24:31 +01003135 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3136 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003137}
3138
Tim Peters2a799bf2002-12-16 20:18:38 +00003139/* ISO methods. */
3140
3141static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303142date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003144 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003146 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003147}
3148
3149static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303150date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003152 int year = GET_YEAR(self);
3153 int week1_monday = iso_week1_monday(year);
3154 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3155 int week;
3156 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003158 week = divmod(today - week1_monday, 7, &day);
3159 if (week < 0) {
3160 --year;
3161 week1_monday = iso_week1_monday(year);
3162 week = divmod(today - week1_monday, 7, &day);
3163 }
3164 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3165 ++year;
3166 week = 0;
3167 }
3168 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003169}
3170
3171/* Miscellaneous methods. */
3172
Tim Peters2a799bf2002-12-16 20:18:38 +00003173static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003174date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003176 if (PyDate_Check(other)) {
3177 int diff = memcmp(((PyDateTime_Date *)self)->data,
3178 ((PyDateTime_Date *)other)->data,
3179 _PyDateTime_DATE_DATASIZE);
3180 return diff_to_bool(diff, op);
3181 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003182 else
3183 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003184}
3185
3186static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303187date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003189 return build_struct_time(GET_YEAR(self),
3190 GET_MONTH(self),
3191 GET_DAY(self),
3192 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003193}
3194
Tim Peters12bf3392002-12-24 05:41:27 +00003195static PyObject *
3196date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3197{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 PyObject *clone;
3199 PyObject *tuple;
3200 int year = GET_YEAR(self);
3201 int month = GET_MONTH(self);
3202 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003204 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3205 &year, &month, &day))
3206 return NULL;
3207 tuple = Py_BuildValue("iii", year, month, day);
3208 if (tuple == NULL)
3209 return NULL;
3210 clone = date_new(Py_TYPE(self), tuple, NULL);
3211 Py_DECREF(tuple);
3212 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003213}
3214
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003215static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003216generic_hash(unsigned char *data, int len)
3217{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003218 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003219}
3220
3221
3222static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003223
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003224static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003225date_hash(PyDateTime_Date *self)
3226{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003227 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003228 self->hashcode = generic_hash(
3229 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003230 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003232 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003233}
3234
3235static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303236date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003238 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3239 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003240}
3241
3242static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303243date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003245 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003247 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003248}
3249
Tim Peters371935f2003-02-01 01:52:50 +00003250/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003251
Tim Petersb57f8f02003-02-01 02:54:15 +00003252/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003253static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003254date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003256 PyObject* field;
3257 field = PyBytes_FromStringAndSize((char*)self->data,
3258 _PyDateTime_DATE_DATASIZE);
3259 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003260}
3261
3262static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003263date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003265 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003266}
3267
3268static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003270 /* Class methods: */
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02003271 DATETIME_DATE_FROMTIMESTAMP_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00003272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003273 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3274 METH_CLASS,
3275 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3276 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003277
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003278 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3279 METH_CLASS,
3280 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003282 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3283 PyDoc_STR("Current date or datetime: same as "
3284 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003286 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003288 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3289 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003290
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003291 {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003292 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003294 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3295 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003297 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3298 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003300 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3301 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3302 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003304 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3305 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003307 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3308 PyDoc_STR("Return the day of the week represented by the date.\n"
3309 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003311 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3312 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3313 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003315 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3316 PyDoc_STR("Return the day of the week represented by the date.\n"
3317 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003318
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003319 {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003320 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003322 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3323 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003325 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003326};
3327
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003328static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003329PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003330
3331static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003332 date_add, /* nb_add */
3333 date_subtract, /* nb_subtract */
3334 0, /* nb_multiply */
3335 0, /* nb_remainder */
3336 0, /* nb_divmod */
3337 0, /* nb_power */
3338 0, /* nb_negative */
3339 0, /* nb_positive */
3340 0, /* nb_absolute */
3341 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003342};
3343
3344static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003345 PyVarObject_HEAD_INIT(NULL, 0)
3346 "datetime.date", /* tp_name */
3347 sizeof(PyDateTime_Date), /* tp_basicsize */
3348 0, /* tp_itemsize */
3349 0, /* tp_dealloc */
3350 0, /* tp_print */
3351 0, /* tp_getattr */
3352 0, /* tp_setattr */
3353 0, /* tp_reserved */
3354 (reprfunc)date_repr, /* tp_repr */
3355 &date_as_number, /* tp_as_number */
3356 0, /* tp_as_sequence */
3357 0, /* tp_as_mapping */
3358 (hashfunc)date_hash, /* tp_hash */
3359 0, /* tp_call */
3360 (reprfunc)date_str, /* tp_str */
3361 PyObject_GenericGetAttr, /* tp_getattro */
3362 0, /* tp_setattro */
3363 0, /* tp_as_buffer */
3364 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3365 date_doc, /* tp_doc */
3366 0, /* tp_traverse */
3367 0, /* tp_clear */
3368 date_richcompare, /* tp_richcompare */
3369 0, /* tp_weaklistoffset */
3370 0, /* tp_iter */
3371 0, /* tp_iternext */
3372 date_methods, /* tp_methods */
3373 0, /* tp_members */
3374 date_getset, /* tp_getset */
3375 0, /* tp_base */
3376 0, /* tp_dict */
3377 0, /* tp_descr_get */
3378 0, /* tp_descr_set */
3379 0, /* tp_dictoffset */
3380 0, /* tp_init */
3381 0, /* tp_alloc */
3382 date_new, /* tp_new */
3383 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003384};
3385
3386/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003387 * PyDateTime_TZInfo implementation.
3388 */
3389
3390/* This is a pure abstract base class, so doesn't do anything beyond
3391 * raising NotImplemented exceptions. Real tzinfo classes need
3392 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003393 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003394 * be subclasses of this tzinfo class, which is easy and quick to check).
3395 *
3396 * Note: For reasons having to do with pickling of subclasses, we have
3397 * to allow tzinfo objects to be instantiated. This wasn't an issue
3398 * in the Python implementation (__init__() could raise NotImplementedError
3399 * there without ill effect), but doing so in the C implementation hit a
3400 * brick wall.
3401 */
3402
3403static PyObject *
3404tzinfo_nogo(const char* methodname)
3405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003406 PyErr_Format(PyExc_NotImplementedError,
3407 "a tzinfo subclass must implement %s()",
3408 methodname);
3409 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003410}
3411
3412/* Methods. A subclass must implement these. */
3413
Tim Peters52dcce22003-01-23 16:36:11 +00003414static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003415tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003417 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003418}
3419
Tim Peters52dcce22003-01-23 16:36:11 +00003420static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003421tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003423 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003424}
3425
Tim Peters52dcce22003-01-23 16:36:11 +00003426static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003427tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003429 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003430}
3431
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003432
3433static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3434 PyDateTime_Delta *delta,
3435 int factor);
3436static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3437static PyObject *datetime_dst(PyObject *self, PyObject *);
3438
Tim Peters52dcce22003-01-23 16:36:11 +00003439static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003440tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003441{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003442 PyObject *result = NULL;
3443 PyObject *off = NULL, *dst = NULL;
3444 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003445
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003446 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003447 PyErr_SetString(PyExc_TypeError,
3448 "fromutc: argument must be a datetime");
3449 return NULL;
3450 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003451 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003452 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3453 "is not self");
3454 return NULL;
3455 }
Tim Peters52dcce22003-01-23 16:36:11 +00003456
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003457 off = datetime_utcoffset(dt, NULL);
3458 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003459 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003460 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003461 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3462 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003463 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003464 }
Tim Peters52dcce22003-01-23 16:36:11 +00003465
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003466 dst = datetime_dst(dt, NULL);
3467 if (dst == NULL)
3468 goto Fail;
3469 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003470 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3471 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003472 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003473 }
Tim Peters52dcce22003-01-23 16:36:11 +00003474
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003475 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3476 if (delta == NULL)
3477 goto Fail;
3478 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003479 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003480 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003481
3482 Py_DECREF(dst);
3483 dst = call_dst(GET_DT_TZINFO(dt), result);
3484 if (dst == NULL)
3485 goto Fail;
3486 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003487 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003488 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003489 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003490 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003491 if (result == NULL)
3492 goto Fail;
3493 }
3494 Py_DECREF(delta);
3495 Py_DECREF(dst);
3496 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003497 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003498
3499Inconsistent:
Serhiy Storchaka34fd4c22018-11-05 16:20:25 +02003500 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003501 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003502
Leo Ariasc3d95082018-02-03 18:36:10 -06003503 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003504Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003505 Py_XDECREF(off);
3506 Py_XDECREF(dst);
3507 Py_XDECREF(delta);
3508 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003509 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003510}
3511
Tim Peters2a799bf2002-12-16 20:18:38 +00003512/*
3513 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003514 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003515 */
3516
Guido van Rossum177e41a2003-01-30 22:06:23 +00003517static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303518tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003519{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003520 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003521 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003522 _Py_IDENTIFIER(__getinitargs__);
3523 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003524
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003525 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003526 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003527 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003528 Py_DECREF(getinitargs);
3529 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003530 return NULL;
3531 }
3532 }
3533 else {
3534 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003535
3536 args = PyTuple_New(0);
3537 if (args == NULL) {
3538 return NULL;
3539 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003540 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003541
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003542 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003543 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003544 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003545 Py_DECREF(getstate);
3546 if (state == NULL) {
3547 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003548 return NULL;
3549 }
3550 }
3551 else {
3552 PyObject **dictptr;
3553 PyErr_Clear();
3554 state = Py_None;
3555 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003556 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003557 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003558 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003559 Py_INCREF(state);
3560 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003562 if (state == Py_None) {
3563 Py_DECREF(state);
3564 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3565 }
3566 else
3567 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003568}
Tim Peters2a799bf2002-12-16 20:18:38 +00003569
3570static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003572 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3573 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003575 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003576 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3577 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003579 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003580 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003582 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003583 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003584
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303585 {"__reduce__", tzinfo_reduce, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003586 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003588 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003589};
3590
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003591static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003592PyDoc_STR("Abstract base class for time zone info objects.");
3593
Neal Norwitz227b5332006-03-22 09:28:35 +00003594static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003595 PyVarObject_HEAD_INIT(NULL, 0)
3596 "datetime.tzinfo", /* tp_name */
3597 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3598 0, /* tp_itemsize */
3599 0, /* tp_dealloc */
3600 0, /* tp_print */
3601 0, /* tp_getattr */
3602 0, /* tp_setattr */
3603 0, /* tp_reserved */
3604 0, /* tp_repr */
3605 0, /* tp_as_number */
3606 0, /* tp_as_sequence */
3607 0, /* tp_as_mapping */
3608 0, /* tp_hash */
3609 0, /* tp_call */
3610 0, /* tp_str */
3611 PyObject_GenericGetAttr, /* tp_getattro */
3612 0, /* tp_setattro */
3613 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003614 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003615 tzinfo_doc, /* tp_doc */
3616 0, /* tp_traverse */
3617 0, /* tp_clear */
3618 0, /* tp_richcompare */
3619 0, /* tp_weaklistoffset */
3620 0, /* tp_iter */
3621 0, /* tp_iternext */
3622 tzinfo_methods, /* tp_methods */
3623 0, /* tp_members */
3624 0, /* tp_getset */
3625 0, /* tp_base */
3626 0, /* tp_dict */
3627 0, /* tp_descr_get */
3628 0, /* tp_descr_set */
3629 0, /* tp_dictoffset */
3630 0, /* tp_init */
3631 0, /* tp_alloc */
3632 PyType_GenericNew, /* tp_new */
3633 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003634};
3635
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003636static char *timezone_kws[] = {"offset", "name", NULL};
3637
3638static PyObject *
3639timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3640{
3641 PyObject *offset;
3642 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003643 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3644 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003645 return new_timezone(offset, name);
3646
3647 return NULL;
3648}
3649
3650static void
3651timezone_dealloc(PyDateTime_TimeZone *self)
3652{
3653 Py_CLEAR(self->offset);
3654 Py_CLEAR(self->name);
3655 Py_TYPE(self)->tp_free((PyObject *)self);
3656}
3657
3658static PyObject *
3659timezone_richcompare(PyDateTime_TimeZone *self,
3660 PyDateTime_TimeZone *other, int op)
3661{
Brian Curtindfc80e32011-08-10 20:28:54 -05003662 if (op != Py_EQ && op != Py_NE)
3663 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003664 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003665 if (op == Py_EQ)
3666 Py_RETURN_FALSE;
3667 else
3668 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003669 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003670 return delta_richcompare(self->offset, other->offset, op);
3671}
3672
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003673static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003674timezone_hash(PyDateTime_TimeZone *self)
3675{
3676 return delta_hash((PyDateTime_Delta *)self->offset);
3677}
3678
3679/* Check argument type passed to tzname, utcoffset, or dst methods.
3680 Returns 0 for good argument. Returns -1 and sets exception info
3681 otherwise.
3682 */
3683static int
3684_timezone_check_argument(PyObject *dt, const char *meth)
3685{
3686 if (dt == Py_None || PyDateTime_Check(dt))
3687 return 0;
3688 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3689 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3690 return -1;
3691}
3692
3693static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003694timezone_repr(PyDateTime_TimeZone *self)
3695{
3696 /* Note that although timezone is not subclassable, it is convenient
3697 to use Py_TYPE(self)->tp_name here. */
3698 const char *type_name = Py_TYPE(self)->tp_name;
3699
3700 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3701 return PyUnicode_FromFormat("%s.utc", type_name);
3702
3703 if (self->name == NULL)
3704 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3705
3706 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3707 self->name);
3708}
3709
3710
3711static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003712timezone_str(PyDateTime_TimeZone *self)
3713{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003714 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003715 PyObject *offset;
3716 char sign;
3717
3718 if (self->name != NULL) {
3719 Py_INCREF(self->name);
3720 return self->name;
3721 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003722 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003723 (GET_TD_DAYS(self->offset) == 0 &&
3724 GET_TD_SECONDS(self->offset) == 0 &&
3725 GET_TD_MICROSECONDS(self->offset) == 0))
3726 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003727 /* Offset is normalized, so it is negative if days < 0 */
3728 if (GET_TD_DAYS(self->offset) < 0) {
3729 sign = '-';
3730 offset = delta_negative((PyDateTime_Delta *)self->offset);
3731 if (offset == NULL)
3732 return NULL;
3733 }
3734 else {
3735 sign = '+';
3736 offset = self->offset;
3737 Py_INCREF(offset);
3738 }
3739 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003740 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003741 seconds = GET_TD_SECONDS(offset);
3742 Py_DECREF(offset);
3743 minutes = divmod(seconds, 60, &seconds);
3744 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003745 if (microseconds != 0) {
3746 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3747 sign, hours, minutes,
3748 seconds, microseconds);
3749 }
3750 if (seconds != 0) {
3751 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3752 sign, hours, minutes, seconds);
3753 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003754 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003755}
3756
3757static PyObject *
3758timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3759{
3760 if (_timezone_check_argument(dt, "tzname") == -1)
3761 return NULL;
3762
3763 return timezone_str(self);
3764}
3765
3766static PyObject *
3767timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3768{
3769 if (_timezone_check_argument(dt, "utcoffset") == -1)
3770 return NULL;
3771
3772 Py_INCREF(self->offset);
3773 return self->offset;
3774}
3775
3776static PyObject *
3777timezone_dst(PyObject *self, PyObject *dt)
3778{
3779 if (_timezone_check_argument(dt, "dst") == -1)
3780 return NULL;
3781
3782 Py_RETURN_NONE;
3783}
3784
3785static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003786timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3787{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003788 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003789 PyErr_SetString(PyExc_TypeError,
3790 "fromutc: argument must be a datetime");
3791 return NULL;
3792 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003793 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003794 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3795 "is not self");
3796 return NULL;
3797 }
3798
3799 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3800}
3801
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003802static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303803timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003804{
3805 if (self->name == NULL)
3806 return Py_BuildValue("(O)", self->offset);
3807 return Py_BuildValue("(OO)", self->offset, self->name);
3808}
3809
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003810static PyMethodDef timezone_methods[] = {
3811 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3812 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003813 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003814
3815 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003816 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003817
3818 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003819 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003820
3821 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3822 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3823
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003824 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3825 PyDoc_STR("pickle support")},
3826
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003827 {NULL, NULL}
3828};
3829
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003830static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003831PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3832
3833static PyTypeObject PyDateTime_TimeZoneType = {
3834 PyVarObject_HEAD_INIT(NULL, 0)
3835 "datetime.timezone", /* tp_name */
3836 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3837 0, /* tp_itemsize */
3838 (destructor)timezone_dealloc, /* tp_dealloc */
3839 0, /* tp_print */
3840 0, /* tp_getattr */
3841 0, /* tp_setattr */
3842 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003843 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003844 0, /* tp_as_number */
3845 0, /* tp_as_sequence */
3846 0, /* tp_as_mapping */
3847 (hashfunc)timezone_hash, /* tp_hash */
3848 0, /* tp_call */
3849 (reprfunc)timezone_str, /* tp_str */
3850 0, /* tp_getattro */
3851 0, /* tp_setattro */
3852 0, /* tp_as_buffer */
3853 Py_TPFLAGS_DEFAULT, /* tp_flags */
3854 timezone_doc, /* tp_doc */
3855 0, /* tp_traverse */
3856 0, /* tp_clear */
3857 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3858 0, /* tp_weaklistoffset */
3859 0, /* tp_iter */
3860 0, /* tp_iternext */
3861 timezone_methods, /* tp_methods */
3862 0, /* tp_members */
3863 0, /* tp_getset */
3864 &PyDateTime_TZInfoType, /* tp_base */
3865 0, /* tp_dict */
3866 0, /* tp_descr_get */
3867 0, /* tp_descr_set */
3868 0, /* tp_dictoffset */
3869 0, /* tp_init */
3870 0, /* tp_alloc */
3871 timezone_new, /* tp_new */
3872};
3873
Tim Peters2a799bf2002-12-16 20:18:38 +00003874/*
Tim Peters37f39822003-01-10 03:49:02 +00003875 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003876 */
3877
Tim Peters37f39822003-01-10 03:49:02 +00003878/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003879 */
3880
3881static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003882time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003884 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003885}
3886
Tim Peters37f39822003-01-10 03:49:02 +00003887static PyObject *
3888time_minute(PyDateTime_Time *self, void *unused)
3889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003890 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003891}
3892
3893/* The name time_second conflicted with some platform header file. */
3894static PyObject *
3895py_time_second(PyDateTime_Time *self, void *unused)
3896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003897 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003898}
3899
3900static PyObject *
3901time_microsecond(PyDateTime_Time *self, void *unused)
3902{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003903 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003904}
3905
3906static PyObject *
3907time_tzinfo(PyDateTime_Time *self, void *unused)
3908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003909 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3910 Py_INCREF(result);
3911 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003912}
3913
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003914static PyObject *
3915time_fold(PyDateTime_Time *self, void *unused)
3916{
3917 return PyLong_FromLong(TIME_GET_FOLD(self));
3918}
3919
Tim Peters37f39822003-01-10 03:49:02 +00003920static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003921 {"hour", (getter)time_hour},
3922 {"minute", (getter)time_minute},
3923 {"second", (getter)py_time_second},
3924 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003925 {"tzinfo", (getter)time_tzinfo},
3926 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003927 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003928};
3929
3930/*
3931 * Constructors.
3932 */
3933
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003934static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003935 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003936
Tim Peters2a799bf2002-12-16 20:18:38 +00003937static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02003938time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
3939{
3940 PyDateTime_Time *me;
3941 char aware = (char)(tzinfo != Py_None);
3942
3943 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
3944 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
3945 return NULL;
3946 }
3947
3948 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3949 if (me != NULL) {
3950 const char *pdata = PyBytes_AS_STRING(state);
3951
3952 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3953 me->hashcode = -1;
3954 me->hastzinfo = aware;
3955 if (aware) {
3956 Py_INCREF(tzinfo);
3957 me->tzinfo = tzinfo;
3958 }
3959 if (pdata[0] & (1 << 7)) {
3960 me->data[0] -= 128;
3961 me->fold = 1;
3962 }
3963 else {
3964 me->fold = 0;
3965 }
3966 }
3967 return (PyObject *)me;
3968}
3969
3970static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003971time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003973 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003974 int hour = 0;
3975 int minute = 0;
3976 int second = 0;
3977 int usecond = 0;
3978 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003979 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003981 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02003982 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
3983 PyObject *state = PyTuple_GET_ITEM(args, 0);
3984 if (PyTuple_GET_SIZE(args) == 2) {
3985 tzinfo = PyTuple_GET_ITEM(args, 1);
3986 }
3987 if (PyBytes_Check(state)) {
3988 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3989 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
3990 {
3991 return time_from_pickle(type, state, tzinfo);
3992 }
3993 }
3994 else if (PyUnicode_Check(state)) {
3995 if (PyUnicode_READY(state)) {
3996 return NULL;
3997 }
3998 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
3999 (0x7F & PyUnicode_READ_CHAR(state, 2)) < 24)
4000 {
4001 state = PyUnicode_AsLatin1String(state);
4002 if (state == NULL) {
4003 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4004 /* More informative error message. */
4005 PyErr_SetString(PyExc_ValueError,
4006 "Failed to encode latin1 string when unpickling "
4007 "a time object. "
4008 "pickle.load(data, encoding='latin1') is assumed.");
4009 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004010 return NULL;
4011 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004012 self = time_from_pickle(type, state, tzinfo);
4013 Py_DECREF(state);
4014 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004015 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004016 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004017 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004018 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004019
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004020 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004021 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004022 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004023 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4024 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004025 }
4026 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004027}
4028
4029/*
4030 * Destructor.
4031 */
4032
4033static void
Tim Peters37f39822003-01-10 03:49:02 +00004034time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004036 if (HASTZINFO(self)) {
4037 Py_XDECREF(self->tzinfo);
4038 }
4039 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004040}
4041
4042/*
Tim Peters855fe882002-12-22 03:43:39 +00004043 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004044 */
4045
Tim Peters2a799bf2002-12-16 20:18:38 +00004046/* These are all METH_NOARGS, so don't need to check the arglist. */
4047static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004048time_utcoffset(PyObject *self, PyObject *unused) {
4049 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004050}
4051
4052static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004053time_dst(PyObject *self, PyObject *unused) {
4054 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004055}
4056
4057static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004058time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004059 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004060}
4061
4062/*
Tim Peters37f39822003-01-10 03:49:02 +00004063 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004064 */
4065
4066static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004067time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004069 const char *type_name = Py_TYPE(self)->tp_name;
4070 int h = TIME_GET_HOUR(self);
4071 int m = TIME_GET_MINUTE(self);
4072 int s = TIME_GET_SECOND(self);
4073 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004074 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004075 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004077 if (us)
4078 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4079 type_name, h, m, s, us);
4080 else if (s)
4081 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4082 type_name, h, m, s);
4083 else
4084 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4085 if (result != NULL && HASTZINFO(self))
4086 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004087 if (result != NULL && fold)
4088 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004089 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004090}
4091
Tim Peters37f39822003-01-10 03:49:02 +00004092static PyObject *
4093time_str(PyDateTime_Time *self)
4094{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07004095 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00004096}
Tim Peters2a799bf2002-12-16 20:18:38 +00004097
4098static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004099time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004101 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004102 char *timespec = NULL;
4103 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004104 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004105 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004106 static char *specs[][2] = {
4107 {"hours", "%02d"},
4108 {"minutes", "%02d:%02d"},
4109 {"seconds", "%02d:%02d:%02d"},
4110 {"milliseconds", "%02d:%02d:%02d.%03d"},
4111 {"microseconds", "%02d:%02d:%02d.%06d"},
4112 };
4113 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004114
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004115 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4116 return NULL;
4117
4118 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4119 if (us == 0) {
4120 /* seconds */
4121 given_spec = 2;
4122 }
4123 else {
4124 /* microseconds */
4125 given_spec = 4;
4126 }
4127 }
4128 else {
4129 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4130 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4131 if (given_spec == 3) {
4132 /* milliseconds */
4133 us = us / 1000;
4134 }
4135 break;
4136 }
4137 }
4138 }
4139
4140 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4141 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4142 return NULL;
4143 }
4144 else {
4145 result = PyUnicode_FromFormat(specs[given_spec][1],
4146 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4147 TIME_GET_SECOND(self), us);
4148 }
Tim Peters37f39822003-01-10 03:49:02 +00004149
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004150 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004151 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004153 /* We need to append the UTC offset. */
4154 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4155 Py_None) < 0) {
4156 Py_DECREF(result);
4157 return NULL;
4158 }
4159 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4160 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004161}
4162
Tim Peters37f39822003-01-10 03:49:02 +00004163static PyObject *
4164time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004166 PyObject *result;
4167 PyObject *tuple;
4168 PyObject *format;
4169 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004171 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4172 &format))
4173 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004175 /* Python's strftime does insane things with the year part of the
4176 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004177 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004178 */
4179 tuple = Py_BuildValue("iiiiiiiii",
4180 1900, 1, 1, /* year, month, day */
4181 TIME_GET_HOUR(self),
4182 TIME_GET_MINUTE(self),
4183 TIME_GET_SECOND(self),
4184 0, 1, -1); /* weekday, daynum, dst */
4185 if (tuple == NULL)
4186 return NULL;
4187 assert(PyTuple_Size(tuple) == 9);
4188 result = wrap_strftime((PyObject *)self, format, tuple,
4189 Py_None);
4190 Py_DECREF(tuple);
4191 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004192}
Tim Peters2a799bf2002-12-16 20:18:38 +00004193
4194/*
4195 * Miscellaneous methods.
4196 */
4197
Tim Peters37f39822003-01-10 03:49:02 +00004198static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004199time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004200{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004201 PyObject *result = NULL;
4202 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004203 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004204
Brian Curtindfc80e32011-08-10 20:28:54 -05004205 if (! PyTime_Check(other))
4206 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004207
4208 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004209 diff = memcmp(((PyDateTime_Time *)self)->data,
4210 ((PyDateTime_Time *)other)->data,
4211 _PyDateTime_TIME_DATASIZE);
4212 return diff_to_bool(diff, op);
4213 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004214 offset1 = time_utcoffset(self, NULL);
4215 if (offset1 == NULL)
4216 return NULL;
4217 offset2 = time_utcoffset(other, NULL);
4218 if (offset2 == NULL)
4219 goto done;
4220 /* If they're both naive, or both aware and have the same offsets,
4221 * we get off cheap. Note that if they're both naive, offset1 ==
4222 * offset2 == Py_None at this point.
4223 */
4224 if ((offset1 == offset2) ||
4225 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4226 delta_cmp(offset1, offset2) == 0)) {
4227 diff = memcmp(((PyDateTime_Time *)self)->data,
4228 ((PyDateTime_Time *)other)->data,
4229 _PyDateTime_TIME_DATASIZE);
4230 result = diff_to_bool(diff, op);
4231 }
4232 /* The hard case: both aware with different UTC offsets */
4233 else if (offset1 != Py_None && offset2 != Py_None) {
4234 int offsecs1, offsecs2;
4235 assert(offset1 != offset2); /* else last "if" handled it */
4236 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4237 TIME_GET_MINUTE(self) * 60 +
4238 TIME_GET_SECOND(self) -
4239 GET_TD_DAYS(offset1) * 86400 -
4240 GET_TD_SECONDS(offset1);
4241 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4242 TIME_GET_MINUTE(other) * 60 +
4243 TIME_GET_SECOND(other) -
4244 GET_TD_DAYS(offset2) * 86400 -
4245 GET_TD_SECONDS(offset2);
4246 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004247 if (diff == 0)
4248 diff = TIME_GET_MICROSECOND(self) -
4249 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004250 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004251 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004252 else if (op == Py_EQ) {
4253 result = Py_False;
4254 Py_INCREF(result);
4255 }
4256 else if (op == Py_NE) {
4257 result = Py_True;
4258 Py_INCREF(result);
4259 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004260 else {
4261 PyErr_SetString(PyExc_TypeError,
4262 "can't compare offset-naive and "
4263 "offset-aware times");
4264 }
4265 done:
4266 Py_DECREF(offset1);
4267 Py_XDECREF(offset2);
4268 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004269}
4270
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004271static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004272time_hash(PyDateTime_Time *self)
4273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004274 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004275 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004276 if (TIME_GET_FOLD(self)) {
4277 self0 = new_time_ex2(TIME_GET_HOUR(self),
4278 TIME_GET_MINUTE(self),
4279 TIME_GET_SECOND(self),
4280 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004281 HASTZINFO(self) ? self->tzinfo : Py_None,
4282 0, Py_TYPE(self));
4283 if (self0 == NULL)
4284 return -1;
4285 }
4286 else {
4287 self0 = (PyObject *)self;
4288 Py_INCREF(self0);
4289 }
4290 offset = time_utcoffset(self0, NULL);
4291 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004292
4293 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004294 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004296 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004297 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004298 self->hashcode = generic_hash(
4299 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004300 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004301 PyObject *temp1, *temp2;
4302 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004304 seconds = TIME_GET_HOUR(self) * 3600 +
4305 TIME_GET_MINUTE(self) * 60 +
4306 TIME_GET_SECOND(self);
4307 microseconds = TIME_GET_MICROSECOND(self);
4308 temp1 = new_delta(0, seconds, microseconds, 1);
4309 if (temp1 == NULL) {
4310 Py_DECREF(offset);
4311 return -1;
4312 }
4313 temp2 = delta_subtract(temp1, offset);
4314 Py_DECREF(temp1);
4315 if (temp2 == NULL) {
4316 Py_DECREF(offset);
4317 return -1;
4318 }
4319 self->hashcode = PyObject_Hash(temp2);
4320 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004321 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004322 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004323 }
4324 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004325}
Tim Peters2a799bf2002-12-16 20:18:38 +00004326
Tim Peters12bf3392002-12-24 05:41:27 +00004327static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004328time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004330 PyObject *clone;
4331 PyObject *tuple;
4332 int hh = TIME_GET_HOUR(self);
4333 int mm = TIME_GET_MINUTE(self);
4334 int ss = TIME_GET_SECOND(self);
4335 int us = TIME_GET_MICROSECOND(self);
4336 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004337 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004338
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004339 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004340 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004341 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004342 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004343 if (fold != 0 && fold != 1) {
4344 PyErr_SetString(PyExc_ValueError,
4345 "fold must be either 0 or 1");
4346 return NULL;
4347 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004348 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4349 if (tuple == NULL)
4350 return NULL;
4351 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004352 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004353 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004354 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004355 Py_DECREF(tuple);
4356 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004357}
4358
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004359static PyObject *
4360time_fromisoformat(PyObject *cls, PyObject *tstr) {
4361 assert(tstr != NULL);
4362
4363 if (!PyUnicode_Check(tstr)) {
4364 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4365 return NULL;
4366 }
4367
4368 Py_ssize_t len;
4369 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4370
Paul Ganssle096329f2018-08-23 11:06:20 -04004371 if (p == NULL) {
4372 goto invalid_string_error;
4373 }
4374
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004375 int hour = 0, minute = 0, second = 0, microsecond = 0;
4376 int tzoffset, tzimicrosecond = 0;
4377 int rv = parse_isoformat_time(p, len,
4378 &hour, &minute, &second, &microsecond,
4379 &tzoffset, &tzimicrosecond);
4380
4381 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04004382 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004383 }
4384
4385 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4386 tzimicrosecond);
4387
4388 if (tzinfo == NULL) {
4389 return NULL;
4390 }
4391
4392 PyObject *t;
4393 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4394 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4395 } else {
4396 t = PyObject_CallFunction(cls, "iiiiO",
4397 hour, minute, second, microsecond, tzinfo);
4398 }
4399
4400 Py_DECREF(tzinfo);
4401 return t;
Paul Ganssle096329f2018-08-23 11:06:20 -04004402
4403invalid_string_error:
4404 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4405 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004406}
4407
4408
Tim Peters371935f2003-02-01 01:52:50 +00004409/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004410
Tim Peters33e0f382003-01-10 02:05:14 +00004411/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004412 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4413 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004414 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004415 */
4416static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004417time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004419 PyObject *basestate;
4420 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004422 basestate = PyBytes_FromStringAndSize((char *)self->data,
4423 _PyDateTime_TIME_DATASIZE);
4424 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004425 if (proto > 3 && TIME_GET_FOLD(self))
4426 /* Set the first bit of the first byte */
4427 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004428 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4429 result = PyTuple_Pack(1, basestate);
4430 else
4431 result = PyTuple_Pack(2, basestate, self->tzinfo);
4432 Py_DECREF(basestate);
4433 }
4434 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004435}
4436
4437static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004438time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004439{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004440 int proto;
4441 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004442 return NULL;
4443
4444 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004445}
4446
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004447static PyObject *
4448time_reduce(PyDateTime_Time *self, PyObject *arg)
4449{
4450 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4451}
4452
Tim Peters37f39822003-01-10 03:49:02 +00004453static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004454
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004455 {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS,
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004456 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4457 "[+HH:MM].\n\n"
4458 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004459
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004460 {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004461 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004463 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4464 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004466 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4467 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004469 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4470 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004472 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4473 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004474
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004475 {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004476 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004477
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004478 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4479 PyDoc_STR("string -> time from time.isoformat() output")},
4480
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004481 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004482 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004483
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004484 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4485 PyDoc_STR("__reduce__() -> (cls, state)")},
4486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004487 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004488};
4489
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004490static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004491PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4492\n\
4493All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004494a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004495
Neal Norwitz227b5332006-03-22 09:28:35 +00004496static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004497 PyVarObject_HEAD_INIT(NULL, 0)
4498 "datetime.time", /* tp_name */
4499 sizeof(PyDateTime_Time), /* tp_basicsize */
4500 0, /* tp_itemsize */
4501 (destructor)time_dealloc, /* tp_dealloc */
4502 0, /* tp_print */
4503 0, /* tp_getattr */
4504 0, /* tp_setattr */
4505 0, /* tp_reserved */
4506 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004507 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004508 0, /* tp_as_sequence */
4509 0, /* tp_as_mapping */
4510 (hashfunc)time_hash, /* tp_hash */
4511 0, /* tp_call */
4512 (reprfunc)time_str, /* tp_str */
4513 PyObject_GenericGetAttr, /* tp_getattro */
4514 0, /* tp_setattro */
4515 0, /* tp_as_buffer */
4516 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4517 time_doc, /* tp_doc */
4518 0, /* tp_traverse */
4519 0, /* tp_clear */
4520 time_richcompare, /* tp_richcompare */
4521 0, /* tp_weaklistoffset */
4522 0, /* tp_iter */
4523 0, /* tp_iternext */
4524 time_methods, /* tp_methods */
4525 0, /* tp_members */
4526 time_getset, /* tp_getset */
4527 0, /* tp_base */
4528 0, /* tp_dict */
4529 0, /* tp_descr_get */
4530 0, /* tp_descr_set */
4531 0, /* tp_dictoffset */
4532 0, /* tp_init */
4533 time_alloc, /* tp_alloc */
4534 time_new, /* tp_new */
4535 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004536};
4537
4538/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004539 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004540 */
4541
Tim Petersa9bc1682003-01-11 03:39:11 +00004542/* Accessor properties. Properties for day, month, and year are inherited
4543 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004544 */
4545
4546static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004547datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004549 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004550}
4551
Tim Petersa9bc1682003-01-11 03:39:11 +00004552static PyObject *
4553datetime_minute(PyDateTime_DateTime *self, void *unused)
4554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004555 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004556}
4557
4558static PyObject *
4559datetime_second(PyDateTime_DateTime *self, void *unused)
4560{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004561 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004562}
4563
4564static PyObject *
4565datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4566{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004567 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004568}
4569
4570static PyObject *
4571datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4574 Py_INCREF(result);
4575 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004576}
4577
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004578static PyObject *
4579datetime_fold(PyDateTime_DateTime *self, void *unused)
4580{
4581 return PyLong_FromLong(DATE_GET_FOLD(self));
4582}
4583
Tim Petersa9bc1682003-01-11 03:39:11 +00004584static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004585 {"hour", (getter)datetime_hour},
4586 {"minute", (getter)datetime_minute},
4587 {"second", (getter)datetime_second},
4588 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004589 {"tzinfo", (getter)datetime_tzinfo},
4590 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004591 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004592};
4593
4594/*
4595 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004596 */
4597
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004598static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004599 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004600 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004601};
4602
Tim Peters2a799bf2002-12-16 20:18:38 +00004603static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004604datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4605{
4606 PyDateTime_DateTime *me;
4607 char aware = (char)(tzinfo != Py_None);
4608
4609 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4610 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4611 return NULL;
4612 }
4613
4614 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4615 if (me != NULL) {
4616 const char *pdata = PyBytes_AS_STRING(state);
4617
4618 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4619 me->hashcode = -1;
4620 me->hastzinfo = aware;
4621 if (aware) {
4622 Py_INCREF(tzinfo);
4623 me->tzinfo = tzinfo;
4624 }
4625 if (pdata[2] & (1 << 7)) {
4626 me->data[2] -= 128;
4627 me->fold = 1;
4628 }
4629 else {
4630 me->fold = 0;
4631 }
4632 }
4633 return (PyObject *)me;
4634}
4635
4636static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004637datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004640 int year;
4641 int month;
4642 int day;
4643 int hour = 0;
4644 int minute = 0;
4645 int second = 0;
4646 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004647 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004648 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004650 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004651 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4652 PyObject *state = PyTuple_GET_ITEM(args, 0);
4653 if (PyTuple_GET_SIZE(args) == 2) {
4654 tzinfo = PyTuple_GET_ITEM(args, 1);
4655 }
4656 if (PyBytes_Check(state)) {
4657 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4658 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4659 {
4660 return datetime_from_pickle(type, state, tzinfo);
4661 }
4662 }
4663 else if (PyUnicode_Check(state)) {
4664 if (PyUnicode_READY(state)) {
4665 return NULL;
4666 }
4667 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4668 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4669 {
4670 state = PyUnicode_AsLatin1String(state);
4671 if (state == NULL) {
4672 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4673 /* More informative error message. */
4674 PyErr_SetString(PyExc_ValueError,
4675 "Failed to encode latin1 string when unpickling "
4676 "a datetime object. "
4677 "pickle.load(data, encoding='latin1') is assumed.");
4678 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004679 return NULL;
4680 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004681 self = datetime_from_pickle(type, state, tzinfo);
4682 Py_DECREF(state);
4683 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004684 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004685 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004686 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004687 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004688
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004689 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004690 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004691 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004692 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004693 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004694 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004695 }
4696 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004697}
4698
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004699/* TM_FUNC is the shared type of _PyTime_localtime() and
4700 * _PyTime_gmtime(). */
4701typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004702
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004703/* As of version 2015f max fold in IANA database is
4704 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004705static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004706/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004707static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004708
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004709static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004710utc_to_seconds(int year, int month, int day,
4711 int hour, int minute, int second)
4712{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004713 long long ordinal;
4714
4715 /* ymd_to_ord() doesn't support year <= 0 */
4716 if (year < MINYEAR || year > MAXYEAR) {
4717 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4718 return -1;
4719 }
4720
4721 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004722 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4723}
4724
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004725static long long
4726local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004727{
4728 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004729 time_t t;
4730 u -= epoch;
4731 t = u;
4732 if (t != u) {
4733 PyErr_SetString(PyExc_OverflowError,
4734 "timestamp out of range for platform time_t");
4735 return -1;
4736 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004737 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004738 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004739 return utc_to_seconds(local_time.tm_year + 1900,
4740 local_time.tm_mon + 1,
4741 local_time.tm_mday,
4742 local_time.tm_hour,
4743 local_time.tm_min,
4744 local_time.tm_sec);
4745}
4746
Tim Petersa9bc1682003-01-11 03:39:11 +00004747/* Internal helper.
4748 * Build datetime from a time_t and a distinct count of microseconds.
4749 * Pass localtime or gmtime for f, to control the interpretation of timet.
4750 */
4751static PyObject *
4752datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004753 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004754{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004755 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004756 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004757
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004758 if (f(timet, &tm) != 0)
4759 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004760
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004761 year = tm.tm_year + 1900;
4762 month = tm.tm_mon + 1;
4763 day = tm.tm_mday;
4764 hour = tm.tm_hour;
4765 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004766 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004767 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004768 * except to the extent that passing them on to the datetime
4769 * constructor would raise ValueError for a reason that
4770 * made no sense to the user.
4771 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004772 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004773
Victor Stinnerb67f0962017-02-10 10:34:02 +01004774 /* local timezone requires to compute fold */
Ammar Askar96d1e692018-07-25 09:54:58 -07004775 if (tzinfo == Py_None && f == _PyTime_localtime
4776 /* On Windows, passing a negative value to local results
4777 * in an OSError because localtime_s on Windows does
4778 * not support negative timestamps. Unfortunately this
4779 * means that fold detection for time values between
4780 * 0 and max_fold_seconds will result in an identical
4781 * error since we subtract max_fold_seconds to detect a
4782 * fold. However, since we know there haven't been any
4783 * folds in the interval [0, max_fold_seconds) in any
4784 * timezone, we can hackily just forego fold detection
4785 * for this time range.
4786 */
4787#ifdef MS_WINDOWS
4788 && (timet - max_fold_seconds > 0)
4789#endif
4790 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004791 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004792
4793 result_seconds = utc_to_seconds(year, month, day,
4794 hour, minute, second);
4795 /* Probe max_fold_seconds to detect a fold. */
4796 probe_seconds = local(epoch + timet - max_fold_seconds);
4797 if (probe_seconds == -1)
4798 return NULL;
4799 transition = result_seconds - probe_seconds - max_fold_seconds;
4800 if (transition < 0) {
4801 probe_seconds = local(epoch + timet + transition);
4802 if (probe_seconds == -1)
4803 return NULL;
4804 if (probe_seconds == result_seconds)
4805 fold = 1;
4806 }
4807 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004808 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4809 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004810}
4811
4812/* Internal helper.
4813 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4814 * to control the interpretation of the timestamp. Since a double doesn't
4815 * have enough bits to cover a datetime's full range of precision, it's
4816 * better to call datetime_from_timet_and_us provided you have a way
4817 * to get that much precision (e.g., C time() isn't good enough).
4818 */
4819static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004820datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004821 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004823 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004824 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004825
Victor Stinnere4a994d2015-03-30 01:10:14 +02004826 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004827 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004828 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004829
Victor Stinner21f58932012-03-14 00:15:40 +01004830 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004831}
4832
4833/* Internal helper.
4834 * Build most accurate possible datetime for current time. Pass localtime or
4835 * gmtime for f as appropriate.
4836 */
4837static PyObject *
4838datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4839{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004840 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004841 time_t secs;
4842 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004843
Victor Stinner1e2b6882015-09-18 13:23:02 +02004844 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004845 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004846 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004847
Victor Stinner1e2b6882015-09-18 13:23:02 +02004848 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004849}
4850
Larry Hastings61272b72014-01-07 12:41:53 -08004851/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004852
4853@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004854datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004855
4856 tz: object = None
4857 Timezone object.
4858
4859Returns new datetime object representing current time local to tz.
4860
4861If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004862[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004863
Larry Hastings31826802013-10-19 00:09:25 -07004864static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004865datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004866/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004868 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004869
Larry Hastings31826802013-10-19 00:09:25 -07004870 /* Return best possible local time -- this isn't constrained by the
4871 * precision of a timestamp.
4872 */
4873 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004874 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004875
Larry Hastings5c661892014-01-24 06:17:25 -08004876 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004877 tz == Py_None ? _PyTime_localtime :
4878 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004879 tz);
4880 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004881 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004882 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004883 }
4884 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004885}
4886
Tim Petersa9bc1682003-01-11 03:39:11 +00004887/* Return best possible UTC time -- this isn't constrained by the
4888 * precision of a timestamp.
4889 */
4890static PyObject *
4891datetime_utcnow(PyObject *cls, PyObject *dummy)
4892{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004893 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004894}
4895
Tim Peters2a799bf2002-12-16 20:18:38 +00004896/* Return new local datetime from timestamp (Python timestamp -- a double). */
4897static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004898datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004900 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004901 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004902 PyObject *tzinfo = Py_None;
4903 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004904
Victor Stinner5d272cc2012-03-13 13:35:55 +01004905 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004906 keywords, &timestamp, &tzinfo))
4907 return NULL;
4908 if (check_tzinfo_subclass(tzinfo) < 0)
4909 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004911 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004912 tzinfo == Py_None ? _PyTime_localtime :
4913 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004914 timestamp,
4915 tzinfo);
4916 if (self != NULL && tzinfo != Py_None) {
4917 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004918 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004919 }
4920 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004921}
4922
Tim Petersa9bc1682003-01-11 03:39:11 +00004923/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4924static PyObject *
4925datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4926{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004927 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004928 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004929
Victor Stinner5d272cc2012-03-13 13:35:55 +01004930 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004931 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004932 Py_None);
4933 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004934}
4935
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004936/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004937static PyObject *
4938datetime_strptime(PyObject *cls, PyObject *args)
4939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004940 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004941 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004942 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004943
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004944 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004945 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004946
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004947 if (module == NULL) {
4948 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004949 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004950 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004951 }
Victor Stinner20401de2016-12-09 15:24:31 +01004952 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4953 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004954}
4955
Tim Petersa9bc1682003-01-11 03:39:11 +00004956/* Return new datetime from date/datetime and time arguments. */
4957static PyObject *
4958datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4959{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004960 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004961 PyObject *date;
4962 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004963 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004964 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004965
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004966 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004967 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004968 &PyDateTime_TimeType, &time, &tzinfo)) {
4969 if (tzinfo == NULL) {
4970 if (HASTZINFO(time))
4971 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4972 else
4973 tzinfo = Py_None;
4974 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004975 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
4976 GET_MONTH(date),
4977 GET_DAY(date),
4978 TIME_GET_HOUR(time),
4979 TIME_GET_MINUTE(time),
4980 TIME_GET_SECOND(time),
4981 TIME_GET_MICROSECOND(time),
4982 tzinfo,
4983 TIME_GET_FOLD(time),
4984 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004985 }
4986 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004987}
Tim Peters2a799bf2002-12-16 20:18:38 +00004988
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004989static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04004990_sanitize_isoformat_str(PyObject *dtstr)
4991{
Paul Ganssle096329f2018-08-23 11:06:20 -04004992 // `fromisoformat` allows surrogate characters in exactly one position,
4993 // the separator; to allow datetime_fromisoformat to make the simplifying
4994 // assumption that all valid strings can be encoded in UTF-8, this function
4995 // replaces any surrogate character separators with `T`.
Paul Ganssle3df85402018-10-22 12:32:52 -04004996 //
4997 // The result of this, if not NULL, returns a new reference
Paul Ganssle096329f2018-08-23 11:06:20 -04004998 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Paul Ganssle3df85402018-10-22 12:32:52 -04004999 if (len < 0) {
5000 return NULL;
5001 }
5002
5003 if (len <= 10 ||
5004 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
5005 Py_INCREF(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005006 return dtstr;
5007 }
5008
Paul Ganssle3df85402018-10-22 12:32:52 -04005009 PyObject *str_out = _PyUnicode_Copy(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005010 if (str_out == NULL) {
5011 return NULL;
5012 }
5013
Paul Ganssle3df85402018-10-22 12:32:52 -04005014 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005015 Py_DECREF(str_out);
5016 return NULL;
5017 }
5018
Paul Ganssle096329f2018-08-23 11:06:20 -04005019 return str_out;
5020}
5021
5022static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005023datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5024{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005025 assert(dtstr != NULL);
5026
5027 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005028 PyErr_SetString(PyExc_TypeError,
5029 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005030 return NULL;
5031 }
5032
Paul Ganssle3df85402018-10-22 12:32:52 -04005033 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5034 if (dtstr_clean == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005035 goto error;
5036 }
5037
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005038 Py_ssize_t len;
Paul Ganssle3df85402018-10-22 12:32:52 -04005039 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04005040
5041 if (dt_ptr == NULL) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005042 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5043 // Encoding errors are invalid string errors at this point
5044 goto invalid_string_error;
5045 }
5046 else {
5047 goto error;
5048 }
Paul Ganssle096329f2018-08-23 11:06:20 -04005049 }
5050
5051 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005052
5053 int year = 0, month = 0, day = 0;
5054 int hour = 0, minute = 0, second = 0, microsecond = 0;
5055 int tzoffset = 0, tzusec = 0;
5056
5057 // date has a fixed length of 10
5058 int rv = parse_isoformat_date(p, &year, &month, &day);
5059
5060 if (!rv && len > 10) {
5061 // In UTF-8, the length of multi-byte characters is encoded in the MSB
5062 if ((p[10] & 0x80) == 0) {
5063 p += 11;
Paul Ganssle3df85402018-10-22 12:32:52 -04005064 }
5065 else {
5066 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005067 case 0xe0:
5068 p += 13;
5069 break;
5070 case 0xf0:
5071 p += 14;
5072 break;
5073 default:
5074 p += 12;
5075 break;
5076 }
5077 }
5078
5079 len -= (p - dt_ptr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005080 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5081 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005082 }
5083 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005084 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005085 }
5086
Paul Ganssle3df85402018-10-22 12:32:52 -04005087 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005088 if (tzinfo == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005089 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005090 }
5091
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005092 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5093 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005094
5095 Py_DECREF(tzinfo);
Paul Ganssle3df85402018-10-22 12:32:52 -04005096 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005097 return dt;
Paul Ganssle096329f2018-08-23 11:06:20 -04005098
5099invalid_string_error:
5100 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5101
5102error:
Paul Ganssle3df85402018-10-22 12:32:52 -04005103 Py_XDECREF(dtstr_clean);
Paul Ganssle096329f2018-08-23 11:06:20 -04005104
5105 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005106}
5107
Tim Peters2a799bf2002-12-16 20:18:38 +00005108/*
5109 * Destructor.
5110 */
5111
5112static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005113datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005115 if (HASTZINFO(self)) {
5116 Py_XDECREF(self->tzinfo);
5117 }
5118 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005119}
5120
5121/*
5122 * Indirect access to tzinfo methods.
5123 */
5124
Tim Peters2a799bf2002-12-16 20:18:38 +00005125/* These are all METH_NOARGS, so don't need to check the arglist. */
5126static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005127datetime_utcoffset(PyObject *self, PyObject *unused) {
5128 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005129}
5130
5131static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005132datetime_dst(PyObject *self, PyObject *unused) {
5133 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005134}
5135
5136static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005137datetime_tzname(PyObject *self, PyObject *unused) {
5138 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005139}
5140
5141/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005142 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005143 */
5144
Tim Petersa9bc1682003-01-11 03:39:11 +00005145/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5146 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005147 */
5148static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005149add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005150 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005152 /* Note that the C-level additions can't overflow, because of
5153 * invariant bounds on the member values.
5154 */
5155 int year = GET_YEAR(date);
5156 int month = GET_MONTH(date);
5157 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5158 int hour = DATE_GET_HOUR(date);
5159 int minute = DATE_GET_MINUTE(date);
5160 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5161 int microsecond = DATE_GET_MICROSECOND(date) +
5162 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005164 assert(factor == 1 || factor == -1);
5165 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005166 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005167 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005168 }
5169
Paul Ganssle89427cd2019-02-04 14:42:04 -05005170 return new_datetime_subclass_ex(year, month, day,
5171 hour, minute, second, microsecond,
5172 HASTZINFO(date) ? date->tzinfo : Py_None,
5173 (PyObject *)Py_TYPE(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00005174}
5175
5176static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005177datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005179 if (PyDateTime_Check(left)) {
5180 /* datetime + ??? */
5181 if (PyDelta_Check(right))
5182 /* datetime + delta */
5183 return add_datetime_timedelta(
5184 (PyDateTime_DateTime *)left,
5185 (PyDateTime_Delta *)right,
5186 1);
5187 }
5188 else if (PyDelta_Check(left)) {
5189 /* delta + datetime */
5190 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5191 (PyDateTime_Delta *) left,
5192 1);
5193 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005194 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005195}
5196
5197static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005198datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005200 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005202 if (PyDateTime_Check(left)) {
5203 /* datetime - ??? */
5204 if (PyDateTime_Check(right)) {
5205 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005206 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005207 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005208
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005209 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5210 offset2 = offset1 = Py_None;
5211 Py_INCREF(offset1);
5212 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005213 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005214 else {
5215 offset1 = datetime_utcoffset(left, NULL);
5216 if (offset1 == NULL)
5217 return NULL;
5218 offset2 = datetime_utcoffset(right, NULL);
5219 if (offset2 == NULL) {
5220 Py_DECREF(offset1);
5221 return NULL;
5222 }
5223 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5224 PyErr_SetString(PyExc_TypeError,
5225 "can't subtract offset-naive and "
5226 "offset-aware datetimes");
5227 Py_DECREF(offset1);
5228 Py_DECREF(offset2);
5229 return NULL;
5230 }
5231 }
5232 if ((offset1 != offset2) &&
5233 delta_cmp(offset1, offset2) != 0) {
5234 offdiff = delta_subtract(offset1, offset2);
5235 if (offdiff == NULL) {
5236 Py_DECREF(offset1);
5237 Py_DECREF(offset2);
5238 return NULL;
5239 }
5240 }
5241 Py_DECREF(offset1);
5242 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 delta_d = ymd_to_ord(GET_YEAR(left),
5244 GET_MONTH(left),
5245 GET_DAY(left)) -
5246 ymd_to_ord(GET_YEAR(right),
5247 GET_MONTH(right),
5248 GET_DAY(right));
5249 /* These can't overflow, since the values are
5250 * normalized. At most this gives the number of
5251 * seconds in one day.
5252 */
5253 delta_s = (DATE_GET_HOUR(left) -
5254 DATE_GET_HOUR(right)) * 3600 +
5255 (DATE_GET_MINUTE(left) -
5256 DATE_GET_MINUTE(right)) * 60 +
5257 (DATE_GET_SECOND(left) -
5258 DATE_GET_SECOND(right));
5259 delta_us = DATE_GET_MICROSECOND(left) -
5260 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005261 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005262 if (result == NULL)
5263 return NULL;
5264
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005265 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005266 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005267 Py_DECREF(offdiff);
5268 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005269 }
5270 else if (PyDelta_Check(right)) {
5271 /* datetime - delta */
5272 result = add_datetime_timedelta(
5273 (PyDateTime_DateTime *)left,
5274 (PyDateTime_Delta *)right,
5275 -1);
5276 }
5277 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005279 if (result == Py_NotImplemented)
5280 Py_INCREF(result);
5281 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005282}
5283
5284/* Various ways to turn a datetime into a string. */
5285
5286static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005287datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005288{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005289 const char *type_name = Py_TYPE(self)->tp_name;
5290 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005292 if (DATE_GET_MICROSECOND(self)) {
5293 baserepr = PyUnicode_FromFormat(
5294 "%s(%d, %d, %d, %d, %d, %d, %d)",
5295 type_name,
5296 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5297 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5298 DATE_GET_SECOND(self),
5299 DATE_GET_MICROSECOND(self));
5300 }
5301 else if (DATE_GET_SECOND(self)) {
5302 baserepr = PyUnicode_FromFormat(
5303 "%s(%d, %d, %d, %d, %d, %d)",
5304 type_name,
5305 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5306 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5307 DATE_GET_SECOND(self));
5308 }
5309 else {
5310 baserepr = PyUnicode_FromFormat(
5311 "%s(%d, %d, %d, %d, %d)",
5312 type_name,
5313 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5314 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5315 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005316 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5317 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005318 if (baserepr == NULL || ! HASTZINFO(self))
5319 return baserepr;
5320 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005321}
5322
Tim Petersa9bc1682003-01-11 03:39:11 +00005323static PyObject *
5324datetime_str(PyDateTime_DateTime *self)
5325{
Victor Stinner4c381542016-12-09 00:33:39 +01005326 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005327}
Tim Peters2a799bf2002-12-16 20:18:38 +00005328
5329static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005330datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005332 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005333 char *timespec = NULL;
5334 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005335 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005336 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005337 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005338 static char *specs[][2] = {
5339 {"hours", "%04d-%02d-%02d%c%02d"},
5340 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5341 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5342 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5343 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5344 };
5345 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005346
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005347 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005348 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005349
5350 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5351 if (us == 0) {
5352 /* seconds */
5353 given_spec = 2;
5354 }
5355 else {
5356 /* microseconds */
5357 given_spec = 4;
5358 }
5359 }
5360 else {
5361 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5362 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5363 if (given_spec == 3) {
5364 us = us / 1000;
5365 }
5366 break;
5367 }
5368 }
5369 }
5370
5371 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5372 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5373 return NULL;
5374 }
5375 else {
5376 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005377 GET_YEAR(self), GET_MONTH(self),
5378 GET_DAY(self), (int)sep,
5379 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5380 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005381 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005383 if (!result || !HASTZINFO(self))
5384 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005386 /* We need to append the UTC offset. */
5387 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5388 (PyObject *)self) < 0) {
5389 Py_DECREF(result);
5390 return NULL;
5391 }
5392 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5393 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005394}
5395
Tim Petersa9bc1682003-01-11 03:39:11 +00005396static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305397datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005399 return format_ctime((PyDateTime_Date *)self,
5400 DATE_GET_HOUR(self),
5401 DATE_GET_MINUTE(self),
5402 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005403}
5404
Tim Peters2a799bf2002-12-16 20:18:38 +00005405/* Miscellaneous methods. */
5406
Tim Petersa9bc1682003-01-11 03:39:11 +00005407static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005408flip_fold(PyObject *dt)
5409{
5410 return new_datetime_ex2(GET_YEAR(dt),
5411 GET_MONTH(dt),
5412 GET_DAY(dt),
5413 DATE_GET_HOUR(dt),
5414 DATE_GET_MINUTE(dt),
5415 DATE_GET_SECOND(dt),
5416 DATE_GET_MICROSECOND(dt),
5417 HASTZINFO(dt) ?
5418 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5419 !DATE_GET_FOLD(dt),
5420 Py_TYPE(dt));
5421}
5422
5423static PyObject *
5424get_flip_fold_offset(PyObject *dt)
5425{
5426 PyObject *result, *flip_dt;
5427
5428 flip_dt = flip_fold(dt);
5429 if (flip_dt == NULL)
5430 return NULL;
5431 result = datetime_utcoffset(flip_dt, NULL);
5432 Py_DECREF(flip_dt);
5433 return result;
5434}
5435
5436/* PEP 495 exception: Whenever one or both of the operands in
5437 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakabac2d5b2018-03-28 22:14:26 +03005438 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005439 *
5440 * Return 1 if exception applies, 0 if not, and -1 on error.
5441 */
5442static int
5443pep495_eq_exception(PyObject *self, PyObject *other,
5444 PyObject *offset_self, PyObject *offset_other)
5445{
5446 int result = 0;
5447 PyObject *flip_offset;
5448
5449 flip_offset = get_flip_fold_offset(self);
5450 if (flip_offset == NULL)
5451 return -1;
5452 if (flip_offset != offset_self &&
5453 delta_cmp(flip_offset, offset_self))
5454 {
5455 result = 1;
5456 goto done;
5457 }
5458 Py_DECREF(flip_offset);
5459
5460 flip_offset = get_flip_fold_offset(other);
5461 if (flip_offset == NULL)
5462 return -1;
5463 if (flip_offset != offset_other &&
5464 delta_cmp(flip_offset, offset_other))
5465 result = 1;
5466 done:
5467 Py_DECREF(flip_offset);
5468 return result;
5469}
5470
5471static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005472datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005473{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005474 PyObject *result = NULL;
5475 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005476 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005478 if (! PyDateTime_Check(other)) {
5479 if (PyDate_Check(other)) {
5480 /* Prevent invocation of date_richcompare. We want to
5481 return NotImplemented here to give the other object
5482 a chance. But since DateTime is a subclass of
5483 Date, if the other object is a Date, it would
5484 compute an ordering based on the date part alone,
5485 and we don't want that. So force unequal or
5486 uncomparable here in that case. */
5487 if (op == Py_EQ)
5488 Py_RETURN_FALSE;
5489 if (op == Py_NE)
5490 Py_RETURN_TRUE;
5491 return cmperror(self, other);
5492 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005493 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005494 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005495
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005496 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005497 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5498 ((PyDateTime_DateTime *)other)->data,
5499 _PyDateTime_DATETIME_DATASIZE);
5500 return diff_to_bool(diff, op);
5501 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005502 offset1 = datetime_utcoffset(self, NULL);
5503 if (offset1 == NULL)
5504 return NULL;
5505 offset2 = datetime_utcoffset(other, NULL);
5506 if (offset2 == NULL)
5507 goto done;
5508 /* If they're both naive, or both aware and have the same offsets,
5509 * we get off cheap. Note that if they're both naive, offset1 ==
5510 * offset2 == Py_None at this point.
5511 */
5512 if ((offset1 == offset2) ||
5513 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5514 delta_cmp(offset1, offset2) == 0)) {
5515 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5516 ((PyDateTime_DateTime *)other)->data,
5517 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005518 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5519 int ex = pep495_eq_exception(self, other, offset1, offset2);
5520 if (ex == -1)
5521 goto done;
5522 if (ex)
5523 diff = 1;
5524 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005525 result = diff_to_bool(diff, op);
5526 }
5527 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005528 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005529
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005530 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005531 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5532 other);
5533 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005534 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005535 diff = GET_TD_DAYS(delta);
5536 if (diff == 0)
5537 diff = GET_TD_SECONDS(delta) |
5538 GET_TD_MICROSECONDS(delta);
5539 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005540 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5541 int ex = pep495_eq_exception(self, other, offset1, offset2);
5542 if (ex == -1)
5543 goto done;
5544 if (ex)
5545 diff = 1;
5546 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005547 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005548 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005549 else if (op == Py_EQ) {
5550 result = Py_False;
5551 Py_INCREF(result);
5552 }
5553 else if (op == Py_NE) {
5554 result = Py_True;
5555 Py_INCREF(result);
5556 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005557 else {
5558 PyErr_SetString(PyExc_TypeError,
5559 "can't compare offset-naive and "
5560 "offset-aware datetimes");
5561 }
5562 done:
5563 Py_DECREF(offset1);
5564 Py_XDECREF(offset2);
5565 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005566}
5567
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005568static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005569datetime_hash(PyDateTime_DateTime *self)
5570{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005571 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005572 PyObject *offset, *self0;
5573 if (DATE_GET_FOLD(self)) {
5574 self0 = new_datetime_ex2(GET_YEAR(self),
5575 GET_MONTH(self),
5576 GET_DAY(self),
5577 DATE_GET_HOUR(self),
5578 DATE_GET_MINUTE(self),
5579 DATE_GET_SECOND(self),
5580 DATE_GET_MICROSECOND(self),
5581 HASTZINFO(self) ? self->tzinfo : Py_None,
5582 0, Py_TYPE(self));
5583 if (self0 == NULL)
5584 return -1;
5585 }
5586 else {
5587 self0 = (PyObject *)self;
5588 Py_INCREF(self0);
5589 }
5590 offset = datetime_utcoffset(self0, NULL);
5591 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005592
5593 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005594 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005596 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005597 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005598 self->hashcode = generic_hash(
5599 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005600 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005601 PyObject *temp1, *temp2;
5602 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005604 assert(HASTZINFO(self));
5605 days = ymd_to_ord(GET_YEAR(self),
5606 GET_MONTH(self),
5607 GET_DAY(self));
5608 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005609 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005610 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005611 temp1 = new_delta(days, seconds,
5612 DATE_GET_MICROSECOND(self),
5613 1);
5614 if (temp1 == NULL) {
5615 Py_DECREF(offset);
5616 return -1;
5617 }
5618 temp2 = delta_subtract(temp1, offset);
5619 Py_DECREF(temp1);
5620 if (temp2 == NULL) {
5621 Py_DECREF(offset);
5622 return -1;
5623 }
5624 self->hashcode = PyObject_Hash(temp2);
5625 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005626 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005627 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005628 }
5629 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005630}
Tim Peters2a799bf2002-12-16 20:18:38 +00005631
5632static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005633datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005634{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005635 PyObject *clone;
5636 PyObject *tuple;
5637 int y = GET_YEAR(self);
5638 int m = GET_MONTH(self);
5639 int d = GET_DAY(self);
5640 int hh = DATE_GET_HOUR(self);
5641 int mm = DATE_GET_MINUTE(self);
5642 int ss = DATE_GET_SECOND(self);
5643 int us = DATE_GET_MICROSECOND(self);
5644 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005645 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005646
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005647 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005648 datetime_kws,
5649 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005650 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005651 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005652 if (fold != 0 && fold != 1) {
5653 PyErr_SetString(PyExc_ValueError,
5654 "fold must be either 0 or 1");
5655 return NULL;
5656 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005657 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5658 if (tuple == NULL)
5659 return NULL;
5660 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005661 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005662 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005663 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005664 Py_DECREF(tuple);
5665 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005666}
5667
5668static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005669local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005670{
5671 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005672 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005673 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005674 PyObject *nameo = NULL;
5675 const char *zone = NULL;
5676
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005677 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005678 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005679#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005680 zone = local_time_tm.tm_zone;
5681 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005682#else /* HAVE_STRUCT_TM_TM_ZONE */
5683 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005684 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005685 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005686 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005687 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005688 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005689 local_time = new_datetime(local_time_tm.tm_year + 1900,
5690 local_time_tm.tm_mon + 1,
5691 local_time_tm.tm_mday,
5692 local_time_tm.tm_hour,
5693 local_time_tm.tm_min,
5694 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005695 if (local_time == NULL) {
5696 return NULL;
5697 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005698 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005699 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005700 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5701 utc_time_tm.tm_mon + 1,
5702 utc_time_tm.tm_mday,
5703 utc_time_tm.tm_hour,
5704 utc_time_tm.tm_min,
5705 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005706 if (utc_time == NULL) {
5707 Py_DECREF(local_time);
5708 return NULL;
5709 }
5710 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005711 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005712 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005713 }
5714#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005715 if (delta == NULL) {
5716 return NULL;
5717 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005718 if (zone != NULL) {
5719 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5720 if (nameo == NULL)
5721 goto error;
5722 }
5723 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005724 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005725 error:
5726 Py_DECREF(delta);
5727 return result;
5728}
5729
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005730static PyObject *
5731local_timezone(PyDateTime_DateTime *utc_time)
5732{
5733 time_t timestamp;
5734 PyObject *delta;
5735 PyObject *one_second;
5736 PyObject *seconds;
5737
5738 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5739 if (delta == NULL)
5740 return NULL;
5741 one_second = new_delta(0, 1, 0, 0);
5742 if (one_second == NULL) {
5743 Py_DECREF(delta);
5744 return NULL;
5745 }
5746 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5747 (PyDateTime_Delta *)one_second);
5748 Py_DECREF(one_second);
5749 Py_DECREF(delta);
5750 if (seconds == NULL)
5751 return NULL;
5752 timestamp = _PyLong_AsTime_t(seconds);
5753 Py_DECREF(seconds);
5754 if (timestamp == -1 && PyErr_Occurred())
5755 return NULL;
5756 return local_timezone_from_timestamp(timestamp);
5757}
5758
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005759static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005760local_to_seconds(int year, int month, int day,
5761 int hour, int minute, int second, int fold);
5762
5763static PyObject *
5764local_timezone_from_local(PyDateTime_DateTime *local_dt)
5765{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005766 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005767 time_t timestamp;
5768 seconds = local_to_seconds(GET_YEAR(local_dt),
5769 GET_MONTH(local_dt),
5770 GET_DAY(local_dt),
5771 DATE_GET_HOUR(local_dt),
5772 DATE_GET_MINUTE(local_dt),
5773 DATE_GET_SECOND(local_dt),
5774 DATE_GET_FOLD(local_dt));
5775 if (seconds == -1)
5776 return NULL;
5777 /* XXX: add bounds check */
5778 timestamp = seconds - epoch;
5779 return local_timezone_from_timestamp(timestamp);
5780}
5781
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005782static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005783datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005784{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005785 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005786 PyObject *offset;
5787 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005788 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005789 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005790 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005791
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005792 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005793 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005794 return NULL;
5795
5796 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005797 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005798
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005799 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005800 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005801 self_tzinfo = local_timezone_from_local(self);
5802 if (self_tzinfo == NULL)
5803 return NULL;
5804 } else {
5805 self_tzinfo = self->tzinfo;
5806 Py_INCREF(self_tzinfo);
5807 }
Tim Peters521fc152002-12-31 17:36:56 +00005808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005809 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005810 if (self_tzinfo == tzinfo) {
5811 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005812 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005813 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005814 }
Tim Peters521fc152002-12-31 17:36:56 +00005815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005816 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005817 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5818 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005819 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005820 return NULL;
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005821 else if(offset == Py_None) {
5822 Py_DECREF(offset);
5823 goto naive;
5824 }
5825 else if (!PyDelta_Check(offset)) {
5826 Py_DECREF(offset);
5827 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5828 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5829 return NULL;
5830 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005831 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005832 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5833 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005834 Py_DECREF(offset);
5835 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005836 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005837
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005838 /* Make sure result is aware and UTC. */
5839 if (!HASTZINFO(result)) {
5840 temp = (PyObject *)result;
5841 result = (PyDateTime_DateTime *)
5842 new_datetime_ex2(GET_YEAR(result),
5843 GET_MONTH(result),
5844 GET_DAY(result),
5845 DATE_GET_HOUR(result),
5846 DATE_GET_MINUTE(result),
5847 DATE_GET_SECOND(result),
5848 DATE_GET_MICROSECOND(result),
5849 PyDateTime_TimeZone_UTC,
5850 DATE_GET_FOLD(result),
5851 Py_TYPE(result));
5852 Py_DECREF(temp);
5853 if (result == NULL)
5854 return NULL;
5855 }
5856 else {
5857 /* Result is already aware - just replace tzinfo. */
5858 temp = result->tzinfo;
5859 result->tzinfo = PyDateTime_TimeZone_UTC;
5860 Py_INCREF(result->tzinfo);
5861 Py_DECREF(temp);
5862 }
5863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005864 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005865 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005866 if (tzinfo == Py_None) {
5867 tzinfo = local_timezone(result);
5868 if (tzinfo == NULL) {
5869 Py_DECREF(result);
5870 return NULL;
5871 }
5872 }
5873 else
5874 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005875 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005876 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005877
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005878 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005879 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005880 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005881 Py_DECREF(temp);
5882
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005883 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005884}
5885
5886static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305887datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00005888{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005889 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005891 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005892 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005893
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005894 dst = call_dst(self->tzinfo, (PyObject *)self);
5895 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005896 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005897
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005898 if (dst != Py_None)
5899 dstflag = delta_bool((PyDateTime_Delta *)dst);
5900 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005901 }
5902 return build_struct_time(GET_YEAR(self),
5903 GET_MONTH(self),
5904 GET_DAY(self),
5905 DATE_GET_HOUR(self),
5906 DATE_GET_MINUTE(self),
5907 DATE_GET_SECOND(self),
5908 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005909}
5910
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005911static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005912local_to_seconds(int year, int month, int day,
5913 int hour, int minute, int second, int fold)
5914{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005915 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005916 t = utc_to_seconds(year, month, day, hour, minute, second);
5917 /* Our goal is to solve t = local(u) for u. */
5918 lt = local(t);
5919 if (lt == -1)
5920 return -1;
5921 a = lt - t;
5922 u1 = t - a;
5923 t1 = local(u1);
5924 if (t1 == -1)
5925 return -1;
5926 if (t1 == t) {
5927 /* We found one solution, but it may not be the one we need.
5928 * Look for an earlier solution (if `fold` is 0), or a
5929 * later one (if `fold` is 1). */
5930 if (fold)
5931 u2 = u1 + max_fold_seconds;
5932 else
5933 u2 = u1 - max_fold_seconds;
5934 lt = local(u2);
5935 if (lt == -1)
5936 return -1;
5937 b = lt - u2;
5938 if (a == b)
5939 return u1;
5940 }
5941 else {
5942 b = t1 - u1;
5943 assert(a != b);
5944 }
5945 u2 = t - b;
5946 t2 = local(u2);
5947 if (t2 == -1)
5948 return -1;
5949 if (t2 == t)
5950 return u2;
5951 if (t1 == t)
5952 return u1;
5953 /* We have found both offsets a and b, but neither t - a nor t - b is
5954 * a solution. This means t is in the gap. */
5955 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5956}
5957
5958/* date(1970,1,1).toordinal() == 719163 */
5959#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5960
Tim Peters2a799bf2002-12-16 20:18:38 +00005961static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305962datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolskya4415142012-06-08 12:33:09 -04005963{
5964 PyObject *result;
5965
5966 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5967 PyObject *delta;
5968 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5969 if (delta == NULL)
5970 return NULL;
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305971 result = delta_total_seconds(delta, NULL);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005972 Py_DECREF(delta);
5973 }
5974 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005975 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005976 seconds = local_to_seconds(GET_YEAR(self),
5977 GET_MONTH(self),
5978 GET_DAY(self),
5979 DATE_GET_HOUR(self),
5980 DATE_GET_MINUTE(self),
5981 DATE_GET_SECOND(self),
5982 DATE_GET_FOLD(self));
5983 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005984 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005985 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5986 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005987 }
5988 return result;
5989}
5990
5991static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305992datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005993{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005994 return new_date(GET_YEAR(self),
5995 GET_MONTH(self),
5996 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005997}
5998
5999static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306000datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006002 return new_time(DATE_GET_HOUR(self),
6003 DATE_GET_MINUTE(self),
6004 DATE_GET_SECOND(self),
6005 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006006 Py_None,
6007 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006008}
6009
6010static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306011datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006012{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006013 return new_time(DATE_GET_HOUR(self),
6014 DATE_GET_MINUTE(self),
6015 DATE_GET_SECOND(self),
6016 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006017 GET_DT_TZINFO(self),
6018 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006019}
6020
6021static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306022datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006023{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006024 int y, m, d, hh, mm, ss;
6025 PyObject *tzinfo;
6026 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006027
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006028 tzinfo = GET_DT_TZINFO(self);
6029 if (tzinfo == Py_None) {
6030 utcself = self;
6031 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006032 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006033 else {
6034 PyObject *offset;
6035 offset = call_utcoffset(tzinfo, (PyObject *)self);
6036 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006037 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006038 if (offset == Py_None) {
6039 Py_DECREF(offset);
6040 utcself = self;
6041 Py_INCREF(utcself);
6042 }
6043 else {
6044 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6045 (PyDateTime_Delta *)offset, -1);
6046 Py_DECREF(offset);
6047 if (utcself == NULL)
6048 return NULL;
6049 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006050 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006051 y = GET_YEAR(utcself);
6052 m = GET_MONTH(utcself);
6053 d = GET_DAY(utcself);
6054 hh = DATE_GET_HOUR(utcself);
6055 mm = DATE_GET_MINUTE(utcself);
6056 ss = DATE_GET_SECOND(utcself);
6057
6058 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006059 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006060}
6061
Tim Peters371935f2003-02-01 01:52:50 +00006062/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006063
Tim Petersa9bc1682003-01-11 03:39:11 +00006064/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006065 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6066 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006067 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006068 */
6069static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006070datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006072 PyObject *basestate;
6073 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006075 basestate = PyBytes_FromStringAndSize((char *)self->data,
6076 _PyDateTime_DATETIME_DATASIZE);
6077 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006078 if (proto > 3 && DATE_GET_FOLD(self))
6079 /* Set the first bit of the third byte */
6080 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006081 if (! HASTZINFO(self) || self->tzinfo == Py_None)
6082 result = PyTuple_Pack(1, basestate);
6083 else
6084 result = PyTuple_Pack(2, basestate, self->tzinfo);
6085 Py_DECREF(basestate);
6086 }
6087 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00006088}
6089
6090static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006091datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006092{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006093 int proto;
6094 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006095 return NULL;
6096
6097 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006098}
6099
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006100static PyObject *
6101datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6102{
6103 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6104}
6105
Tim Petersa9bc1682003-01-11 03:39:11 +00006106static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006108 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006109
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006110 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006112 {"utcnow", (PyCFunction)datetime_utcnow,
6113 METH_NOARGS | METH_CLASS,
6114 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006115
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006116 {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006117 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6118 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006120 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6121 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006122 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006124 {"strptime", (PyCFunction)datetime_strptime,
6125 METH_VARARGS | METH_CLASS,
6126 PyDoc_STR("string, format -> new datetime parsed from a string "
6127 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006128
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006129 {"combine", (PyCFunction)(void(*)(void))datetime_combine,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006130 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6131 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006132
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006133 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6134 METH_O | METH_CLASS,
6135 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006137 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006139 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6140 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006142 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6143 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006145 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6146 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006148 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6149 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006151 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6152 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006153
Alexander Belopolskya4415142012-06-08 12:33:09 -04006154 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6155 PyDoc_STR("Return POSIX timestamp as float.")},
6156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006157 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6158 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006159
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006160 {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006161 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006162 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006163 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006164 "defaults to 'T'.\n"
6165 "timespec specifies what components of the time to include"
6166 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6167 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006169 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6170 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006172 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6173 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006175 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6176 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006177
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006178 {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006179 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006180
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006181 {"astimezone", (PyCFunction)(void(*)(void))datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006182 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006183
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006184 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006185 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006186
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006187 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6188 PyDoc_STR("__reduce__() -> (cls, state)")},
6189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006190 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006191};
6192
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006193static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006194PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6195\n\
6196The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006197instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006198
Tim Petersa9bc1682003-01-11 03:39:11 +00006199static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006200 datetime_add, /* nb_add */
6201 datetime_subtract, /* nb_subtract */
6202 0, /* nb_multiply */
6203 0, /* nb_remainder */
6204 0, /* nb_divmod */
6205 0, /* nb_power */
6206 0, /* nb_negative */
6207 0, /* nb_positive */
6208 0, /* nb_absolute */
6209 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006210};
6211
Neal Norwitz227b5332006-03-22 09:28:35 +00006212static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006213 PyVarObject_HEAD_INIT(NULL, 0)
6214 "datetime.datetime", /* tp_name */
6215 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6216 0, /* tp_itemsize */
6217 (destructor)datetime_dealloc, /* tp_dealloc */
6218 0, /* tp_print */
6219 0, /* tp_getattr */
6220 0, /* tp_setattr */
6221 0, /* tp_reserved */
6222 (reprfunc)datetime_repr, /* tp_repr */
6223 &datetime_as_number, /* tp_as_number */
6224 0, /* tp_as_sequence */
6225 0, /* tp_as_mapping */
6226 (hashfunc)datetime_hash, /* tp_hash */
6227 0, /* tp_call */
6228 (reprfunc)datetime_str, /* tp_str */
6229 PyObject_GenericGetAttr, /* tp_getattro */
6230 0, /* tp_setattro */
6231 0, /* tp_as_buffer */
6232 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6233 datetime_doc, /* tp_doc */
6234 0, /* tp_traverse */
6235 0, /* tp_clear */
6236 datetime_richcompare, /* tp_richcompare */
6237 0, /* tp_weaklistoffset */
6238 0, /* tp_iter */
6239 0, /* tp_iternext */
6240 datetime_methods, /* tp_methods */
6241 0, /* tp_members */
6242 datetime_getset, /* tp_getset */
6243 &PyDateTime_DateType, /* tp_base */
6244 0, /* tp_dict */
6245 0, /* tp_descr_get */
6246 0, /* tp_descr_set */
6247 0, /* tp_dictoffset */
6248 0, /* tp_init */
6249 datetime_alloc, /* tp_alloc */
6250 datetime_new, /* tp_new */
6251 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006252};
6253
6254/* ---------------------------------------------------------------------------
6255 * Module methods and initialization.
6256 */
6257
6258static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006259 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006260};
6261
Tim Peters9ddf40b2004-06-20 22:41:32 +00006262/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6263 * datetime.h.
6264 */
6265static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006266 &PyDateTime_DateType,
6267 &PyDateTime_DateTimeType,
6268 &PyDateTime_TimeType,
6269 &PyDateTime_DeltaType,
6270 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006271 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006272 new_date_ex,
6273 new_datetime_ex,
6274 new_time_ex,
6275 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006276 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006277 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006278 date_fromtimestamp,
6279 new_datetime_ex2,
6280 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006281};
6282
6283
Martin v. Löwis1a214512008-06-11 05:26:20 +00006284
6285static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006286 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006287 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006288 "Fast implementation of the datetime type.",
6289 -1,
6290 module_methods,
6291 NULL,
6292 NULL,
6293 NULL,
6294 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006295};
6296
Tim Peters2a799bf2002-12-16 20:18:38 +00006297PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006298PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006300 PyObject *m; /* a module object */
6301 PyObject *d; /* its dict */
6302 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006303 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006305 m = PyModule_Create(&datetimemodule);
6306 if (m == NULL)
6307 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006309 if (PyType_Ready(&PyDateTime_DateType) < 0)
6310 return NULL;
6311 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6312 return NULL;
6313 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6314 return NULL;
6315 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6316 return NULL;
6317 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6318 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006319 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6320 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006322 /* timedelta values */
6323 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006325 x = new_delta(0, 0, 1, 0);
6326 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6327 return NULL;
6328 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006330 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6331 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6332 return NULL;
6333 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006335 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6336 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6337 return NULL;
6338 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006340 /* date values */
6341 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006343 x = new_date(1, 1, 1);
6344 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6345 return NULL;
6346 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006348 x = new_date(MAXYEAR, 12, 31);
6349 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6350 return NULL;
6351 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006353 x = new_delta(1, 0, 0, 0);
6354 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6355 return NULL;
6356 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006358 /* time values */
6359 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006360
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006361 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006362 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6363 return NULL;
6364 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006365
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006366 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006367 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6368 return NULL;
6369 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006371 x = new_delta(0, 0, 1, 0);
6372 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6373 return NULL;
6374 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006376 /* datetime values */
6377 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006378
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006379 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006380 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6381 return NULL;
6382 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006383
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006384 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006385 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6386 return NULL;
6387 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006389 x = new_delta(0, 0, 1, 0);
6390 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6391 return NULL;
6392 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006393
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006394 /* timezone values */
6395 d = PyDateTime_TimeZoneType.tp_dict;
6396
6397 delta = new_delta(0, 0, 0, 0);
6398 if (delta == NULL)
6399 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006400 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006401 Py_DECREF(delta);
6402 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6403 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006404 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006405 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006406
6407 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6408 if (delta == NULL)
6409 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006410 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006411 Py_DECREF(delta);
6412 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6413 return NULL;
6414 Py_DECREF(x);
6415
6416 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6417 if (delta == NULL)
6418 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006419 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006420 Py_DECREF(delta);
6421 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6422 return NULL;
6423 Py_DECREF(x);
6424
Alexander Belopolskya4415142012-06-08 12:33:09 -04006425 /* Epoch */
6426 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006427 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006428 if (PyDateTime_Epoch == NULL)
6429 return NULL;
6430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006431 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006432 PyModule_AddIntMacro(m, MINYEAR);
6433 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006435 Py_INCREF(&PyDateTime_DateType);
6436 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006438 Py_INCREF(&PyDateTime_DateTimeType);
6439 PyModule_AddObject(m, "datetime",
6440 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006442 Py_INCREF(&PyDateTime_TimeType);
6443 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006445 Py_INCREF(&PyDateTime_DeltaType);
6446 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006448 Py_INCREF(&PyDateTime_TZInfoType);
6449 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006450
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006451 Py_INCREF(&PyDateTime_TimeZoneType);
6452 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006454 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6455 if (x == NULL)
6456 return NULL;
6457 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006459 /* A 4-year cycle has an extra leap day over what we'd get from
6460 * pasting together 4 single years.
6461 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006462 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006463 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006465 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6466 * get from pasting together 4 100-year cycles.
6467 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006468 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006469 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006471 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6472 * pasting together 25 4-year cycles.
6473 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006474 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006475 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006477 us_per_ms = PyLong_FromLong(1000);
6478 us_per_second = PyLong_FromLong(1000000);
6479 us_per_minute = PyLong_FromLong(60000000);
6480 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006481 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006482 us_per_minute == NULL || seconds_per_day == NULL)
6483 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006485 /* The rest are too big for 32-bit ints, but even
6486 * us_per_week fits in 40 bits, so doubles should be exact.
6487 */
6488 us_per_hour = PyLong_FromDouble(3600000000.0);
6489 us_per_day = PyLong_FromDouble(86400000000.0);
6490 us_per_week = PyLong_FromDouble(604800000000.0);
6491 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6492 return NULL;
6493 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006494}
Tim Petersf3615152003-01-01 21:51:37 +00006495
6496/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006497Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006498 x.n = x stripped of its timezone -- its naive time.
6499 x.o = x.utcoffset(), 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.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006502 return None
Tim Petersf3615152003-01-01 21:51:37 +00006503 x.s = x's standard offset, x.o - x.d
6504
6505Now some derived rules, where k is a duration (timedelta).
6506
65071. x.o = x.s + x.d
6508 This follows from the definition of x.s.
6509
Tim Petersc5dc4da2003-01-02 17:55:03 +000065102. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006511 This is actually a requirement, an assumption we need to make about
6512 sane tzinfo classes.
6513
65143. The naive UTC time corresponding to x is x.n - x.o.
6515 This is again a requirement for a sane tzinfo class.
6516
65174. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006518 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006519
Tim Petersc5dc4da2003-01-02 17:55:03 +000065205. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006521 Again follows from how arithmetic is defined.
6522
Tim Peters8bb5ad22003-01-24 02:44:45 +00006523Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006524(meaning that the various tzinfo methods exist, and don't blow up or return
6525None when called).
6526
Tim Petersa9bc1682003-01-11 03:39:11 +00006527The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006528x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006529
6530By #3, we want
6531
Tim Peters8bb5ad22003-01-24 02:44:45 +00006532 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006533
6534The algorithm starts by attaching tz to x.n, and calling that y. So
6535x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6536becomes true; in effect, we want to solve [2] for k:
6537
Tim Peters8bb5ad22003-01-24 02:44:45 +00006538 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006539
6540By #1, this is the same as
6541
Tim Peters8bb5ad22003-01-24 02:44:45 +00006542 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006543
6544By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6545Substituting that into [3],
6546
Tim Peters8bb5ad22003-01-24 02:44:45 +00006547 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6548 k - (y+k).s - (y+k).d = 0; rearranging,
6549 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6550 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006551
Tim Peters8bb5ad22003-01-24 02:44:45 +00006552On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6553approximate k by ignoring the (y+k).d term at first. Note that k can't be
6554very large, since all offset-returning methods return a duration of magnitude
6555less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6556be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006557
6558In any case, the new value is
6559
Tim Peters8bb5ad22003-01-24 02:44:45 +00006560 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006561
Tim Peters8bb5ad22003-01-24 02:44:45 +00006562It's helpful to step back at look at [4] from a higher level: it's simply
6563mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006564
6565At this point, if
6566
Tim Peters8bb5ad22003-01-24 02:44:45 +00006567 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006568
6569we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006570at the start of daylight time. Picture US Eastern for concreteness. The wall
6571time 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 +00006572sense then. The docs ask that an Eastern tzinfo class consider such a time to
6573be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6574on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006575the only spelling that makes sense on the local wall clock.
6576
Tim Petersc5dc4da2003-01-02 17:55:03 +00006577In fact, if [5] holds at this point, we do have the standard-time spelling,
6578but that takes a bit of proof. We first prove a stronger result. What's the
6579difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006580
Tim Peters8bb5ad22003-01-24 02:44:45 +00006581 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006582
Tim Petersc5dc4da2003-01-02 17:55:03 +00006583Now
6584 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006585 (y + y.s).n = by #5
6586 y.n + y.s = since y.n = x.n
6587 x.n + y.s = since z and y are have the same tzinfo member,
6588 y.s = z.s by #2
6589 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006590
Tim Petersc5dc4da2003-01-02 17:55:03 +00006591Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006592
Tim Petersc5dc4da2003-01-02 17:55:03 +00006593 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006594 x.n - ((x.n + z.s) - z.o) = expanding
6595 x.n - x.n - z.s + z.o = cancelling
6596 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006597 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006598
Tim Petersc5dc4da2003-01-02 17:55:03 +00006599So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006600
Tim Petersc5dc4da2003-01-02 17:55:03 +00006601If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006602spelling we wanted in the endcase described above. We're done. Contrarily,
6603if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006604
Tim Petersc5dc4da2003-01-02 17:55:03 +00006605If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6606add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006607local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006608
Tim Petersc5dc4da2003-01-02 17:55:03 +00006609Let
Tim Petersf3615152003-01-01 21:51:37 +00006610
Tim Peters4fede1a2003-01-04 00:26:59 +00006611 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006612
Tim Peters4fede1a2003-01-04 00:26:59 +00006613and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006614
Tim Peters8bb5ad22003-01-24 02:44:45 +00006615 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006616
Tim Peters8bb5ad22003-01-24 02:44:45 +00006617If so, we're done. If not, the tzinfo class is insane, according to the
6618assumptions we've made. This also requires a bit of proof. As before, let's
6619compute the difference between the LHS and RHS of [8] (and skipping some of
6620the justifications for the kinds of substitutions we've done several times
6621already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006622
Tim Peters8bb5ad22003-01-24 02:44:45 +00006623 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006624 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6625 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6626 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6627 - z.n + z.n - z.o + z'.o = cancel z.n
6628 - z.o + z'.o = #1 twice
6629 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6630 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006631
6632So 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 +00006633we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6634return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006635
Tim Peters8bb5ad22003-01-24 02:44:45 +00006636How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6637a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6638would have to change the result dst() returns: we start in DST, and moving
6639a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006640
Tim Peters8bb5ad22003-01-24 02:44:45 +00006641There isn't a sane case where this can happen. The closest it gets is at
6642the end of DST, where there's an hour in UTC with no spelling in a hybrid
6643tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6644that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6645UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6646time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6647clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6648standard time. Since that's what the local clock *does*, we want to map both
6649UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006650in local time, but so it goes -- it's the way the local clock works.
6651
Tim Peters8bb5ad22003-01-24 02:44:45 +00006652When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6653so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6654z' = 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 +00006655(correctly) concludes that z' is not UTC-equivalent to x.
6656
6657Because we know z.d said z was in daylight time (else [5] would have held and
6658we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006659and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006660return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6661but the reasoning doesn't depend on the example -- it depends on there being
6662two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006663z' must be in standard time, and is the spelling we want in this case.
6664
6665Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6666concerned (because it takes z' as being in standard time rather than the
6667daylight time we intend here), but returning it gives the real-life "local
6668clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6669tz.
6670
6671When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6672the 1:MM standard time spelling we want.
6673
6674So how can this break? One of the assumptions must be violated. Two
6675possibilities:
6676
66771) [2] effectively says that y.s is invariant across all y belong to a given
6678 time zone. This isn't true if, for political reasons or continental drift,
6679 a region decides to change its base offset from UTC.
6680
66812) There may be versions of "double daylight" time where the tail end of
6682 the analysis gives up a step too early. I haven't thought about that
6683 enough to say.
6684
6685In any case, it's clear that the default fromutc() is strong enough to handle
6686"almost all" time zones: so long as the standard offset is invariant, it
6687doesn't matter if daylight time transition points change from year to year, or
6688if daylight time is skipped in some years; it doesn't matter how large or
6689small dst() may get within its bounds; and it doesn't even matter if some
6690perverse time zone returns a negative dst()). So a breaking case must be
6691pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006692--------------------------------------------------------------------------- */