blob: acdde83dc845a5d36a22675175e936313224741a [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"
Victor Stinner4a21e572020-04-15 02:35:41 +020012#include "structmember.h" // PyMemberDef
Tim Peters2a799bf2002-12-16 20:18:38 +000013
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)
Dong-hee Na1b55b652020-02-17 19:09:15 +090021#define PyDate_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateType)
Paul Ganssle0d126722018-11-13 03:02:25 -050022
23#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090024#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateTimeType)
Paul Ganssle0d126722018-11-13 03:02:25 -050025
26#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090027#define PyTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TimeType)
Paul Ganssle0d126722018-11-13 03:02:25 -050028
29#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090030#define PyDelta_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DeltaType)
Paul Ganssle0d126722018-11-13 03:02:25 -050031
32#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090033#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TZInfoType)
Paul Ganssle0d126722018-11-13 03:02:25 -050034
Pablo Galindo4be11c02019-08-22 20:24:25 +010035#define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType)
Tim Peters2a799bf2002-12-16 20:18:38 +000036
Larry Hastings61272b72014-01-07 12:41:53 -080037/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080038module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080039class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +020040class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType"
Paul Ganssle1b97b9b2020-05-16 10:02:59 -040041class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCalendarDateType"
Larry Hastings61272b72014-01-07 12:41:53 -080042[clinic start generated code]*/
Paul Ganssle1b97b9b2020-05-16 10:02:59 -040043/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81bec0fa19837f63]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080044
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030045#include "clinic/_datetimemodule.c.h"
46
Tim Peters2a799bf2002-12-16 20:18:38 +000047/* We require that C int be at least 32 bits, and use int virtually
48 * everywhere. In just a few cases we use a temp long, where a Python
49 * API returns a C long. In such cases, we have to ensure that the
50 * final result fits in a C int (this can be an issue on 64-bit boxes).
51 */
52#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000053# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000054#endif
55
56#define MINYEAR 1
57#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000058#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000059
60/* Nine decimal digits is easy to communicate, and leaves enough room
61 * so that two delta days can be added w/o fear of overflowing a signed
62 * 32-bit int, and with plenty of room left over to absorb any possible
63 * carries from adding seconds.
64 */
65#define MAX_DELTA_DAYS 999999999
66
67/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068#define GET_YEAR PyDateTime_GET_YEAR
69#define GET_MONTH PyDateTime_GET_MONTH
70#define GET_DAY PyDateTime_GET_DAY
71#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
72#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
73#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
74#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040075#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000076
77/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
79 ((o)->data[1] = ((v) & 0x00ff)))
80#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
81#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000082
83/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
85#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
86#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
87#define DATE_SET_MICROSECOND(o, v) \
88 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
89 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
90 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040091#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000092
93/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
95#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
96#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
97#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040098#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
100#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
101#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
102#define TIME_SET_MICROSECOND(o, v) \
103 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
104 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
105 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400106#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000107
108/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
110#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
111#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113#define SET_TD_DAYS(o, v) ((o)->days = (v))
114#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000115#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
116
Tim Petersa032d2e2003-01-11 00:15:54 +0000117/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
118 * p->hastzinfo.
119 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000120#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
121#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
122 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
123#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
124 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000125/* M is a char or int claiming to be a valid month. The macro is equivalent
126 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000128 */
129#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
130
Tim Peters2a799bf2002-12-16 20:18:38 +0000131/* Forward declarations. */
132static PyTypeObject PyDateTime_DateType;
133static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000134static PyTypeObject PyDateTime_DeltaType;
Paul Ganssle1b97b9b2020-05-16 10:02:59 -0400135static PyTypeObject PyDateTime_IsoCalendarDateType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000136static PyTypeObject PyDateTime_TimeType;
137static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000138static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000139
Victor Stinnerb67f0962017-02-10 10:34:02 +0100140static int check_tzinfo_subclass(PyObject *p);
141
Martin v. Löwise75fc142013-11-07 18:46:53 +0100142_Py_IDENTIFIER(as_integer_ratio);
143_Py_IDENTIFIER(fromutc);
144_Py_IDENTIFIER(isoformat);
145_Py_IDENTIFIER(strftime);
146
Tim Peters2a799bf2002-12-16 20:18:38 +0000147/* ---------------------------------------------------------------------------
148 * Math utilities.
149 */
150
151/* k = i+j overflows iff k differs in sign from both inputs,
152 * iff k^i has sign bit set and k^j has sign bit set,
153 * iff (k^i)&(k^j) has sign bit set.
154 */
155#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000157
158/* Compute Python divmod(x, y), returning the quotient and storing the
159 * remainder into *r. The quotient is the floor of x/y, and that's
160 * the real point of this. C will probably truncate instead (C99
161 * requires truncation; C89 left it implementation-defined).
162 * Simplification: we *require* that y > 0 here. That's appropriate
163 * for all the uses made of it. This simplifies the code and makes
164 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
165 * overflow case).
166 */
167static int
168divmod(int x, int y, int *r)
169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 assert(y > 0);
173 quo = x / y;
174 *r = x - quo * y;
175 if (*r < 0) {
176 --quo;
177 *r += y;
178 }
179 assert(0 <= *r && *r < y);
180 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000181}
182
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000183/* Nearest integer to m / n for integers m and n. Half-integer results
184 * are rounded to even.
185 */
186static PyObject *
187divide_nearest(PyObject *m, PyObject *n)
188{
189 PyObject *result;
190 PyObject *temp;
191
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000192 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000193 if (temp == NULL)
194 return NULL;
195 result = PyTuple_GET_ITEM(temp, 0);
196 Py_INCREF(result);
197 Py_DECREF(temp);
198
199 return result;
200}
201
Tim Peters2a799bf2002-12-16 20:18:38 +0000202/* ---------------------------------------------------------------------------
203 * General calendrical helper functions
204 */
205
206/* For each month ordinal in 1..12, the number of days in that month,
207 * and the number of days before that month in the same year. These
208 * are correct for non-leap years only.
209 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200210static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 0, /* unused; this vector uses 1-based indexing */
212 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000213};
214
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200215static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 0, /* unused; this vector uses 1-based indexing */
217 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000218};
219
220/* year -> 1 if leap year, else 0. */
221static int
222is_leap(int year)
223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 /* Cast year to unsigned. The result is the same either way, but
225 * C can generate faster code for unsigned mod than for signed
226 * mod (especially for % 4 -- a good compiler should just grab
227 * the last 2 bits when the LHS is unsigned).
228 */
229 const unsigned int ayear = (unsigned int)year;
230 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000231}
232
233/* year, month -> number of days in that month in that year */
234static int
235days_in_month(int year, int month)
236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 assert(month >= 1);
238 assert(month <= 12);
239 if (month == 2 && is_leap(year))
240 return 29;
241 else
242 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000243}
244
Martin Panter46f50722016-05-26 05:35:26 +0000245/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000246static int
247days_before_month(int year, int month)
248{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 assert(month >= 1);
252 assert(month <= 12);
253 days = _days_before_month[month];
254 if (month > 2 && is_leap(year))
255 ++days;
256 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000257}
258
259/* year -> number of days before January 1st of year. Remember that we
260 * start with year 1, so days_before_year(1) == 0.
261 */
262static int
263days_before_year(int year)
264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 int y = year - 1;
266 /* This is incorrect if year <= 0; we really want the floor
267 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000268 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000270 assert (year >= 1);
271 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000272}
273
274/* Number of days in 4, 100, and 400 year cycles. That these have
275 * the correct values is asserted in the module init function.
276 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277#define DI4Y 1461 /* days_before_year(5); days in 4 years */
278#define DI100Y 36524 /* days_before_year(101); days in 100 years */
279#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000280
281/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
282static void
283ord_to_ymd(int ordinal, int *year, int *month, int *day)
284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
288 * leap years repeats exactly every 400 years. The basic strategy is
289 * to find the closest 400-year boundary at or before ordinal, then
290 * work with the offset from that boundary to ordinal. Life is much
291 * clearer if we subtract 1 from ordinal first -- then the values
292 * of ordinal at 400-year boundaries are exactly those divisible
293 * by DI400Y:
294 *
295 * D M Y n n-1
296 * -- --- ---- ---------- ----------------
297 * 31 Dec -400 -DI400Y -DI400Y -1
298 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
299 * ...
300 * 30 Dec 000 -1 -2
301 * 31 Dec 000 0 -1
302 * 1 Jan 001 1 0 400-year boundary
303 * 2 Jan 001 2 1
304 * 3 Jan 001 3 2
305 * ...
306 * 31 Dec 400 DI400Y DI400Y -1
307 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
308 */
309 assert(ordinal >= 1);
310 --ordinal;
311 n400 = ordinal / DI400Y;
312 n = ordinal % DI400Y;
313 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 /* Now n is the (non-negative) offset, in days, from January 1 of
316 * year, to the desired date. Now compute how many 100-year cycles
317 * precede n.
318 * Note that it's possible for n100 to equal 4! In that case 4 full
319 * 100-year cycles precede the desired day, which implies the
320 * desired day is December 31 at the end of a 400-year cycle.
321 */
322 n100 = n / DI100Y;
323 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 /* Now compute how many 4-year cycles precede it. */
326 n4 = n / DI4Y;
327 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 /* And now how many single years. Again n1 can be 4, and again
330 * meaning that the desired day is December 31 at the end of the
331 * 4-year cycle.
332 */
333 n1 = n / 365;
334 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 *year += n100 * 100 + n4 * 4 + n1;
337 if (n1 == 4 || n100 == 4) {
338 assert(n == 0);
339 *year -= 1;
340 *month = 12;
341 *day = 31;
342 return;
343 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 /* Now the year is correct, and n is the offset from January 1. We
346 * find the month via an estimate that's either exact or one too
347 * large.
348 */
349 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
350 assert(leapyear == is_leap(*year));
351 *month = (n + 50) >> 5;
352 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
353 if (preceding > n) {
354 /* estimate is too large */
355 *month -= 1;
356 preceding -= days_in_month(*year, *month);
357 }
358 n -= preceding;
359 assert(0 <= n);
360 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000363}
364
365/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
366static int
367ymd_to_ord(int year, int month, int day)
368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000370}
371
372/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
373static int
374weekday(int year, int month, int day)
375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000377}
378
379/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
380 * first calendar week containing a Thursday.
381 */
382static int
383iso_week1_monday(int year)
384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
386 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
387 int first_weekday = (first_day + 6) % 7;
388 /* ordinal of closest Monday at or before 1/1 */
389 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
392 week1_monday += 7;
393 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000394}
395
396/* ---------------------------------------------------------------------------
397 * Range checkers.
398 */
399
400/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
401 * If not, raise OverflowError and return -1.
402 */
403static int
404check_delta_day_range(int days)
405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
407 return 0;
408 PyErr_Format(PyExc_OverflowError,
409 "days=%d; must have magnitude <= %d",
410 days, MAX_DELTA_DAYS);
411 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000412}
413
414/* Check that date arguments are in range. Return 0 if they are. If they
415 * aren't, raise ValueError and return -1.
416 */
417static int
418check_date_args(int year, int month, int day)
419{
420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 if (year < MINYEAR || year > MAXYEAR) {
Victor Stinnerb67f0962017-02-10 10:34:02 +0100422 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 return -1;
424 }
425 if (month < 1 || month > 12) {
426 PyErr_SetString(PyExc_ValueError,
427 "month must be in 1..12");
428 return -1;
429 }
430 if (day < 1 || day > days_in_month(year, month)) {
431 PyErr_SetString(PyExc_ValueError,
432 "day is out of range for month");
433 return -1;
434 }
435 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000436}
437
438/* Check that time arguments are in range. Return 0 if they are. If they
439 * aren't, raise ValueError and return -1.
440 */
441static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400442check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000443{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 if (h < 0 || h > 23) {
445 PyErr_SetString(PyExc_ValueError,
446 "hour must be in 0..23");
447 return -1;
448 }
449 if (m < 0 || m > 59) {
450 PyErr_SetString(PyExc_ValueError,
451 "minute must be in 0..59");
452 return -1;
453 }
454 if (s < 0 || s > 59) {
455 PyErr_SetString(PyExc_ValueError,
456 "second must be in 0..59");
457 return -1;
458 }
459 if (us < 0 || us > 999999) {
460 PyErr_SetString(PyExc_ValueError,
461 "microsecond must be in 0..999999");
462 return -1;
463 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400464 if (fold != 0 && fold != 1) {
465 PyErr_SetString(PyExc_ValueError,
466 "fold must be either 0 or 1");
467 return -1;
468 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000470}
471
472/* ---------------------------------------------------------------------------
473 * Normalization utilities.
474 */
475
476/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
477 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
478 * at least factor, enough of *lo is converted into "hi" units so that
479 * 0 <= *lo < factor. The input values must be such that int overflow
480 * is impossible.
481 */
482static void
483normalize_pair(int *hi, int *lo, int factor)
484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 assert(factor > 0);
486 assert(lo != hi);
487 if (*lo < 0 || *lo >= factor) {
488 const int num_hi = divmod(*lo, factor, lo);
489 const int new_hi = *hi + num_hi;
490 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
491 *hi = new_hi;
492 }
493 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000494}
495
496/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 * 0 <= *s < 24*3600
498 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000499 * The input values must be such that the internals don't overflow.
500 * The way this routine is used, we don't get close.
501 */
502static void
503normalize_d_s_us(int *d, int *s, int *us)
504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 if (*us < 0 || *us >= 1000000) {
506 normalize_pair(s, us, 1000000);
507 /* |s| can't be bigger than about
508 * |original s| + |original us|/1000000 now.
509 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 }
512 if (*s < 0 || *s >= 24*3600) {
513 normalize_pair(d, s, 24*3600);
514 /* |d| can't be bigger than about
515 * |original d| +
516 * (|original s| + |original us|/1000000) / (24*3600) now.
517 */
518 }
519 assert(0 <= *s && *s < 24*3600);
520 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000521}
522
523/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 * 1 <= *m <= 12
525 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000526 * The input values must be such that the internals don't overflow.
527 * The way this routine is used, we don't get close.
528 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000529static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000530normalize_y_m_d(int *y, int *m, int *d)
531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000533
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000534 /* In actual use, m is always the month component extracted from a
535 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 /* Now only day can be out of bounds (year may also be out of bounds
541 * for a datetime object, but we don't care about that here).
542 * If day is out of bounds, what to do is arguable, but at least the
543 * method here is principled and explainable.
544 */
545 dim = days_in_month(*y, *m);
546 if (*d < 1 || *d > dim) {
547 /* Move day-1 days from the first of the month. First try to
548 * get off cheap if we're only one day out of range
549 * (adjustments for timezone alone can't be worse than that).
550 */
551 if (*d == 0) {
552 --*m;
553 if (*m > 0)
554 *d = days_in_month(*y, *m);
555 else {
556 --*y;
557 *m = 12;
558 *d = 31;
559 }
560 }
561 else if (*d == dim + 1) {
562 /* move forward a day */
563 ++*m;
564 *d = 1;
565 if (*m > 12) {
566 *m = 1;
567 ++*y;
568 }
569 }
570 else {
571 int ordinal = ymd_to_ord(*y, *m, 1) +
572 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000573 if (ordinal < 1 || ordinal > MAXORDINAL) {
574 goto error;
575 } else {
576 ord_to_ymd(ordinal, y, m, d);
577 return 0;
578 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 }
580 }
581 assert(*m > 0);
582 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000583 if (MINYEAR <= *y && *y <= MAXYEAR)
584 return 0;
585 error:
586 PyErr_SetString(PyExc_OverflowError,
587 "date value out of range");
588 return -1;
589
Tim Peters2a799bf2002-12-16 20:18:38 +0000590}
591
592/* Fiddle out-of-bounds months and days so that the result makes some kind
593 * of sense. The parameters are both inputs and outputs. Returns < 0 on
594 * failure, where failure means the adjusted year is out of bounds.
595 */
596static int
597normalize_date(int *year, int *month, int *day)
598{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000599 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000600}
601
602/* Force all the datetime fields into range. The parameters are both
603 * inputs and outputs. Returns < 0 on error.
604 */
605static int
606normalize_datetime(int *year, int *month, int *day,
607 int *hour, int *minute, int *second,
608 int *microsecond)
609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 normalize_pair(second, microsecond, 1000000);
611 normalize_pair(minute, second, 60);
612 normalize_pair(hour, minute, 60);
613 normalize_pair(day, hour, 24);
614 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000615}
616
617/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000618 * Basic object allocation: tp_alloc implementations. These allocate
619 * Python objects of the right size and type, and do the Python object-
620 * initialization bit. If there's not enough memory, they return NULL after
621 * setting MemoryError. All data members remain uninitialized trash.
622 *
623 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000624 * member is needed. This is ugly, imprecise, and possibly insecure.
625 * tp_basicsize for the time and datetime types is set to the size of the
626 * struct that has room for the tzinfo member, so subclasses in Python will
627 * allocate enough space for a tzinfo member whether or not one is actually
628 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
629 * part is that PyType_GenericAlloc() (which subclasses in Python end up
630 * using) just happens today to effectively ignore the nitems argument
631 * when tp_itemsize is 0, which it is for these type objects. If that
632 * changes, perhaps the callers of tp_alloc slots in this file should
633 * be changed to force a 0 nitems argument unless the type being allocated
634 * is a base type implemented in this file (so that tp_alloc is time_alloc
635 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000636 */
637
638static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000639time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 self = (PyObject *)
644 PyObject_MALLOC(aware ?
645 sizeof(PyDateTime_Time) :
646 sizeof(_PyDateTime_BaseTime));
647 if (self == NULL)
648 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100649 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000650 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000651}
652
653static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000654datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 self = (PyObject *)
659 PyObject_MALLOC(aware ?
660 sizeof(PyDateTime_DateTime) :
661 sizeof(_PyDateTime_BaseDateTime));
662 if (self == NULL)
663 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100664 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000666}
667
668/* ---------------------------------------------------------------------------
669 * Helpers for setting object fields. These work on pointers to the
670 * appropriate base class.
671 */
672
673/* For date and datetime. */
674static void
675set_date_fields(PyDateTime_Date *self, int y, int m, int d)
676{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 self->hashcode = -1;
678 SET_YEAR(self, y);
679 SET_MONTH(self, m);
680 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000681}
682
683/* ---------------------------------------------------------------------------
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500684 * String parsing utilities and helper functions
685 */
686
Paul Ganssle3df85402018-10-22 12:32:52 -0400687static const char *
688parse_digits(const char *ptr, int *var, size_t num_digits)
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500689{
690 for (size_t i = 0; i < num_digits; ++i) {
691 unsigned int tmp = (unsigned int)(*(ptr++) - '0');
692 if (tmp > 9) {
693 return NULL;
694 }
695 *var *= 10;
696 *var += (signed int)tmp;
697 }
698
699 return ptr;
700}
701
Paul Ganssle3df85402018-10-22 12:32:52 -0400702static int
703parse_isoformat_date(const char *dtstr, int *year, int *month, int *day)
704{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500705 /* Parse the date components of the result of date.isoformat()
Paul Ganssle3df85402018-10-22 12:32:52 -0400706 *
707 * Return codes:
708 * 0: Success
709 * -1: Failed to parse date component
710 * -2: Failed to parse dateseparator
711 */
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500712 const char *p = dtstr;
713 p = parse_digits(p, year, 4);
714 if (NULL == p) {
715 return -1;
716 }
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100717
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500718 if (*(p++) != '-') {
719 return -2;
720 }
721
722 p = parse_digits(p, month, 2);
723 if (NULL == p) {
724 return -1;
725 }
726
727 if (*(p++) != '-') {
728 return -2;
729 }
730
731 p = parse_digits(p, day, 2);
732 if (p == NULL) {
733 return -1;
734 }
735
736 return 0;
737}
738
739static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400740parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
741 int *minute, int *second, int *microsecond)
742{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500743 const char *p = tstr;
744 const char *p_end = tstr_end;
745 int *vals[3] = {hour, minute, second};
746
747 // Parse [HH[:MM[:SS]]]
748 for (size_t i = 0; i < 3; ++i) {
749 p = parse_digits(p, vals[i], 2);
750 if (NULL == p) {
751 return -3;
752 }
753
754 char c = *(p++);
755 if (p >= p_end) {
756 return c != '\0';
Paul Ganssle3df85402018-10-22 12:32:52 -0400757 }
758 else if (c == ':') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500759 continue;
Paul Ganssle3df85402018-10-22 12:32:52 -0400760 }
761 else if (c == '.') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500762 break;
Paul Ganssle3df85402018-10-22 12:32:52 -0400763 }
764 else {
765 return -4; // Malformed time separator
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500766 }
767 }
768
769 // Parse .fff[fff]
770 size_t len_remains = p_end - p;
771 if (!(len_remains == 6 || len_remains == 3)) {
772 return -3;
773 }
774
775 p = parse_digits(p, microsecond, len_remains);
776 if (NULL == p) {
777 return -3;
778 }
779
780 if (len_remains == 3) {
781 *microsecond *= 1000;
782 }
783
784 // Return 1 if it's not the end of the string
785 return *p != '\0';
786}
787
788static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400789parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
790 int *second, int *microsecond, int *tzoffset,
791 int *tzmicrosecond)
792{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500793 // Parse the time portion of a datetime.isoformat() string
794 //
795 // Return codes:
796 // 0: Success (no tzoffset)
797 // 1: Success (with tzoffset)
798 // -3: Failed to parse time component
799 // -4: Failed to parse time separator
800 // -5: Malformed timezone string
801
802 const char *p = dtstr;
803 const char *p_end = dtstr + dtlen;
804
805 const char *tzinfo_pos = p;
806 do {
807 if (*tzinfo_pos == '+' || *tzinfo_pos == '-') {
808 break;
809 }
Paul Ganssle3df85402018-10-22 12:32:52 -0400810 } while (++tzinfo_pos < p_end);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500811
Paul Ganssle3df85402018-10-22 12:32:52 -0400812 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second,
813 microsecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500814
815 if (rv < 0) {
816 return rv;
Paul Ganssle3df85402018-10-22 12:32:52 -0400817 }
818 else if (tzinfo_pos == p_end) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500819 // We know that there's no time zone, so if there's stuff at the
820 // end of the string it's an error.
821 if (rv == 1) {
822 return -5;
Paul Ganssle3df85402018-10-22 12:32:52 -0400823 }
824 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500825 return 0;
826 }
827 }
828
829 // Parse time zone component
830 // Valid formats are:
831 // - +HH:MM (len 6)
832 // - +HH:MM:SS (len 9)
833 // - +HH:MM:SS.ffffff (len 16)
834 size_t tzlen = p_end - tzinfo_pos;
835 if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) {
836 return -5;
837 }
838
Paul Ganssle3df85402018-10-22 12:32:52 -0400839 int tzsign = (*tzinfo_pos == '-') ? -1 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500840 tzinfo_pos++;
841 int tzhour = 0, tzminute = 0, tzsecond = 0;
Paul Ganssle3df85402018-10-22 12:32:52 -0400842 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond,
843 tzmicrosecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500844
845 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
846 *tzmicrosecond *= tzsign;
847
Paul Ganssle3df85402018-10-22 12:32:52 -0400848 return rv ? -5 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500849}
850
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500851/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000852 * Create various objects, mostly without range checking.
853 */
854
855/* Create a date instance with no range checking. */
856static PyObject *
857new_date_ex(int year, int month, int day, PyTypeObject *type)
858{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000860
Victor Stinnerb67f0962017-02-10 10:34:02 +0100861 if (check_date_args(year, month, day) < 0) {
862 return NULL;
863 }
864
Paul Ganssle3df85402018-10-22 12:32:52 -0400865 self = (PyDateTime_Date *)(type->tp_alloc(type, 0));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 if (self != NULL)
867 set_date_fields(self, year, month, day);
Paul Ganssle3df85402018-10-22 12:32:52 -0400868 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000869}
870
871#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000873
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500874// Forward declaration
Paul Ganssle3df85402018-10-22 12:32:52 -0400875static PyObject *
876new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500877
878/* Create date instance with no range checking, or call subclass constructor */
879static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -0400880new_date_subclass_ex(int year, int month, int day, PyObject *cls)
881{
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500882 PyObject *result;
883 // We have "fast path" constructors for two subclasses: date and datetime
884 if ((PyTypeObject *)cls == &PyDateTime_DateType) {
885 result = new_date_ex(year, month, day, (PyTypeObject *)cls);
Paul Ganssle3df85402018-10-22 12:32:52 -0400886 }
887 else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500888 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
889 (PyTypeObject *)cls);
Paul Ganssle3df85402018-10-22 12:32:52 -0400890 }
891 else {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500892 result = PyObject_CallFunction(cls, "iii", year, month, day);
893 }
894
895 return result;
896}
897
Tim Petersb0c854d2003-05-17 15:57:00 +0000898/* Create a datetime instance with no range checking. */
899static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400900new_datetime_ex2(int year, int month, int day, int hour, int minute,
901 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000902{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 PyDateTime_DateTime *self;
904 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000905
Victor Stinnerb67f0962017-02-10 10:34:02 +0100906 if (check_date_args(year, month, day) < 0) {
907 return NULL;
908 }
909 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
910 return NULL;
911 }
912 if (check_tzinfo_subclass(tzinfo) < 0) {
913 return NULL;
914 }
915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
917 if (self != NULL) {
918 self->hastzinfo = aware;
919 set_date_fields((PyDateTime_Date *)self, year, month, day);
920 DATE_SET_HOUR(self, hour);
921 DATE_SET_MINUTE(self, minute);
922 DATE_SET_SECOND(self, second);
923 DATE_SET_MICROSECOND(self, usecond);
924 if (aware) {
925 Py_INCREF(tzinfo);
926 self->tzinfo = tzinfo;
927 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400928 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 }
930 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000931}
932
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400933static PyObject *
934new_datetime_ex(int year, int month, int day, int hour, int minute,
935 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
936{
937 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
938 tzinfo, 0, type);
939}
940
941#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
942 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000944
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500945static PyObject *
946new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
947 int second, int usecond, PyObject *tzinfo,
948 int fold, PyObject *cls) {
949 PyObject* dt;
950 if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) {
951 // Use the fast path constructor
952 dt = new_datetime(year, month, day, hour, minute, second, usecond,
953 tzinfo, fold);
954 } else {
955 // Subclass
956 dt = PyObject_CallFunction(cls, "iiiiiiiO",
957 year,
958 month,
959 day,
960 hour,
961 minute,
962 second,
963 usecond,
964 tzinfo);
965 }
966
967 return dt;
968}
969
970static PyObject *
971new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
972 int second, int usecond, PyObject *tzinfo,
973 PyObject *cls) {
974 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
975 second, usecond, tzinfo, 0,
976 cls);
977}
978
Tim Petersb0c854d2003-05-17 15:57:00 +0000979/* Create a time instance with no range checking. */
980static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400981new_time_ex2(int hour, int minute, int second, int usecond,
982 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 PyDateTime_Time *self;
985 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000986
Victor Stinnerb67f0962017-02-10 10:34:02 +0100987 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
988 return NULL;
989 }
990 if (check_tzinfo_subclass(tzinfo) < 0) {
991 return NULL;
992 }
993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
995 if (self != NULL) {
996 self->hastzinfo = aware;
997 self->hashcode = -1;
998 TIME_SET_HOUR(self, hour);
999 TIME_SET_MINUTE(self, minute);
1000 TIME_SET_SECOND(self, second);
1001 TIME_SET_MICROSECOND(self, usecond);
1002 if (aware) {
1003 Py_INCREF(tzinfo);
1004 self->tzinfo = tzinfo;
1005 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001006 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 }
1008 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001009}
1010
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001011static PyObject *
1012new_time_ex(int hour, int minute, int second, int usecond,
1013 PyObject *tzinfo, PyTypeObject *type)
1014{
1015 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
1016}
1017
1018#define new_time(hh, mm, ss, us, tzinfo, fold) \
1019 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001020
1021/* Create a timedelta instance. Normalize the members iff normalize is
1022 * true. Passing false is a speed optimization, if you know for sure
1023 * that seconds and microseconds are already in their proper ranges. In any
1024 * case, raises OverflowError and returns NULL if the normalized days is out
1025 * of range).
1026 */
1027static PyObject *
1028new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +00001030{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 if (normalize)
1034 normalize_d_s_us(&days, &seconds, &microseconds);
1035 assert(0 <= seconds && seconds < 24*3600);
1036 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +00001037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 if (check_delta_day_range(days) < 0)
1039 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1042 if (self != NULL) {
1043 self->hashcode = -1;
1044 SET_TD_DAYS(self, days);
1045 SET_TD_SECONDS(self, seconds);
1046 SET_TD_MICROSECONDS(self, microseconds);
1047 }
1048 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001049}
1050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051#define new_delta(d, s, us, normalize) \
1052 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001053
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001054
1055typedef struct
1056{
1057 PyObject_HEAD
1058 PyObject *offset;
1059 PyObject *name;
1060} PyDateTime_TimeZone;
1061
Victor Stinner6ced7c42011-03-21 18:15:42 +01001062/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001063static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -04001064/* The interned Epoch datetime instance */
1065static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00001066
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001067/* Create new timezone instance checking offset range. This
1068 function does not check the name argument. Caller must assure
1069 that offset is a timedelta instance and name is either NULL
1070 or a unicode object. */
1071static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001072create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001073{
1074 PyDateTime_TimeZone *self;
1075 PyTypeObject *type = &PyDateTime_TimeZoneType;
1076
1077 assert(offset != NULL);
1078 assert(PyDelta_Check(offset));
1079 assert(name == NULL || PyUnicode_Check(name));
1080
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001081 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1082 if (self == NULL) {
1083 return NULL;
1084 }
1085 Py_INCREF(offset);
1086 self->offset = offset;
1087 Py_XINCREF(name);
1088 self->name = name;
1089 return (PyObject *)self;
1090}
1091
1092static int delta_bool(PyDateTime_Delta *self);
1093
1094static PyObject *
1095new_timezone(PyObject *offset, PyObject *name)
1096{
1097 assert(offset != NULL);
1098 assert(PyDelta_Check(offset));
1099 assert(name == NULL || PyUnicode_Check(name));
1100
1101 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
1102 Py_INCREF(PyDateTime_TimeZone_UTC);
1103 return PyDateTime_TimeZone_UTC;
1104 }
Ngalim Siregar92c7e302019-08-09 21:22:16 +07001105 if ((GET_TD_DAYS(offset) == -1 &&
1106 GET_TD_SECONDS(offset) == 0 &&
1107 GET_TD_MICROSECONDS(offset) < 1) ||
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001108 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1109 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1110 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04001111 " timedelta(hours=24),"
1112 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001113 return NULL;
1114 }
1115
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001116 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001117}
1118
Tim Petersb0c854d2003-05-17 15:57:00 +00001119/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001120 * tzinfo helpers.
1121 */
1122
Tim Peters855fe882002-12-22 03:43:39 +00001123/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
1124 * raise TypeError and return -1.
1125 */
1126static int
1127check_tzinfo_subclass(PyObject *p)
1128{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 if (p == Py_None || PyTZInfo_Check(p))
1130 return 0;
1131 PyErr_Format(PyExc_TypeError,
1132 "tzinfo argument must be None or of a tzinfo subclass, "
1133 "not type '%s'",
1134 Py_TYPE(p)->tp_name);
1135 return -1;
Tim Peters855fe882002-12-22 03:43:39 +00001136}
1137
Tim Peters2a799bf2002-12-16 20:18:38 +00001138/* If self has a tzinfo member, return a BORROWED reference to it. Else
1139 * return NULL, which is NOT AN ERROR. There are no error returns here,
1140 * and the caller must not decref the result.
1141 */
1142static PyObject *
1143get_tzinfo_member(PyObject *self)
1144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 if (PyDateTime_Check(self) && HASTZINFO(self))
1148 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1149 else if (PyTime_Check(self) && HASTZINFO(self))
1150 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001153}
1154
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001155/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
1156 * be an instance of the tzinfo class. If the method returns None, this
1157 * returns None. If the method doesn't return None or timedelta, TypeError is
1158 * raised and this returns NULL. If it returns a timedelta and the value is
1159 * out of range or isn't a whole number of minutes, ValueError is raised and
1160 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +00001161 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001162static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001163call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001164{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001165 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001168 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001170
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001171 if (tzinfo == Py_None)
1172 Py_RETURN_NONE;
1173 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1174 if (offset == Py_None || offset == NULL)
1175 return offset;
1176 if (PyDelta_Check(offset)) {
Ngalim Siregar92c7e302019-08-09 21:22:16 +07001177 if ((GET_TD_DAYS(offset) == -1 &&
1178 GET_TD_SECONDS(offset) == 0 &&
1179 GET_TD_MICROSECONDS(offset) < 1) ||
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001180 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1181 Py_DECREF(offset);
1182 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1183 " strictly between -timedelta(hours=24) and"
1184 " timedelta(hours=24).");
1185 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 }
1187 }
1188 else {
1189 PyErr_Format(PyExc_TypeError,
1190 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001191 "timedelta, not '%.200s'",
1192 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07001193 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001194 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001196
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001197 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001198}
1199
1200/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1201 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
1202 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +00001203 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001204 * If utcoffset() returns an out of range timedelta,
1205 * ValueError is raised and this returns -1. Else *none is
1206 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001207 */
Tim Peters855fe882002-12-22 03:43:39 +00001208static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001209call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1210{
1211 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001212}
1213
Tim Peters2a799bf2002-12-16 20:18:38 +00001214/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1215 * result. tzinfo must be an instance of the tzinfo class. If dst()
1216 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001217 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00001218 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +00001219 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001220 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001221 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001222static PyObject *
1223call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001224{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001225 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001226}
1227
Tim Petersbad8ff02002-12-30 20:52:32 +00001228/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +00001229 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001230 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001231 * returns NULL. If the result is a string, we ensure it is a Unicode
1232 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001233 */
1234static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001235call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001238 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 assert(tzinfo != NULL);
1241 assert(check_tzinfo_subclass(tzinfo) >= 0);
1242 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001245 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001246
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001247 result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001248
1249 if (result == NULL || result == Py_None)
1250 return result;
1251
1252 if (!PyUnicode_Check(result)) {
1253 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1254 "return None or a string, not '%s'",
1255 Py_TYPE(result)->tp_name);
1256 Py_DECREF(result);
1257 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001259
1260 return result;
Tim Peters00237032002-12-27 02:21:51 +00001261}
1262
Tim Peters2a799bf2002-12-16 20:18:38 +00001263/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1264 * stuff
1265 * ", tzinfo=" + repr(tzinfo)
1266 * before the closing ")".
1267 */
1268static PyObject *
1269append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 assert(PyUnicode_Check(repr));
1274 assert(tzinfo);
1275 if (tzinfo == Py_None)
1276 return repr;
1277 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001278 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1279 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 Py_DECREF(repr);
1281 if (temp == NULL)
1282 return NULL;
1283 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1284 Py_DECREF(temp);
1285 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001286}
1287
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001288/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1289 * stuff
1290 * ", fold=" + repr(tzinfo)
1291 * before the closing ")".
1292 */
1293static PyObject *
1294append_keyword_fold(PyObject *repr, int fold)
1295{
1296 PyObject *temp;
1297
1298 assert(PyUnicode_Check(repr));
1299 if (fold == 0)
1300 return repr;
1301 /* Get rid of the trailing ')'. */
1302 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1303 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1304 Py_DECREF(repr);
1305 if (temp == NULL)
1306 return NULL;
1307 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1308 Py_DECREF(temp);
1309 return repr;
1310}
1311
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001312static inline PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04001313tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
1314{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001315 PyObject *tzinfo;
1316 if (rv == 1) {
1317 // Create a timezone from offset in seconds (0 returns UTC)
1318 if (tzoffset == 0) {
1319 Py_INCREF(PyDateTime_TimeZone_UTC);
1320 return PyDateTime_TimeZone_UTC;
1321 }
1322
1323 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001324 if (delta == NULL) {
1325 return NULL;
1326 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001327 tzinfo = new_timezone(delta, NULL);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001328 Py_DECREF(delta);
Paul Ganssle3df85402018-10-22 12:32:52 -04001329 }
1330 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001331 tzinfo = Py_None;
1332 Py_INCREF(Py_None);
1333 }
1334
1335 return tzinfo;
1336}
1337
Tim Peters2a799bf2002-12-16 20:18:38 +00001338/* ---------------------------------------------------------------------------
1339 * String format helpers.
1340 */
1341
1342static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001343format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001344{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001345 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1347 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001348 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1350 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1351 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1356 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1357 GET_DAY(date), hours, minutes, seconds,
1358 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001359}
1360
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001361static PyObject *delta_negative(PyDateTime_Delta *self);
1362
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001363/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001364 * buflen bytes remaining. The UTC offset is gotten by calling
1365 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1366 * *buf, and that's all. Else the returned value is checked for sanity (an
1367 * integer in range), and if that's OK it's converted to an hours & minutes
1368 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001369 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001370 * Returns 0 if everything is OK. If the return value from utcoffset() is
1371 * bogus, an appropriate exception is set and -1 is returned.
1372 */
1373static int
Tim Peters328fff72002-12-20 01:31:27 +00001374format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001376{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001377 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001378 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001382
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001383 offset = call_utcoffset(tzinfo, tzinfoarg);
1384 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001386 if (offset == Py_None) {
1387 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 *buf = '\0';
1389 return 0;
1390 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001391 /* Offset is normalized, so it is negative if days < 0 */
1392 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001394 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001395 if (offset == NULL)
1396 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001398 else {
1399 sign = '+';
1400 }
1401 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001402 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001403 seconds = GET_TD_SECONDS(offset);
1404 Py_DECREF(offset);
1405 minutes = divmod(seconds, 60, &seconds);
1406 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001407 if (microseconds) {
1408 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1409 hours, sep, minutes, sep, seconds, microseconds);
1410 return 0;
1411 }
1412 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001413 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1414 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001415 return 0;
1416 }
1417 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001419}
1420
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001421static PyObject *
1422make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 PyObject *temp;
1425 PyObject *tzinfo = get_tzinfo_member(object);
1426 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001427 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 if (Zreplacement == NULL)
1430 return NULL;
1431 if (tzinfo == Py_None || tzinfo == NULL)
1432 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 assert(tzinfoarg != NULL);
1435 temp = call_tzname(tzinfo, tzinfoarg);
1436 if (temp == NULL)
1437 goto Error;
1438 if (temp == Py_None) {
1439 Py_DECREF(temp);
1440 return Zreplacement;
1441 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 assert(PyUnicode_Check(temp));
1444 /* Since the tzname is getting stuffed into the
1445 * format, we have to double any % signs so that
1446 * strftime doesn't treat them as format codes.
1447 */
1448 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001449 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 Py_DECREF(temp);
1451 if (Zreplacement == NULL)
1452 return NULL;
1453 if (!PyUnicode_Check(Zreplacement)) {
1454 PyErr_SetString(PyExc_TypeError,
1455 "tzname.replace() did not return a string");
1456 goto Error;
1457 }
1458 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001459
1460 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 Py_DECREF(Zreplacement);
1462 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001463}
1464
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001465static PyObject *
1466make_freplacement(PyObject *object)
1467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 char freplacement[64];
1469 if (PyTime_Check(object))
1470 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1471 else if (PyDateTime_Check(object))
1472 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1473 else
1474 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001477}
1478
Tim Peters2a799bf2002-12-16 20:18:38 +00001479/* I sure don't want to reproduce the strftime code from the time module,
1480 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001481 * giving special meanings to the %z, %Z and %f format codes via a
1482 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001483 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1484 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001485 */
1486static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001487wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1493 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1494 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 const char *pin; /* pointer to next char in input format */
1497 Py_ssize_t flen; /* length of input format */
1498 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 PyObject *newfmt = NULL; /* py string, the output format */
1501 char *pnew; /* pointer to available byte in output format */
1502 size_t totalnew; /* number bytes total in output format buffer,
1503 exclusive of trailing \0 */
1504 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 const char *ptoappend; /* ptr to string to append to output buffer */
1507 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 assert(object && format && timetuple);
1510 assert(PyUnicode_Check(format));
1511 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001512 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 if (!pin)
1514 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 /* Scan the input format, looking for %z/%Z/%f escapes, building
1517 * a new format. Since computing the replacements for those codes
1518 * is expensive, don't unless they're actually used.
1519 */
1520 if (flen > INT_MAX - 1) {
1521 PyErr_NoMemory();
1522 goto Done;
1523 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 totalnew = flen + 1; /* realistic if no %z/%Z */
1526 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1527 if (newfmt == NULL) goto Done;
1528 pnew = PyBytes_AsString(newfmt);
1529 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 while ((ch = *pin++) != '\0') {
1532 if (ch != '%') {
1533 ptoappend = pin - 1;
1534 ntoappend = 1;
1535 }
1536 else if ((ch = *pin++) == '\0') {
Victor Stinner2ff58a22019-06-17 14:27:23 +02001537 /* Null byte follows %, copy only '%'.
1538 *
MichaelSaah454b3d42019-01-14 05:23:39 -05001539 * Back the pin up one char so that we catch the null check
1540 * the next time through the loop.*/
1541 pin--;
1542 ptoappend = pin - 1;
1543 ntoappend = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 }
1545 /* A % has been seen and ch is the character after it. */
1546 else if (ch == 'z') {
1547 if (zreplacement == NULL) {
1548 /* format utcoffset */
1549 char buf[100];
1550 PyObject *tzinfo = get_tzinfo_member(object);
1551 zreplacement = PyBytes_FromStringAndSize("", 0);
1552 if (zreplacement == NULL) goto Done;
1553 if (tzinfo != Py_None && tzinfo != NULL) {
1554 assert(tzinfoarg != NULL);
1555 if (format_utcoffset(buf,
1556 sizeof(buf),
1557 "",
1558 tzinfo,
1559 tzinfoarg) < 0)
1560 goto Done;
1561 Py_DECREF(zreplacement);
1562 zreplacement =
1563 PyBytes_FromStringAndSize(buf,
1564 strlen(buf));
1565 if (zreplacement == NULL)
1566 goto Done;
1567 }
1568 }
1569 assert(zreplacement != NULL);
1570 ptoappend = PyBytes_AS_STRING(zreplacement);
1571 ntoappend = PyBytes_GET_SIZE(zreplacement);
1572 }
1573 else if (ch == 'Z') {
1574 /* format tzname */
1575 if (Zreplacement == NULL) {
1576 Zreplacement = make_Zreplacement(object,
1577 tzinfoarg);
1578 if (Zreplacement == NULL)
1579 goto Done;
1580 }
1581 assert(Zreplacement != NULL);
1582 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001583 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001585 if (ptoappend == NULL)
1586 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 }
1588 else if (ch == 'f') {
1589 /* format microseconds */
1590 if (freplacement == NULL) {
1591 freplacement = make_freplacement(object);
1592 if (freplacement == NULL)
1593 goto Done;
1594 }
1595 assert(freplacement != NULL);
1596 assert(PyBytes_Check(freplacement));
1597 ptoappend = PyBytes_AS_STRING(freplacement);
1598 ntoappend = PyBytes_GET_SIZE(freplacement);
1599 }
1600 else {
1601 /* percent followed by neither z nor Z */
1602 ptoappend = pin - 2;
1603 ntoappend = 2;
1604 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 /* Append the ntoappend chars starting at ptoappend to
1607 * the new format.
1608 */
1609 if (ntoappend == 0)
1610 continue;
1611 assert(ptoappend != NULL);
1612 assert(ntoappend > 0);
1613 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001614 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 PyErr_NoMemory();
1616 goto Done;
1617 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001618 totalnew <<= 1;
1619 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 pnew = PyBytes_AsString(newfmt) + usednew;
1622 }
1623 memcpy(pnew, ptoappend, ntoappend);
1624 pnew += ntoappend;
1625 usednew += ntoappend;
1626 assert(usednew <= totalnew);
1627 } /* end while() */
Victor Stinner2ff58a22019-06-17 14:27:23 +02001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1630 goto Done;
1631 {
1632 PyObject *format;
1633 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 if (time == NULL)
1636 goto Done;
1637 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1638 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001639 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1640 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 Py_DECREF(format);
1642 }
1643 Py_DECREF(time);
1644 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001645 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 Py_XDECREF(freplacement);
1647 Py_XDECREF(zreplacement);
1648 Py_XDECREF(Zreplacement);
1649 Py_XDECREF(newfmt);
1650 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001651}
1652
Tim Peters2a799bf2002-12-16 20:18:38 +00001653/* ---------------------------------------------------------------------------
1654 * Wrap functions from the time module. These aren't directly available
1655 * from C. Perhaps they should be.
1656 */
1657
1658/* Call time.time() and return its result (a Python float). */
1659static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001660time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 PyObject *result = NULL;
1663 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001666 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001667
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001668 result = _PyObject_CallMethodIdNoArgs(time, &PyId_time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 Py_DECREF(time);
1670 }
1671 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001672}
1673
1674/* Build a time.struct_time. The weekday and day number are automatically
1675 * computed from the y,m,d args.
1676 */
1677static PyObject *
1678build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001681 PyObject *result;
1682 _Py_IDENTIFIER(struct_time);
1683 PyObject *args;
1684
Tim Peters2a799bf2002-12-16 20:18:38 +00001685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001687 if (time == NULL) {
1688 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 }
Victor Stinner2b635972016-12-09 00:38:16 +01001690
1691 args = Py_BuildValue("iiiiiiiii",
1692 y, m, d,
1693 hh, mm, ss,
1694 weekday(y, m, d),
1695 days_before_month(y, m) + d,
1696 dstflag);
1697 if (args == NULL) {
1698 Py_DECREF(time);
1699 return NULL;
1700 }
1701
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001702 result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args);
Victor Stinner2b635972016-12-09 00:38:16 +01001703 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001704 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001705 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001706}
1707
1708/* ---------------------------------------------------------------------------
1709 * Miscellaneous helpers.
1710 */
1711
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001712/* The comparisons here all most naturally compute a cmp()-like result.
Tim Peters2a799bf2002-12-16 20:18:38 +00001713 * This little helper turns that into a bool result for rich comparisons.
1714 */
1715static PyObject *
1716diff_to_bool(int diff, int op)
1717{
stratakise8b19652017-11-02 11:32:54 +01001718 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001719}
1720
Tim Peters07534a62003-02-07 22:50:28 +00001721/* Raises a "can't compare" TypeError and returns NULL. */
1722static PyObject *
1723cmperror(PyObject *a, PyObject *b)
1724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 PyErr_Format(PyExc_TypeError,
1726 "can't compare %s to %s",
1727 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1728 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001729}
1730
Tim Peters2a799bf2002-12-16 20:18:38 +00001731/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001732 * Cached Python objects; these are set by the module init function.
1733 */
1734
1735/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736static PyObject *us_per_ms = NULL; /* 1000 */
1737static PyObject *us_per_second = NULL; /* 1000000 */
1738static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001739static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1740static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1741static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001742static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1743
Tim Peters2a799bf2002-12-16 20:18:38 +00001744/* ---------------------------------------------------------------------------
1745 * Class implementations.
1746 */
1747
1748/*
1749 * PyDateTime_Delta implementation.
1750 */
1751
1752/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001754 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001755 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1756 * due to ubiquitous overflow possibilities.
1757 */
1758static PyObject *
1759delta_to_microseconds(PyDateTime_Delta *self)
1760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 PyObject *x1 = NULL;
1762 PyObject *x2 = NULL;
1763 PyObject *x3 = NULL;
1764 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1767 if (x1 == NULL)
1768 goto Done;
1769 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1770 if (x2 == NULL)
1771 goto Done;
1772 Py_DECREF(x1);
1773 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 /* x2 has days in seconds */
1776 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1777 if (x1 == NULL)
1778 goto Done;
1779 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1780 if (x3 == NULL)
1781 goto Done;
1782 Py_DECREF(x1);
1783 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001784 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 /* x3 has days+seconds in seconds */
1787 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1788 if (x1 == NULL)
1789 goto Done;
1790 Py_DECREF(x3);
1791 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 /* x1 has days+seconds in us */
1794 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1795 if (x2 == NULL)
1796 goto Done;
1797 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001798 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001799
1800Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 Py_XDECREF(x1);
1802 Py_XDECREF(x2);
1803 Py_XDECREF(x3);
1804 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001805}
1806
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001807static PyObject *
1808checked_divmod(PyObject *a, PyObject *b)
1809{
1810 PyObject *result = PyNumber_Divmod(a, b);
1811 if (result != NULL) {
1812 if (!PyTuple_Check(result)) {
1813 PyErr_Format(PyExc_TypeError,
1814 "divmod() returned non-tuple (type %.200s)",
Victor Stinnerdaa97562020-02-07 03:37:06 +01001815 Py_TYPE(result)->tp_name);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001816 Py_DECREF(result);
1817 return NULL;
1818 }
1819 if (PyTuple_GET_SIZE(result) != 2) {
1820 PyErr_Format(PyExc_TypeError,
1821 "divmod() returned a tuple of size %zd",
1822 PyTuple_GET_SIZE(result));
1823 Py_DECREF(result);
1824 return NULL;
1825 }
1826 }
1827 return result;
1828}
1829
Serhiy Storchaka95949422013-08-27 19:40:23 +03001830/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001831 */
1832static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001833microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 int us;
1836 int s;
1837 int d;
Tim Peters2a799bf2002-12-16 20:18:38 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 PyObject *tuple = NULL;
1840 PyObject *num = NULL;
1841 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001842
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001843 tuple = checked_divmod(pyus, us_per_second);
1844 if (tuple == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 goto Done;
1846 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001847
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001848 num = PyTuple_GET_ITEM(tuple, 1); /* us */
1849 us = _PyLong_AsInt(num);
1850 num = NULL;
1851 if (us == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 goto Done;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001853 }
1854 if (!(0 <= us && us < 1000000)) {
1855 goto BadDivmod;
1856 }
1857
1858 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 Py_INCREF(num);
1860 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001861
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001862 tuple = checked_divmod(num, seconds_per_day);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 if (tuple == NULL)
1864 goto Done;
1865 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001866
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001867 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */
1868 s = _PyLong_AsInt(num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 num = NULL;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001870 if (s == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 goto Done;
1872 }
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001873 if (!(0 <= s && s < 24*3600)) {
1874 goto BadDivmod;
1875 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001876
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001877 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 Py_INCREF(num);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001879 d = _PyLong_AsInt(num);
1880 if (d == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 goto Done;
1882 }
1883 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001884
1885Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 Py_XDECREF(tuple);
1887 Py_XDECREF(num);
1888 return result;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001889
1890BadDivmod:
1891 PyErr_SetString(PyExc_TypeError,
1892 "divmod() returned a value out of range");
1893 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001894}
1895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896#define microseconds_to_delta(pymicros) \
1897 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001898
Tim Peters2a799bf2002-12-16 20:18:38 +00001899static PyObject *
1900multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 PyObject *pyus_in;
1903 PyObject *pyus_out;
1904 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 pyus_in = delta_to_microseconds(delta);
1907 if (pyus_in == NULL)
1908 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001909
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001910 pyus_out = PyNumber_Multiply(intobj, pyus_in);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 Py_DECREF(pyus_in);
1912 if (pyus_out == NULL)
1913 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 result = microseconds_to_delta(pyus_out);
1916 Py_DECREF(pyus_out);
1917 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001918}
1919
1920static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001921get_float_as_integer_ratio(PyObject *floatobj)
1922{
1923 PyObject *ratio;
1924
1925 assert(floatobj && PyFloat_Check(floatobj));
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001926 ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio);
Oren Milman865e4b42017-09-19 15:58:11 +03001927 if (ratio == NULL) {
1928 return NULL;
1929 }
1930 if (!PyTuple_Check(ratio)) {
1931 PyErr_Format(PyExc_TypeError,
1932 "unexpected return type from as_integer_ratio(): "
1933 "expected tuple, got '%.200s'",
1934 Py_TYPE(ratio)->tp_name);
1935 Py_DECREF(ratio);
1936 return NULL;
1937 }
1938 if (PyTuple_Size(ratio) != 2) {
1939 PyErr_SetString(PyExc_ValueError,
1940 "as_integer_ratio() must return a 2-tuple");
1941 Py_DECREF(ratio);
1942 return NULL;
1943 }
1944 return ratio;
1945}
1946
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001947/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001948static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001949multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001950{
1951 PyObject *result = NULL;
1952 PyObject *pyus_in = NULL, *temp, *pyus_out;
1953 PyObject *ratio = NULL;
1954
1955 pyus_in = delta_to_microseconds(delta);
1956 if (pyus_in == NULL)
1957 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001958 ratio = get_float_as_integer_ratio(floatobj);
1959 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001960 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001961 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001962 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001963 Py_DECREF(pyus_in);
1964 pyus_in = NULL;
1965 if (temp == NULL)
1966 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001967 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001968 Py_DECREF(temp);
1969 if (pyus_out == NULL)
1970 goto error;
1971 result = microseconds_to_delta(pyus_out);
1972 Py_DECREF(pyus_out);
1973 error:
1974 Py_XDECREF(pyus_in);
1975 Py_XDECREF(ratio);
1976
1977 return result;
1978}
1979
1980static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001981divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 PyObject *pyus_in;
1984 PyObject *pyus_out;
1985 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 pyus_in = delta_to_microseconds(delta);
1988 if (pyus_in == NULL)
1989 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1992 Py_DECREF(pyus_in);
1993 if (pyus_out == NULL)
1994 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 result = microseconds_to_delta(pyus_out);
1997 Py_DECREF(pyus_out);
1998 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001999}
2000
2001static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 PyObject *pyus_left;
2005 PyObject *pyus_right;
2006 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 pyus_left = delta_to_microseconds(left);
2009 if (pyus_left == NULL)
2010 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 pyus_right = delta_to_microseconds(right);
2013 if (pyus_right == NULL) {
2014 Py_DECREF(pyus_left);
2015 return NULL;
2016 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 result = PyNumber_FloorDivide(pyus_left, pyus_right);
2019 Py_DECREF(pyus_left);
2020 Py_DECREF(pyus_right);
2021 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002022}
2023
2024static PyObject *
2025truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2026{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 PyObject *pyus_left;
2028 PyObject *pyus_right;
2029 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 pyus_left = delta_to_microseconds(left);
2032 if (pyus_left == NULL)
2033 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 pyus_right = delta_to_microseconds(right);
2036 if (pyus_right == NULL) {
2037 Py_DECREF(pyus_left);
2038 return NULL;
2039 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2042 Py_DECREF(pyus_left);
2043 Py_DECREF(pyus_right);
2044 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002045}
2046
2047static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002048truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2049{
2050 PyObject *result;
2051 PyObject *pyus_in, *pyus_out;
2052 pyus_in = delta_to_microseconds(delta);
2053 if (pyus_in == NULL)
2054 return NULL;
2055 pyus_out = divide_nearest(pyus_in, i);
2056 Py_DECREF(pyus_in);
2057 if (pyus_out == NULL)
2058 return NULL;
2059 result = microseconds_to_delta(pyus_out);
2060 Py_DECREF(pyus_out);
2061
2062 return result;
2063}
2064
2065static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002066delta_add(PyObject *left, PyObject *right)
2067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2071 /* delta + delta */
2072 /* The C-level additions can't overflow because of the
2073 * invariant bounds.
2074 */
2075 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2076 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2077 int microseconds = GET_TD_MICROSECONDS(left) +
2078 GET_TD_MICROSECONDS(right);
2079 result = new_delta(days, seconds, microseconds, 1);
2080 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 if (result == Py_NotImplemented)
2083 Py_INCREF(result);
2084 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002085}
2086
2087static PyObject *
2088delta_negative(PyDateTime_Delta *self)
2089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 return new_delta(-GET_TD_DAYS(self),
2091 -GET_TD_SECONDS(self),
2092 -GET_TD_MICROSECONDS(self),
2093 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002094}
2095
2096static PyObject *
2097delta_positive(PyDateTime_Delta *self)
2098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 /* Could optimize this (by returning self) if this isn't a
2100 * subclass -- but who uses unary + ? Approximately nobody.
2101 */
2102 return new_delta(GET_TD_DAYS(self),
2103 GET_TD_SECONDS(self),
2104 GET_TD_MICROSECONDS(self),
2105 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002106}
2107
2108static PyObject *
2109delta_abs(PyDateTime_Delta *self)
2110{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 assert(GET_TD_MICROSECONDS(self) >= 0);
2114 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 if (GET_TD_DAYS(self) < 0)
2117 result = delta_negative(self);
2118 else
2119 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002122}
2123
2124static PyObject *
2125delta_subtract(PyObject *left, PyObject *right)
2126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2130 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002131 /* The C-level additions can't overflow because of the
2132 * invariant bounds.
2133 */
2134 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2135 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2136 int microseconds = GET_TD_MICROSECONDS(left) -
2137 GET_TD_MICROSECONDS(right);
2138 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 if (result == Py_NotImplemented)
2142 Py_INCREF(result);
2143 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002144}
2145
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002146static int
2147delta_cmp(PyObject *self, PyObject *other)
2148{
2149 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2150 if (diff == 0) {
2151 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2152 if (diff == 0)
2153 diff = GET_TD_MICROSECONDS(self) -
2154 GET_TD_MICROSECONDS(other);
2155 }
2156 return diff;
2157}
2158
Tim Peters2a799bf2002-12-16 20:18:38 +00002159static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002160delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002161{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002163 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 return diff_to_bool(diff, op);
2165 }
2166 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002167 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002169}
2170
2171static PyObject *delta_getstate(PyDateTime_Delta *self);
2172
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002173static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002174delta_hash(PyDateTime_Delta *self)
2175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 if (self->hashcode == -1) {
2177 PyObject *temp = delta_getstate(self);
2178 if (temp != NULL) {
2179 self->hashcode = PyObject_Hash(temp);
2180 Py_DECREF(temp);
2181 }
2182 }
2183 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002184}
2185
2186static PyObject *
2187delta_multiply(PyObject *left, PyObject *right)
2188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 if (PyDelta_Check(left)) {
2192 /* delta * ??? */
2193 if (PyLong_Check(right))
2194 result = multiply_int_timedelta(right,
2195 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002196 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002197 result = multiply_truedivide_timedelta_float(
2198 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 }
2200 else if (PyLong_Check(left))
2201 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002202 (PyDateTime_Delta *) right);
2203 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002204 result = multiply_truedivide_timedelta_float(
2205 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002207 if (result == Py_NotImplemented)
2208 Py_INCREF(result);
2209 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002210}
2211
2212static PyObject *
2213delta_divide(PyObject *left, PyObject *right)
2214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002215 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 if (PyDelta_Check(left)) {
2218 /* delta * ??? */
2219 if (PyLong_Check(right))
2220 result = divide_timedelta_int(
2221 (PyDateTime_Delta *)left,
2222 right);
2223 else if (PyDelta_Check(right))
2224 result = divide_timedelta_timedelta(
2225 (PyDateTime_Delta *)left,
2226 (PyDateTime_Delta *)right);
2227 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 if (result == Py_NotImplemented)
2230 Py_INCREF(result);
2231 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002232}
2233
Mark Dickinson7c186e22010-04-20 22:32:49 +00002234static PyObject *
2235delta_truedivide(PyObject *left, PyObject *right)
2236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 if (PyDelta_Check(left)) {
2240 if (PyDelta_Check(right))
2241 result = truedivide_timedelta_timedelta(
2242 (PyDateTime_Delta *)left,
2243 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002244 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002245 result = multiply_truedivide_timedelta_float(
2246 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002247 else if (PyLong_Check(right))
2248 result = truedivide_timedelta_int(
2249 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002252 if (result == Py_NotImplemented)
2253 Py_INCREF(result);
2254 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002255}
2256
2257static PyObject *
2258delta_remainder(PyObject *left, PyObject *right)
2259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 PyObject *pyus_left;
2261 PyObject *pyus_right;
2262 PyObject *pyus_remainder;
2263 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002264
Brian Curtindfc80e32011-08-10 20:28:54 -05002265 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2266 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2269 if (pyus_left == NULL)
2270 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2273 if (pyus_right == NULL) {
2274 Py_DECREF(pyus_left);
2275 return NULL;
2276 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2279 Py_DECREF(pyus_left);
2280 Py_DECREF(pyus_right);
2281 if (pyus_remainder == NULL)
2282 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 remainder = microseconds_to_delta(pyus_remainder);
2285 Py_DECREF(pyus_remainder);
2286 if (remainder == NULL)
2287 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002290}
2291
2292static PyObject *
2293delta_divmod(PyObject *left, PyObject *right)
2294{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 PyObject *pyus_left;
2296 PyObject *pyus_right;
2297 PyObject *divmod;
2298 PyObject *delta;
2299 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002300
Brian Curtindfc80e32011-08-10 20:28:54 -05002301 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2302 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2305 if (pyus_left == NULL)
2306 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2309 if (pyus_right == NULL) {
2310 Py_DECREF(pyus_left);
2311 return NULL;
2312 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002313
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002314 divmod = checked_divmod(pyus_left, pyus_right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 Py_DECREF(pyus_left);
2316 Py_DECREF(pyus_right);
2317 if (divmod == NULL)
2318 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002320 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2321 if (delta == NULL) {
2322 Py_DECREF(divmod);
2323 return NULL;
2324 }
2325 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2326 Py_DECREF(delta);
2327 Py_DECREF(divmod);
2328 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002329}
2330
Tim Peters2a799bf2002-12-16 20:18:38 +00002331/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2332 * timedelta constructor. sofar is the # of microseconds accounted for
2333 * so far, and there are factor microseconds per current unit, the number
2334 * of which is given by num. num * factor is added to sofar in a
2335 * numerically careful way, and that's the result. Any fractional
2336 * microseconds left over (this can happen if num is a float type) are
2337 * added into *leftover.
2338 * Note that there are many ways this can give an error (NULL) return.
2339 */
2340static PyObject *
2341accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2342 double *leftover)
2343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 PyObject *prod;
2345 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 if (PyLong_Check(num)) {
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002350 prod = PyNumber_Multiply(num, factor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 if (prod == NULL)
2352 return NULL;
2353 sum = PyNumber_Add(sofar, prod);
2354 Py_DECREF(prod);
2355 return sum;
2356 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002358 if (PyFloat_Check(num)) {
2359 double dnum;
2360 double fracpart;
2361 double intpart;
2362 PyObject *x;
2363 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002365 /* The Plan: decompose num into an integer part and a
2366 * fractional part, num = intpart + fracpart.
2367 * Then num * factor ==
2368 * intpart * factor + fracpart * factor
2369 * and the LHS can be computed exactly in long arithmetic.
2370 * The RHS is again broken into an int part and frac part.
2371 * and the frac part is added into *leftover.
2372 */
2373 dnum = PyFloat_AsDouble(num);
2374 if (dnum == -1.0 && PyErr_Occurred())
2375 return NULL;
2376 fracpart = modf(dnum, &intpart);
2377 x = PyLong_FromDouble(intpart);
2378 if (x == NULL)
2379 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 prod = PyNumber_Multiply(x, factor);
2382 Py_DECREF(x);
2383 if (prod == NULL)
2384 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 sum = PyNumber_Add(sofar, prod);
2387 Py_DECREF(prod);
2388 if (sum == NULL)
2389 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 if (fracpart == 0.0)
2392 return sum;
2393 /* So far we've lost no information. Dealing with the
2394 * fractional part requires float arithmetic, and may
2395 * lose a little info.
2396 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002397 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 dnum *= fracpart;
2401 fracpart = modf(dnum, &intpart);
2402 x = PyLong_FromDouble(intpart);
2403 if (x == NULL) {
2404 Py_DECREF(sum);
2405 return NULL;
2406 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 y = PyNumber_Add(sum, x);
2409 Py_DECREF(sum);
2410 Py_DECREF(x);
2411 *leftover += fracpart;
2412 return y;
2413 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 PyErr_Format(PyExc_TypeError,
2416 "unsupported type for timedelta %s component: %s",
2417 tag, Py_TYPE(num)->tp_name);
2418 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002419}
2420
2421static PyObject *
2422delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 /* Argument objects. */
2427 PyObject *day = NULL;
2428 PyObject *second = NULL;
2429 PyObject *us = NULL;
2430 PyObject *ms = NULL;
2431 PyObject *minute = NULL;
2432 PyObject *hour = NULL;
2433 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 PyObject *x = NULL; /* running sum of microseconds */
2436 PyObject *y = NULL; /* temp sum of microseconds */
2437 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 static char *keywords[] = {
2440 "days", "seconds", "microseconds", "milliseconds",
2441 "minutes", "hours", "weeks", NULL
2442 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2445 keywords,
2446 &day, &second, &us,
2447 &ms, &minute, &hour, &week) == 0)
2448 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 x = PyLong_FromLong(0);
2451 if (x == NULL)
2452 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002454#define CLEANUP \
2455 Py_DECREF(x); \
2456 x = y; \
2457 if (x == NULL) \
2458 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002461 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 CLEANUP;
2463 }
2464 if (ms) {
2465 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2466 CLEANUP;
2467 }
2468 if (second) {
2469 y = accum("seconds", x, second, us_per_second, &leftover_us);
2470 CLEANUP;
2471 }
2472 if (minute) {
2473 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2474 CLEANUP;
2475 }
2476 if (hour) {
2477 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2478 CLEANUP;
2479 }
2480 if (day) {
2481 y = accum("days", x, day, us_per_day, &leftover_us);
2482 CLEANUP;
2483 }
2484 if (week) {
2485 y = accum("weeks", x, week, us_per_week, &leftover_us);
2486 CLEANUP;
2487 }
2488 if (leftover_us) {
2489 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002490 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002491 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002492 PyObject *temp;
2493
Victor Stinner69cc4872015-09-08 23:58:54 +02002494 if (fabs(whole_us - leftover_us) == 0.5) {
2495 /* We're exactly halfway between two integers. In order
2496 * to do round-half-to-even, we must determine whether x
2497 * is odd. Note that x is odd when it's last bit is 1. The
2498 * code below uses bitwise and operation to check the last
2499 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002500 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002501 if (temp == NULL) {
2502 Py_DECREF(x);
2503 goto Done;
2504 }
2505 x_is_odd = PyObject_IsTrue(temp);
2506 Py_DECREF(temp);
2507 if (x_is_odd == -1) {
2508 Py_DECREF(x);
2509 goto Done;
2510 }
2511 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2512 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002513
Victor Stinner36a5a062013-08-28 01:53:39 +02002514 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 if (temp == NULL) {
2517 Py_DECREF(x);
2518 goto Done;
2519 }
2520 y = PyNumber_Add(x, temp);
2521 Py_DECREF(temp);
2522 CLEANUP;
2523 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002525 self = microseconds_to_delta_ex(x, type);
2526 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002527Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002529
2530#undef CLEANUP
2531}
2532
2533static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002534delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002535{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 return (GET_TD_DAYS(self) != 0
2537 || GET_TD_SECONDS(self) != 0
2538 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002539}
2540
2541static PyObject *
2542delta_repr(PyDateTime_Delta *self)
2543{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002544 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002545
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002546 if (args == NULL) {
2547 return NULL;
2548 }
2549
2550 const char *sep = "";
2551
2552 if (GET_TD_DAYS(self) != 0) {
2553 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2554 if (args == NULL) {
2555 return NULL;
2556 }
2557 sep = ", ";
2558 }
2559
2560 if (GET_TD_SECONDS(self) != 0) {
2561 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2562 GET_TD_SECONDS(self)));
2563 if (args == NULL) {
2564 return NULL;
2565 }
2566 sep = ", ";
2567 }
2568
2569 if (GET_TD_MICROSECONDS(self) != 0) {
2570 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2571 GET_TD_MICROSECONDS(self)));
2572 if (args == NULL) {
2573 return NULL;
2574 }
2575 }
2576
2577 if (PyUnicode_GET_LENGTH(args) == 0) {
2578 Py_SETREF(args, PyUnicode_FromString("0"));
2579 if (args == NULL) {
2580 return NULL;
2581 }
2582 }
2583
2584 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2585 args);
2586 Py_DECREF(args);
2587 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002588}
2589
2590static PyObject *
2591delta_str(PyDateTime_Delta *self)
2592{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002593 int us = GET_TD_MICROSECONDS(self);
2594 int seconds = GET_TD_SECONDS(self);
2595 int minutes = divmod(seconds, 60, &seconds);
2596 int hours = divmod(minutes, 60, &minutes);
2597 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599 if (days) {
2600 if (us)
2601 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2602 days, (days == 1 || days == -1) ? "" : "s",
2603 hours, minutes, seconds, us);
2604 else
2605 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2606 days, (days == 1 || days == -1) ? "" : "s",
2607 hours, minutes, seconds);
2608 } else {
2609 if (us)
2610 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2611 hours, minutes, seconds, us);
2612 else
2613 return PyUnicode_FromFormat("%d:%02d:%02d",
2614 hours, minutes, seconds);
2615 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002616
Tim Peters2a799bf2002-12-16 20:18:38 +00002617}
2618
Tim Peters371935f2003-02-01 01:52:50 +00002619/* Pickle support, a simple use of __reduce__. */
2620
Tim Petersb57f8f02003-02-01 02:54:15 +00002621/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002622static PyObject *
2623delta_getstate(PyDateTime_Delta *self)
2624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625 return Py_BuildValue("iii", GET_TD_DAYS(self),
2626 GET_TD_SECONDS(self),
2627 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002628}
2629
Tim Peters2a799bf2002-12-16 20:18:38 +00002630static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302631delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitroube6859d2009-11-25 23:02:32 +00002632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 PyObject *total_seconds;
2634 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2637 if (total_microseconds == NULL)
2638 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002639
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002640 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002644}
2645
2646static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302647delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00002648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002649 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002650}
2651
2652#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2653
2654static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002656 {"days", T_INT, OFFSET(days), READONLY,
2657 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 {"seconds", T_INT, OFFSET(seconds), READONLY,
2660 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2663 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2664 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002665};
2666
2667static PyMethodDef delta_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302668 {"total_seconds", delta_total_seconds, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002669 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2672 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002674 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002675};
2676
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002677static const char delta_doc[] =
Chris Barkerd6a61f22018-10-19 15:43:24 -07002678PyDoc_STR("Difference between two datetime values.\n\n"
2679 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2680 "minutes=0, hours=0, weeks=0)\n\n"
2681 "All arguments are optional and default to 0.\n"
2682 "Arguments may be integers or floats, and may be positive or negative.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002683
2684static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002685 delta_add, /* nb_add */
2686 delta_subtract, /* nb_subtract */
2687 delta_multiply, /* nb_multiply */
2688 delta_remainder, /* nb_remainder */
2689 delta_divmod, /* nb_divmod */
2690 0, /* nb_power */
2691 (unaryfunc)delta_negative, /* nb_negative */
2692 (unaryfunc)delta_positive, /* nb_positive */
2693 (unaryfunc)delta_abs, /* nb_absolute */
2694 (inquiry)delta_bool, /* nb_bool */
2695 0, /*nb_invert*/
2696 0, /*nb_lshift*/
2697 0, /*nb_rshift*/
2698 0, /*nb_and*/
2699 0, /*nb_xor*/
2700 0, /*nb_or*/
2701 0, /*nb_int*/
2702 0, /*nb_reserved*/
2703 0, /*nb_float*/
2704 0, /*nb_inplace_add*/
2705 0, /*nb_inplace_subtract*/
2706 0, /*nb_inplace_multiply*/
2707 0, /*nb_inplace_remainder*/
2708 0, /*nb_inplace_power*/
2709 0, /*nb_inplace_lshift*/
2710 0, /*nb_inplace_rshift*/
2711 0, /*nb_inplace_and*/
2712 0, /*nb_inplace_xor*/
2713 0, /*nb_inplace_or*/
2714 delta_divide, /* nb_floor_divide */
2715 delta_truedivide, /* nb_true_divide */
2716 0, /* nb_inplace_floor_divide */
2717 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002718};
2719
2720static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002721 PyVarObject_HEAD_INIT(NULL, 0)
2722 "datetime.timedelta", /* tp_name */
2723 sizeof(PyDateTime_Delta), /* tp_basicsize */
2724 0, /* tp_itemsize */
2725 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002726 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002727 0, /* tp_getattr */
2728 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002729 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002730 (reprfunc)delta_repr, /* tp_repr */
2731 &delta_as_number, /* tp_as_number */
2732 0, /* tp_as_sequence */
2733 0, /* tp_as_mapping */
2734 (hashfunc)delta_hash, /* tp_hash */
2735 0, /* tp_call */
2736 (reprfunc)delta_str, /* tp_str */
2737 PyObject_GenericGetAttr, /* tp_getattro */
2738 0, /* tp_setattro */
2739 0, /* tp_as_buffer */
2740 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2741 delta_doc, /* tp_doc */
2742 0, /* tp_traverse */
2743 0, /* tp_clear */
2744 delta_richcompare, /* tp_richcompare */
2745 0, /* tp_weaklistoffset */
2746 0, /* tp_iter */
2747 0, /* tp_iternext */
2748 delta_methods, /* tp_methods */
2749 delta_members, /* tp_members */
2750 0, /* tp_getset */
2751 0, /* tp_base */
2752 0, /* tp_dict */
2753 0, /* tp_descr_get */
2754 0, /* tp_descr_set */
2755 0, /* tp_dictoffset */
2756 0, /* tp_init */
2757 0, /* tp_alloc */
2758 delta_new, /* tp_new */
2759 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002760};
2761
2762/*
2763 * PyDateTime_Date implementation.
2764 */
2765
2766/* Accessor properties. */
2767
2768static PyObject *
2769date_year(PyDateTime_Date *self, void *unused)
2770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002771 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002772}
2773
2774static PyObject *
2775date_month(PyDateTime_Date *self, void *unused)
2776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002777 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002778}
2779
2780static PyObject *
2781date_day(PyDateTime_Date *self, void *unused)
2782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002783 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002784}
2785
2786static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002787 {"year", (getter)date_year},
2788 {"month", (getter)date_month},
2789 {"day", (getter)date_day},
2790 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002791};
2792
2793/* Constructors. */
2794
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002795static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002796
Tim Peters2a799bf2002-12-16 20:18:38 +00002797static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002798date_from_pickle(PyTypeObject *type, PyObject *state)
2799{
2800 PyDateTime_Date *me;
2801
2802 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2803 if (me != NULL) {
2804 const char *pdata = PyBytes_AS_STRING(state);
2805 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2806 me->hashcode = -1;
2807 }
2808 return (PyObject *)me;
2809}
2810
2811static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002812date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 int year;
2816 int month;
2817 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002819 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka1133a8c2018-12-07 16:48:21 +02002820 if (PyTuple_GET_SIZE(args) == 1) {
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002821 PyObject *state = PyTuple_GET_ITEM(args, 0);
2822 if (PyBytes_Check(state)) {
2823 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2824 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2825 {
2826 return date_from_pickle(type, state);
Victor Stinnerb37672d2018-11-22 03:37:50 +01002827 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002828 }
2829 else if (PyUnicode_Check(state)) {
2830 if (PyUnicode_READY(state)) {
2831 return NULL;
2832 }
2833 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
2834 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
2835 {
2836 state = PyUnicode_AsLatin1String(state);
2837 if (state == NULL) {
2838 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
2839 /* More informative error message. */
2840 PyErr_SetString(PyExc_ValueError,
2841 "Failed to encode latin1 string when unpickling "
2842 "a date object. "
2843 "pickle.load(data, encoding='latin1') is assumed.");
2844 }
2845 return NULL;
2846 }
2847 self = date_from_pickle(type, state);
2848 Py_DECREF(state);
2849 return self;
2850 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002852 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2855 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 self = new_date_ex(year, month, day, type);
2857 }
2858 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002859}
2860
Tim Peters2a799bf2002-12-16 20:18:38 +00002861static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002862date_fromtimestamp(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002863{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002864 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002865 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002866
Victor Stinnere4a994d2015-03-30 01:10:14 +02002867 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002869
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002870 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002871 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002872
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002873 return new_date_subclass_ex(tm.tm_year + 1900,
2874 tm.tm_mon + 1,
2875 tm.tm_mday,
2876 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002877}
2878
2879/* Return new date from current time.
2880 * We say this is equivalent to fromtimestamp(time.time()), and the
2881 * only way to be sure of that is to *call* time.time(). That's not
2882 * generally the same as calling C's time.
2883 */
2884static PyObject *
2885date_today(PyObject *cls, PyObject *dummy)
2886{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002887 PyObject *time;
2888 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002889 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002891 time = time_time();
2892 if (time == NULL)
2893 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002895 /* Note well: today() is a class method, so this may not call
2896 * date.fromtimestamp. For example, it may call
2897 * datetime.fromtimestamp. That's why we need all the accuracy
2898 * time.time() delivers; if someone were gonzo about optimization,
2899 * date.today() could get away with plain C time().
2900 */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02002901 result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002902 Py_DECREF(time);
2903 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002904}
2905
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002906/*[clinic input]
2907@classmethod
2908datetime.date.fromtimestamp
2909
2910 timestamp: object
2911 /
2912
2913Create a date from a POSIX timestamp.
2914
2915The timestamp is a number, e.g. created via time.time(), that is interpreted
2916as local time.
2917[clinic start generated code]*/
2918
Tim Peters2a799bf2002-12-16 20:18:38 +00002919static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002920datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp)
2921/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00002922{
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002923 return date_fromtimestamp((PyObject *) type, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002924}
2925
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04002926/* bpo-36025: This is a wrapper for API compatibility with the public C API,
2927 * which expects a function that takes an *args tuple, whereas the argument
2928 * clinic generates code that takes METH_O.
2929 */
2930static PyObject *
2931datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args)
2932{
2933 PyObject *timestamp;
2934 PyObject *result = NULL;
2935
2936 if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, &timestamp)) {
2937 result = date_fromtimestamp(cls, timestamp);
2938 }
2939
2940 return result;
2941}
2942
Tim Peters2a799bf2002-12-16 20:18:38 +00002943/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2944 * the ordinal is out of range.
2945 */
2946static PyObject *
2947date_fromordinal(PyObject *cls, PyObject *args)
2948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002949 PyObject *result = NULL;
2950 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002952 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2953 int year;
2954 int month;
2955 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002957 if (ordinal < 1)
2958 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2959 ">= 1");
2960 else {
2961 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002962 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002963 }
2964 }
2965 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002966}
2967
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002968/* Return the new date from a string as generated by date.isoformat() */
2969static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04002970date_fromisoformat(PyObject *cls, PyObject *dtstr)
2971{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002972 assert(dtstr != NULL);
2973
2974 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04002975 PyErr_SetString(PyExc_TypeError,
2976 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002977 return NULL;
2978 }
2979
2980 Py_ssize_t len;
2981
Paul Ganssle3df85402018-10-22 12:32:52 -04002982 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04002983 if (dt_ptr == NULL) {
2984 goto invalid_string_error;
2985 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002986
2987 int year = 0, month = 0, day = 0;
2988
2989 int rv;
2990 if (len == 10) {
2991 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
Paul Ganssle3df85402018-10-22 12:32:52 -04002992 }
2993 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002994 rv = -1;
2995 }
2996
2997 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04002998 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002999 }
3000
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05003001 return new_date_subclass_ex(year, month, day, cls);
Paul Ganssle096329f2018-08-23 11:06:20 -04003002
3003invalid_string_error:
Paul Ganssle3df85402018-10-22 12:32:52 -04003004 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04003005 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003006}
3007
Paul Ganssle88c09372019-04-29 09:22:03 -04003008
3009static PyObject *
3010date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw)
3011{
3012 static char *keywords[] = {
3013 "year", "week", "day", NULL
3014 };
3015
3016 int year, week, day;
3017 if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar",
3018 keywords,
3019 &year, &week, &day) == 0) {
3020 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
3021 PyErr_Format(PyExc_ValueError,
3022 "ISO calendar component out of range");
3023
3024 }
3025 return NULL;
3026 }
3027
3028 // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
3029 if (year < MINYEAR || year > MAXYEAR) {
3030 PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
3031 return NULL;
3032 }
3033
3034 if (week <= 0 || week >= 53) {
3035 int out_of_range = 1;
3036 if (week == 53) {
3037 // ISO years have 53 weeks in it on years starting with a Thursday
3038 // and on leap years starting on Wednesday
3039 int first_weekday = weekday(year, 1, 1);
3040 if (first_weekday == 3 || (first_weekday == 2 && is_leap(year))) {
3041 out_of_range = 0;
3042 }
3043 }
3044
3045 if (out_of_range) {
3046 PyErr_Format(PyExc_ValueError, "Invalid week: %d", week);
3047 return NULL;
3048 }
3049 }
3050
3051 if (day <= 0 || day >= 8) {
3052 PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])",
3053 day);
3054 return NULL;
3055 }
3056
3057 // Convert (Y, W, D) to (Y, M, D) in-place
3058 int day_1 = iso_week1_monday(year);
3059
3060 int month = week;
3061 int day_offset = (month - 1)*7 + day - 1;
3062
3063 ord_to_ymd(day_1 + day_offset, &year, &month, &day);
3064
3065 return new_date_subclass_ex(year, month, day, cls);
3066}
3067
3068
Tim Peters2a799bf2002-12-16 20:18:38 +00003069/*
3070 * Date arithmetic.
3071 */
3072
3073/* date + timedelta -> date. If arg negate is true, subtract the timedelta
3074 * instead.
3075 */
3076static PyObject *
3077add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
3078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003079 PyObject *result = NULL;
3080 int year = GET_YEAR(date);
3081 int month = GET_MONTH(date);
3082 int deltadays = GET_TD_DAYS(delta);
3083 /* C-level overflow is impossible because |deltadays| < 1e9. */
3084 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00003085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003086 if (normalize_date(&year, &month, &day) >= 0)
Paul Ganssle89427cd2019-02-04 14:42:04 -05003087 result = new_date_subclass_ex(year, month, day,
3088 (PyObject* )Py_TYPE(date));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003089 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003090}
3091
3092static PyObject *
3093date_add(PyObject *left, PyObject *right)
3094{
Brian Curtindfc80e32011-08-10 20:28:54 -05003095 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3096 Py_RETURN_NOTIMPLEMENTED;
3097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003098 if (PyDate_Check(left)) {
3099 /* date + ??? */
3100 if (PyDelta_Check(right))
3101 /* date + delta */
3102 return add_date_timedelta((PyDateTime_Date *) left,
3103 (PyDateTime_Delta *) right,
3104 0);
3105 }
3106 else {
3107 /* ??? + date
3108 * 'right' must be one of us, or we wouldn't have been called
3109 */
3110 if (PyDelta_Check(left))
3111 /* delta + date */
3112 return add_date_timedelta((PyDateTime_Date *) right,
3113 (PyDateTime_Delta *) left,
3114 0);
3115 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003116 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003117}
3118
3119static PyObject *
3120date_subtract(PyObject *left, PyObject *right)
3121{
Brian Curtindfc80e32011-08-10 20:28:54 -05003122 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3123 Py_RETURN_NOTIMPLEMENTED;
3124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 if (PyDate_Check(left)) {
3126 if (PyDate_Check(right)) {
3127 /* date - date */
3128 int left_ord = ymd_to_ord(GET_YEAR(left),
3129 GET_MONTH(left),
3130 GET_DAY(left));
3131 int right_ord = ymd_to_ord(GET_YEAR(right),
3132 GET_MONTH(right),
3133 GET_DAY(right));
3134 return new_delta(left_ord - right_ord, 0, 0, 0);
3135 }
3136 if (PyDelta_Check(right)) {
3137 /* date - delta */
3138 return add_date_timedelta((PyDateTime_Date *) left,
3139 (PyDateTime_Delta *) right,
3140 1);
3141 }
3142 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003143 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003144}
3145
3146
3147/* Various ways to turn a date into a string. */
3148
3149static PyObject *
3150date_repr(PyDateTime_Date *self)
3151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003152 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3153 Py_TYPE(self)->tp_name,
3154 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003155}
3156
3157static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303158date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003160 return PyUnicode_FromFormat("%04d-%02d-%02d",
3161 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003162}
3163
Tim Peterse2df5ff2003-05-02 18:39:55 +00003164/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003165static PyObject *
3166date_str(PyDateTime_Date *self)
3167{
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02003168 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
Tim Peters2a799bf2002-12-16 20:18:38 +00003169}
3170
3171
3172static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303173date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003175 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003176}
3177
3178static PyObject *
3179date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003181 /* This method can be inherited, and needs to call the
3182 * timetuple() method appropriate to self's class.
3183 */
3184 PyObject *result;
3185 PyObject *tuple;
3186 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003187 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003188 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003190 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3191 &format))
3192 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003193
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02003194 tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003195 if (tuple == NULL)
3196 return NULL;
3197 result = wrap_strftime((PyObject *)self, format, tuple,
3198 (PyObject *)self);
3199 Py_DECREF(tuple);
3200 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003201}
3202
Eric Smith1ba31142007-09-11 18:06:02 +00003203static PyObject *
3204date_format(PyDateTime_Date *self, PyObject *args)
3205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003206 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3209 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003211 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003212 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003213 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003214
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02003215 return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime,
3216 format);
Eric Smith1ba31142007-09-11 18:06:02 +00003217}
3218
Tim Peters2a799bf2002-12-16 20:18:38 +00003219/* ISO methods. */
3220
3221static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303222date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003224 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003226 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003227}
3228
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003229PyDoc_STRVAR(iso_calendar_date__doc__,
3230"The result of date.isocalendar() or datetime.isocalendar()\n\n\
3231This object may be accessed either as a tuple of\n\
3232 ((year, week, weekday)\n\
3233or via the object attributes as named in the above tuple.");
3234
3235typedef struct {
3236 PyTupleObject tuple;
3237} PyDateTime_IsoCalendarDate;
3238
3239static PyObject *
3240iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self)
3241{
3242 PyObject* year = PyTuple_GetItem((PyObject *)self, 0);
3243 if (year == NULL) {
3244 return NULL;
3245 }
3246 PyObject* week = PyTuple_GetItem((PyObject *)self, 1);
3247 if (week == NULL) {
3248 return NULL;
3249 }
3250 PyObject* weekday = PyTuple_GetItem((PyObject *)self, 2);
3251 if (weekday == NULL) {
3252 return NULL;
3253 }
3254
3255 return PyUnicode_FromFormat("%.200s(year=%S, week=%S, weekday=%S)",
3256 Py_TYPE(self)->tp_name, year, week, weekday);
3257}
3258
3259static PyObject *
3260iso_calendar_date_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
3261{
3262 // Construct the tuple that this reduces to
3263 PyObject * reduce_tuple = Py_BuildValue(
3264 "O((OOO))", &PyTuple_Type,
3265 PyTuple_GET_ITEM(self, 0),
3266 PyTuple_GET_ITEM(self, 1),
3267 PyTuple_GET_ITEM(self, 2)
3268 );
3269
3270 return reduce_tuple;
3271}
3272
3273static PyObject *
3274iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused)
3275{
3276 PyObject *year = PyTuple_GetItem((PyObject *)self, 0);
3277 if (year == NULL) {
3278 return NULL;
3279 }
3280 Py_INCREF(year);
3281 return year;
3282}
3283
3284static PyObject *
3285iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused)
3286{
3287 PyObject *week = PyTuple_GetItem((PyObject *)self, 1);
3288 if (week == NULL) {
3289 return NULL;
3290 }
3291 Py_INCREF(week);
3292 return week;
3293}
3294
3295static PyObject *
3296iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused)
3297{
3298 PyObject *weekday = PyTuple_GetItem((PyObject *)self, 2);
3299 if (weekday == NULL) {
3300 return NULL;
3301 }
3302 Py_INCREF(weekday);
3303 return weekday;
3304}
3305
3306static PyGetSetDef iso_calendar_date_getset[] = {
3307 {"year", (getter)iso_calendar_date_year},
3308 {"week", (getter)iso_calendar_date_week},
3309 {"weekday", (getter)iso_calendar_date_weekday},
3310 {NULL}
3311};
3312
3313static PyMethodDef iso_calendar_date_methods[] = {
3314 {"__reduce__", (PyCFunction)iso_calendar_date_reduce, METH_NOARGS,
3315 PyDoc_STR("__reduce__() -> (cls, state)")},
3316 {NULL, NULL},
3317};
3318
3319static PyTypeObject PyDateTime_IsoCalendarDateType = {
3320 PyVarObject_HEAD_INIT(NULL, 0)
3321 .tp_name = "datetime.IsoCalendarDate",
3322 .tp_basicsize = sizeof(PyDateTime_IsoCalendarDate),
3323 .tp_repr = (reprfunc) iso_calendar_date_repr,
3324 .tp_flags = Py_TPFLAGS_DEFAULT,
3325 .tp_doc = iso_calendar_date__doc__,
3326 .tp_methods = iso_calendar_date_methods,
3327 .tp_getset = iso_calendar_date_getset,
Miss Islington (bot)eceee542020-05-28 09:41:41 -07003328 // .tp_base = &PyTuple_Type, // filled in PyInit__datetime
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003329 .tp_new = iso_calendar_date_new,
3330};
3331
3332/*[clinic input]
3333@classmethod
3334datetime.IsoCalendarDate.__new__ as iso_calendar_date_new
3335 year: int
3336 week: int
3337 weekday: int
3338[clinic start generated code]*/
3339
3340static PyObject *
3341iso_calendar_date_new_impl(PyTypeObject *type, int year, int week,
3342 int weekday)
3343/*[clinic end generated code: output=383d33d8dc7183a2 input=4f2c663c9d19c4ee]*/
3344
3345{
3346 PyDateTime_IsoCalendarDate *self;
3347 self = (PyDateTime_IsoCalendarDate *) type->tp_alloc(type, 3);
3348 if (self == NULL) {
3349 return NULL;
3350 }
3351
3352 PyTuple_SET_ITEM(self, 0, PyLong_FromLong(year));
3353 PyTuple_SET_ITEM(self, 1, PyLong_FromLong(week));
3354 PyTuple_SET_ITEM(self, 2, PyLong_FromLong(weekday));
3355
3356 return (PyObject *)self;
3357}
3358
Tim Peters2a799bf2002-12-16 20:18:38 +00003359static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303360date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003362 int year = GET_YEAR(self);
3363 int week1_monday = iso_week1_monday(year);
3364 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3365 int week;
3366 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003368 week = divmod(today - week1_monday, 7, &day);
3369 if (week < 0) {
3370 --year;
3371 week1_monday = iso_week1_monday(year);
3372 week = divmod(today - week1_monday, 7, &day);
3373 }
3374 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3375 ++year;
3376 week = 0;
3377 }
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003378
3379 PyObject* v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType,
3380 year, week + 1, day + 1);
3381 if (v == NULL) {
3382 return NULL;
3383 }
3384 return v;
Tim Peters2a799bf2002-12-16 20:18:38 +00003385}
3386
3387/* Miscellaneous methods. */
3388
Tim Peters2a799bf2002-12-16 20:18:38 +00003389static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003390date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003392 if (PyDate_Check(other)) {
3393 int diff = memcmp(((PyDateTime_Date *)self)->data,
3394 ((PyDateTime_Date *)other)->data,
3395 _PyDateTime_DATE_DATASIZE);
3396 return diff_to_bool(diff, op);
3397 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003398 else
3399 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003400}
3401
3402static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303403date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003405 return build_struct_time(GET_YEAR(self),
3406 GET_MONTH(self),
3407 GET_DAY(self),
3408 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003409}
3410
Tim Peters12bf3392002-12-24 05:41:27 +00003411static PyObject *
3412date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003414 PyObject *clone;
3415 PyObject *tuple;
3416 int year = GET_YEAR(self);
3417 int month = GET_MONTH(self);
3418 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003420 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3421 &year, &month, &day))
3422 return NULL;
3423 tuple = Py_BuildValue("iii", year, month, day);
3424 if (tuple == NULL)
3425 return NULL;
3426 clone = date_new(Py_TYPE(self), tuple, NULL);
3427 Py_DECREF(tuple);
3428 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003429}
3430
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003431static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003432generic_hash(unsigned char *data, int len)
3433{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003434 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003435}
3436
3437
3438static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003439
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003440static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003441date_hash(PyDateTime_Date *self)
3442{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003443 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003444 self->hashcode = generic_hash(
3445 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003446 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003448 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003449}
3450
3451static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303452date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003454 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3455 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003456}
3457
3458static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303459date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003461 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003463 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003464}
3465
Tim Peters371935f2003-02-01 01:52:50 +00003466/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003467
Tim Petersb57f8f02003-02-01 02:54:15 +00003468/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003469static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003470date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003472 PyObject* field;
3473 field = PyBytes_FromStringAndSize((char*)self->data,
3474 _PyDateTime_DATE_DATASIZE);
3475 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003476}
3477
3478static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003479date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003480{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003481 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003482}
3483
3484static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003486 /* Class methods: */
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02003487 DATETIME_DATE_FROMTIMESTAMP_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00003488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3490 METH_CLASS,
3491 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3492 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003493
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003494 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3495 METH_CLASS,
3496 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3497
Paul Ganssle88c09372019-04-29 09:22:03 -04003498 {"fromisocalendar", (PyCFunction)(void(*)(void))date_fromisocalendar,
3499 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
3500 PyDoc_STR("int, int, int -> Construct a date from the ISO year, week "
3501 "number and weekday.\n\n"
3502 "This is the inverse of the date.isocalendar() function")},
3503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003504 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3505 PyDoc_STR("Current date or datetime: same as "
3506 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003510 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3511 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003512
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003513 {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003514 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003516 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3517 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003519 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3520 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003522 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003523 PyDoc_STR("Return a named tuple containing ISO year, week number, and "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003524 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003526 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3527 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003529 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3530 PyDoc_STR("Return the day of the week represented by the date.\n"
3531 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003533 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3534 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3535 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003537 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3538 PyDoc_STR("Return the day of the week represented by the date.\n"
3539 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003540
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003541 {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003542 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003544 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3545 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003547 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003548};
3549
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003550static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003551PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003552
3553static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003554 date_add, /* nb_add */
3555 date_subtract, /* nb_subtract */
3556 0, /* nb_multiply */
3557 0, /* nb_remainder */
3558 0, /* nb_divmod */
3559 0, /* nb_power */
3560 0, /* nb_negative */
3561 0, /* nb_positive */
3562 0, /* nb_absolute */
3563 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003564};
3565
3566static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003567 PyVarObject_HEAD_INIT(NULL, 0)
3568 "datetime.date", /* tp_name */
3569 sizeof(PyDateTime_Date), /* tp_basicsize */
3570 0, /* tp_itemsize */
3571 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003572 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003573 0, /* tp_getattr */
3574 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003575 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003576 (reprfunc)date_repr, /* tp_repr */
3577 &date_as_number, /* tp_as_number */
3578 0, /* tp_as_sequence */
3579 0, /* tp_as_mapping */
3580 (hashfunc)date_hash, /* tp_hash */
3581 0, /* tp_call */
3582 (reprfunc)date_str, /* tp_str */
3583 PyObject_GenericGetAttr, /* tp_getattro */
3584 0, /* tp_setattro */
3585 0, /* tp_as_buffer */
3586 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3587 date_doc, /* tp_doc */
3588 0, /* tp_traverse */
3589 0, /* tp_clear */
3590 date_richcompare, /* tp_richcompare */
3591 0, /* tp_weaklistoffset */
3592 0, /* tp_iter */
3593 0, /* tp_iternext */
3594 date_methods, /* tp_methods */
3595 0, /* tp_members */
3596 date_getset, /* tp_getset */
3597 0, /* tp_base */
3598 0, /* tp_dict */
3599 0, /* tp_descr_get */
3600 0, /* tp_descr_set */
3601 0, /* tp_dictoffset */
3602 0, /* tp_init */
3603 0, /* tp_alloc */
3604 date_new, /* tp_new */
3605 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003606};
3607
3608/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003609 * PyDateTime_TZInfo implementation.
3610 */
3611
3612/* This is a pure abstract base class, so doesn't do anything beyond
3613 * raising NotImplemented exceptions. Real tzinfo classes need
3614 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003615 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003616 * be subclasses of this tzinfo class, which is easy and quick to check).
3617 *
3618 * Note: For reasons having to do with pickling of subclasses, we have
3619 * to allow tzinfo objects to be instantiated. This wasn't an issue
3620 * in the Python implementation (__init__() could raise NotImplementedError
3621 * there without ill effect), but doing so in the C implementation hit a
3622 * brick wall.
3623 */
3624
3625static PyObject *
3626tzinfo_nogo(const char* methodname)
3627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003628 PyErr_Format(PyExc_NotImplementedError,
3629 "a tzinfo subclass must implement %s()",
3630 methodname);
3631 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003632}
3633
3634/* Methods. A subclass must implement these. */
3635
Tim Peters52dcce22003-01-23 16:36:11 +00003636static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003637tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003639 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003640}
3641
Tim Peters52dcce22003-01-23 16:36:11 +00003642static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003643tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003645 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003646}
3647
Tim Peters52dcce22003-01-23 16:36:11 +00003648static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003649tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3650{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003651 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003652}
3653
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003654
3655static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3656 PyDateTime_Delta *delta,
3657 int factor);
3658static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3659static PyObject *datetime_dst(PyObject *self, PyObject *);
3660
Tim Peters52dcce22003-01-23 16:36:11 +00003661static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003662tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003663{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003664 PyObject *result = NULL;
3665 PyObject *off = NULL, *dst = NULL;
3666 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003667
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003668 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003669 PyErr_SetString(PyExc_TypeError,
3670 "fromutc: argument must be a datetime");
3671 return NULL;
3672 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003673 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003674 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3675 "is not self");
3676 return NULL;
3677 }
Tim Peters52dcce22003-01-23 16:36:11 +00003678
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003679 off = datetime_utcoffset(dt, NULL);
3680 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003681 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003682 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003683 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3684 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003685 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003686 }
Tim Peters52dcce22003-01-23 16:36:11 +00003687
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003688 dst = datetime_dst(dt, NULL);
3689 if (dst == NULL)
3690 goto Fail;
3691 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003692 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3693 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003694 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003695 }
Tim Peters52dcce22003-01-23 16:36:11 +00003696
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003697 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3698 if (delta == NULL)
3699 goto Fail;
3700 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003701 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003702 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003703
3704 Py_DECREF(dst);
3705 dst = call_dst(GET_DT_TZINFO(dt), result);
3706 if (dst == NULL)
3707 goto Fail;
3708 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003709 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003710 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003711 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003712 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003713 if (result == NULL)
3714 goto Fail;
3715 }
3716 Py_DECREF(delta);
3717 Py_DECREF(dst);
3718 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003719 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003720
3721Inconsistent:
Serhiy Storchaka34fd4c22018-11-05 16:20:25 +02003722 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003723 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003724
Leo Ariasc3d95082018-02-03 18:36:10 -06003725 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003726Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003727 Py_XDECREF(off);
3728 Py_XDECREF(dst);
3729 Py_XDECREF(delta);
3730 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003731 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003732}
3733
Tim Peters2a799bf2002-12-16 20:18:38 +00003734/*
3735 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003736 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003737 */
3738
Guido van Rossum177e41a2003-01-30 22:06:23 +00003739static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303740tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003741{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003742 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003743 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003744 _Py_IDENTIFIER(__getinitargs__);
3745 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003746
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003747 if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) {
3748 return NULL;
3749 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003750 if (getinitargs != NULL) {
Victor Stinner2ff58a22019-06-17 14:27:23 +02003751 args = PyObject_CallNoArgs(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003752 Py_DECREF(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003753 }
3754 else {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003755 args = PyTuple_New(0);
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003756 }
3757 if (args == NULL) {
3758 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003759 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003760
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003761 if (_PyObject_LookupAttrId(self, &PyId___getstate__, &getstate) < 0) {
3762 Py_DECREF(args);
3763 return NULL;
3764 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003765 if (getstate != NULL) {
Victor Stinner2ff58a22019-06-17 14:27:23 +02003766 state = PyObject_CallNoArgs(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003767 Py_DECREF(getstate);
3768 if (state == NULL) {
3769 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003770 return NULL;
3771 }
3772 }
3773 else {
3774 PyObject **dictptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003775 state = Py_None;
3776 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003777 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003778 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003779 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003780 Py_INCREF(state);
3781 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003783 if (state == Py_None) {
3784 Py_DECREF(state);
3785 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3786 }
3787 else
3788 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003789}
Tim Peters2a799bf2002-12-16 20:18:38 +00003790
3791static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003793 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3794 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003796 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003797 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3798 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003800 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003801 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003803 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003804 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003805
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303806 {"__reduce__", tzinfo_reduce, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003807 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003809 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003810};
3811
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003812static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003813PyDoc_STR("Abstract base class for time zone info objects.");
3814
Neal Norwitz227b5332006-03-22 09:28:35 +00003815static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003816 PyVarObject_HEAD_INIT(NULL, 0)
3817 "datetime.tzinfo", /* tp_name */
3818 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3819 0, /* tp_itemsize */
3820 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003821 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003822 0, /* tp_getattr */
3823 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003824 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003825 0, /* tp_repr */
3826 0, /* tp_as_number */
3827 0, /* tp_as_sequence */
3828 0, /* tp_as_mapping */
3829 0, /* tp_hash */
3830 0, /* tp_call */
3831 0, /* tp_str */
3832 PyObject_GenericGetAttr, /* tp_getattro */
3833 0, /* tp_setattro */
3834 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003835 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003836 tzinfo_doc, /* tp_doc */
3837 0, /* tp_traverse */
3838 0, /* tp_clear */
3839 0, /* tp_richcompare */
3840 0, /* tp_weaklistoffset */
3841 0, /* tp_iter */
3842 0, /* tp_iternext */
3843 tzinfo_methods, /* tp_methods */
3844 0, /* tp_members */
3845 0, /* tp_getset */
3846 0, /* tp_base */
3847 0, /* tp_dict */
3848 0, /* tp_descr_get */
3849 0, /* tp_descr_set */
3850 0, /* tp_dictoffset */
3851 0, /* tp_init */
3852 0, /* tp_alloc */
3853 PyType_GenericNew, /* tp_new */
3854 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003855};
3856
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003857static char *timezone_kws[] = {"offset", "name", NULL};
3858
3859static PyObject *
3860timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3861{
3862 PyObject *offset;
3863 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003864 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3865 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003866 return new_timezone(offset, name);
3867
3868 return NULL;
3869}
3870
3871static void
3872timezone_dealloc(PyDateTime_TimeZone *self)
3873{
3874 Py_CLEAR(self->offset);
3875 Py_CLEAR(self->name);
3876 Py_TYPE(self)->tp_free((PyObject *)self);
3877}
3878
3879static PyObject *
3880timezone_richcompare(PyDateTime_TimeZone *self,
3881 PyDateTime_TimeZone *other, int op)
3882{
Brian Curtindfc80e32011-08-10 20:28:54 -05003883 if (op != Py_EQ && op != Py_NE)
3884 Py_RETURN_NOTIMPLEMENTED;
Pablo Galindo4be11c02019-08-22 20:24:25 +01003885 if (!PyTimezone_Check(other)) {
Serhiy Storchaka17e52642019-08-04 12:38:46 +03003886 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003887 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003888 return delta_richcompare(self->offset, other->offset, op);
3889}
3890
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003891static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003892timezone_hash(PyDateTime_TimeZone *self)
3893{
3894 return delta_hash((PyDateTime_Delta *)self->offset);
3895}
3896
3897/* Check argument type passed to tzname, utcoffset, or dst methods.
3898 Returns 0 for good argument. Returns -1 and sets exception info
3899 otherwise.
3900 */
3901static int
3902_timezone_check_argument(PyObject *dt, const char *meth)
3903{
3904 if (dt == Py_None || PyDateTime_Check(dt))
3905 return 0;
3906 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3907 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3908 return -1;
3909}
3910
3911static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003912timezone_repr(PyDateTime_TimeZone *self)
3913{
3914 /* Note that although timezone is not subclassable, it is convenient
3915 to use Py_TYPE(self)->tp_name here. */
3916 const char *type_name = Py_TYPE(self)->tp_name;
3917
3918 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3919 return PyUnicode_FromFormat("%s.utc", type_name);
3920
3921 if (self->name == NULL)
3922 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3923
3924 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3925 self->name);
3926}
3927
3928
3929static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003930timezone_str(PyDateTime_TimeZone *self)
3931{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003932 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003933 PyObject *offset;
3934 char sign;
3935
3936 if (self->name != NULL) {
3937 Py_INCREF(self->name);
3938 return self->name;
3939 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003940 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003941 (GET_TD_DAYS(self->offset) == 0 &&
3942 GET_TD_SECONDS(self->offset) == 0 &&
3943 GET_TD_MICROSECONDS(self->offset) == 0))
3944 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003945 /* Offset is normalized, so it is negative if days < 0 */
3946 if (GET_TD_DAYS(self->offset) < 0) {
3947 sign = '-';
3948 offset = delta_negative((PyDateTime_Delta *)self->offset);
3949 if (offset == NULL)
3950 return NULL;
3951 }
3952 else {
3953 sign = '+';
3954 offset = self->offset;
3955 Py_INCREF(offset);
3956 }
3957 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003958 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003959 seconds = GET_TD_SECONDS(offset);
3960 Py_DECREF(offset);
3961 minutes = divmod(seconds, 60, &seconds);
3962 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003963 if (microseconds != 0) {
3964 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3965 sign, hours, minutes,
3966 seconds, microseconds);
3967 }
3968 if (seconds != 0) {
3969 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3970 sign, hours, minutes, seconds);
3971 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003972 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003973}
3974
3975static PyObject *
3976timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3977{
3978 if (_timezone_check_argument(dt, "tzname") == -1)
3979 return NULL;
3980
3981 return timezone_str(self);
3982}
3983
3984static PyObject *
3985timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3986{
3987 if (_timezone_check_argument(dt, "utcoffset") == -1)
3988 return NULL;
3989
3990 Py_INCREF(self->offset);
3991 return self->offset;
3992}
3993
3994static PyObject *
3995timezone_dst(PyObject *self, PyObject *dt)
3996{
3997 if (_timezone_check_argument(dt, "dst") == -1)
3998 return NULL;
3999
4000 Py_RETURN_NONE;
4001}
4002
4003static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004004timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
4005{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004006 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004007 PyErr_SetString(PyExc_TypeError,
4008 "fromutc: argument must be a datetime");
4009 return NULL;
4010 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004011 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004012 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
4013 "is not self");
4014 return NULL;
4015 }
4016
4017 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
4018}
4019
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00004020static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304021timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00004022{
4023 if (self->name == NULL)
4024 return Py_BuildValue("(O)", self->offset);
4025 return Py_BuildValue("(OO)", self->offset, self->name);
4026}
4027
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004028static PyMethodDef timezone_methods[] = {
4029 {"tzname", (PyCFunction)timezone_tzname, METH_O,
4030 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00004031 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004032
4033 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00004034 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004035
4036 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00004037 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004038
4039 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
4040 PyDoc_STR("datetime in UTC -> datetime in local time.")},
4041
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00004042 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
4043 PyDoc_STR("pickle support")},
4044
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004045 {NULL, NULL}
4046};
4047
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004048static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004049PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
4050
4051static PyTypeObject PyDateTime_TimeZoneType = {
4052 PyVarObject_HEAD_INIT(NULL, 0)
4053 "datetime.timezone", /* tp_name */
4054 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
4055 0, /* tp_itemsize */
4056 (destructor)timezone_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004057 0, /* tp_vectorcall_offset */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004058 0, /* tp_getattr */
4059 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004060 0, /* tp_as_async */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00004061 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004062 0, /* tp_as_number */
4063 0, /* tp_as_sequence */
4064 0, /* tp_as_mapping */
4065 (hashfunc)timezone_hash, /* tp_hash */
4066 0, /* tp_call */
4067 (reprfunc)timezone_str, /* tp_str */
4068 0, /* tp_getattro */
4069 0, /* tp_setattro */
4070 0, /* tp_as_buffer */
4071 Py_TPFLAGS_DEFAULT, /* tp_flags */
4072 timezone_doc, /* tp_doc */
4073 0, /* tp_traverse */
4074 0, /* tp_clear */
4075 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
4076 0, /* tp_weaklistoffset */
4077 0, /* tp_iter */
4078 0, /* tp_iternext */
4079 timezone_methods, /* tp_methods */
4080 0, /* tp_members */
4081 0, /* tp_getset */
Miss Islington (bot)eceee542020-05-28 09:41:41 -07004082 0, /* tp_base; filled in PyInit__datetime */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004083 0, /* tp_dict */
4084 0, /* tp_descr_get */
4085 0, /* tp_descr_set */
4086 0, /* tp_dictoffset */
4087 0, /* tp_init */
4088 0, /* tp_alloc */
4089 timezone_new, /* tp_new */
4090};
4091
Tim Peters2a799bf2002-12-16 20:18:38 +00004092/*
Tim Peters37f39822003-01-10 03:49:02 +00004093 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004094 */
4095
Tim Peters37f39822003-01-10 03:49:02 +00004096/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00004097 */
4098
4099static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004100time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004103}
4104
Tim Peters37f39822003-01-10 03:49:02 +00004105static PyObject *
4106time_minute(PyDateTime_Time *self, void *unused)
4107{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004108 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00004109}
4110
4111/* The name time_second conflicted with some platform header file. */
4112static PyObject *
4113py_time_second(PyDateTime_Time *self, void *unused)
4114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004115 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00004116}
4117
4118static PyObject *
4119time_microsecond(PyDateTime_Time *self, void *unused)
4120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004121 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00004122}
4123
4124static PyObject *
4125time_tzinfo(PyDateTime_Time *self, void *unused)
4126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004127 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4128 Py_INCREF(result);
4129 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004130}
4131
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004132static PyObject *
4133time_fold(PyDateTime_Time *self, void *unused)
4134{
4135 return PyLong_FromLong(TIME_GET_FOLD(self));
4136}
4137
Tim Peters37f39822003-01-10 03:49:02 +00004138static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004139 {"hour", (getter)time_hour},
4140 {"minute", (getter)time_minute},
4141 {"second", (getter)py_time_second},
4142 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004143 {"tzinfo", (getter)time_tzinfo},
4144 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004145 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004146};
4147
4148/*
4149 * Constructors.
4150 */
4151
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004152static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004153 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00004154
Tim Peters2a799bf2002-12-16 20:18:38 +00004155static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004156time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4157{
4158 PyDateTime_Time *me;
4159 char aware = (char)(tzinfo != Py_None);
4160
4161 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4162 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4163 return NULL;
4164 }
4165
4166 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
4167 if (me != NULL) {
4168 const char *pdata = PyBytes_AS_STRING(state);
4169
4170 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
4171 me->hashcode = -1;
4172 me->hastzinfo = aware;
4173 if (aware) {
4174 Py_INCREF(tzinfo);
4175 me->tzinfo = tzinfo;
4176 }
4177 if (pdata[0] & (1 << 7)) {
4178 me->data[0] -= 128;
4179 me->fold = 1;
4180 }
4181 else {
4182 me->fold = 0;
4183 }
4184 }
4185 return (PyObject *)me;
4186}
4187
4188static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004189time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004190{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004192 int hour = 0;
4193 int minute = 0;
4194 int second = 0;
4195 int usecond = 0;
4196 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004197 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004199 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004200 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4201 PyObject *state = PyTuple_GET_ITEM(args, 0);
4202 if (PyTuple_GET_SIZE(args) == 2) {
4203 tzinfo = PyTuple_GET_ITEM(args, 1);
4204 }
4205 if (PyBytes_Check(state)) {
4206 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
4207 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
4208 {
4209 return time_from_pickle(type, state, tzinfo);
4210 }
4211 }
4212 else if (PyUnicode_Check(state)) {
4213 if (PyUnicode_READY(state)) {
4214 return NULL;
4215 }
4216 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
Justin Blanchard122376d2019-08-29 03:36:15 -04004217 (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24)
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004218 {
4219 state = PyUnicode_AsLatin1String(state);
4220 if (state == NULL) {
4221 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4222 /* More informative error message. */
4223 PyErr_SetString(PyExc_ValueError,
4224 "Failed to encode latin1 string when unpickling "
4225 "a time object. "
4226 "pickle.load(data, encoding='latin1') is assumed.");
4227 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004228 return NULL;
4229 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004230 self = time_from_pickle(type, state, tzinfo);
4231 Py_DECREF(state);
4232 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004233 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004235 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004236 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004237
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004238 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004239 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004240 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004241 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4242 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004243 }
4244 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004245}
4246
4247/*
4248 * Destructor.
4249 */
4250
4251static void
Tim Peters37f39822003-01-10 03:49:02 +00004252time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004253{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004254 if (HASTZINFO(self)) {
4255 Py_XDECREF(self->tzinfo);
4256 }
4257 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004258}
4259
4260/*
Tim Peters855fe882002-12-22 03:43:39 +00004261 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004262 */
4263
Tim Peters2a799bf2002-12-16 20:18:38 +00004264/* These are all METH_NOARGS, so don't need to check the arglist. */
4265static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004266time_utcoffset(PyObject *self, PyObject *unused) {
4267 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004268}
4269
4270static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004271time_dst(PyObject *self, PyObject *unused) {
4272 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004273}
4274
4275static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004276time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004277 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004278}
4279
4280/*
Tim Peters37f39822003-01-10 03:49:02 +00004281 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004282 */
4283
4284static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004285time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004286{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004287 const char *type_name = Py_TYPE(self)->tp_name;
4288 int h = TIME_GET_HOUR(self);
4289 int m = TIME_GET_MINUTE(self);
4290 int s = TIME_GET_SECOND(self);
4291 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004292 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004293 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004295 if (us)
4296 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4297 type_name, h, m, s, us);
4298 else if (s)
4299 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4300 type_name, h, m, s);
4301 else
4302 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4303 if (result != NULL && HASTZINFO(self))
4304 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004305 if (result != NULL && fold)
4306 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004307 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004308}
4309
Tim Peters37f39822003-01-10 03:49:02 +00004310static PyObject *
4311time_str(PyDateTime_Time *self)
4312{
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02004313 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
Tim Peters37f39822003-01-10 03:49:02 +00004314}
Tim Peters2a799bf2002-12-16 20:18:38 +00004315
4316static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004317time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004319 char buf[100];
Andy Lesterc3fa6342020-02-24 00:40:43 -06004320 const char *timespec = NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004321 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004322 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004323 int us = TIME_GET_MICROSECOND(self);
Andy Lesterc3fa6342020-02-24 00:40:43 -06004324 static const char *specs[][2] = {
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004325 {"hours", "%02d"},
4326 {"minutes", "%02d:%02d"},
4327 {"seconds", "%02d:%02d:%02d"},
4328 {"milliseconds", "%02d:%02d:%02d.%03d"},
4329 {"microseconds", "%02d:%02d:%02d.%06d"},
4330 };
4331 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004332
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004333 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4334 return NULL;
4335
4336 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4337 if (us == 0) {
4338 /* seconds */
4339 given_spec = 2;
4340 }
4341 else {
4342 /* microseconds */
4343 given_spec = 4;
4344 }
4345 }
4346 else {
4347 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4348 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4349 if (given_spec == 3) {
4350 /* milliseconds */
4351 us = us / 1000;
4352 }
4353 break;
4354 }
4355 }
4356 }
4357
4358 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4359 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4360 return NULL;
4361 }
4362 else {
4363 result = PyUnicode_FromFormat(specs[given_spec][1],
4364 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4365 TIME_GET_SECOND(self), us);
4366 }
Tim Peters37f39822003-01-10 03:49:02 +00004367
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004368 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004369 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004371 /* We need to append the UTC offset. */
4372 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4373 Py_None) < 0) {
4374 Py_DECREF(result);
4375 return NULL;
4376 }
4377 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4378 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004379}
4380
Tim Peters37f39822003-01-10 03:49:02 +00004381static PyObject *
4382time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 PyObject *result;
4385 PyObject *tuple;
4386 PyObject *format;
4387 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004389 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4390 &format))
4391 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004393 /* Python's strftime does insane things with the year part of the
4394 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004395 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004396 */
4397 tuple = Py_BuildValue("iiiiiiiii",
4398 1900, 1, 1, /* year, month, day */
4399 TIME_GET_HOUR(self),
4400 TIME_GET_MINUTE(self),
4401 TIME_GET_SECOND(self),
4402 0, 1, -1); /* weekday, daynum, dst */
4403 if (tuple == NULL)
4404 return NULL;
4405 assert(PyTuple_Size(tuple) == 9);
4406 result = wrap_strftime((PyObject *)self, format, tuple,
4407 Py_None);
4408 Py_DECREF(tuple);
4409 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004410}
Tim Peters2a799bf2002-12-16 20:18:38 +00004411
4412/*
4413 * Miscellaneous methods.
4414 */
4415
Tim Peters37f39822003-01-10 03:49:02 +00004416static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004417time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004418{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004419 PyObject *result = NULL;
4420 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004421 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004422
Brian Curtindfc80e32011-08-10 20:28:54 -05004423 if (! PyTime_Check(other))
4424 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004425
4426 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004427 diff = memcmp(((PyDateTime_Time *)self)->data,
4428 ((PyDateTime_Time *)other)->data,
4429 _PyDateTime_TIME_DATASIZE);
4430 return diff_to_bool(diff, op);
4431 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004432 offset1 = time_utcoffset(self, NULL);
4433 if (offset1 == NULL)
4434 return NULL;
4435 offset2 = time_utcoffset(other, NULL);
4436 if (offset2 == NULL)
4437 goto done;
4438 /* If they're both naive, or both aware and have the same offsets,
4439 * we get off cheap. Note that if they're both naive, offset1 ==
4440 * offset2 == Py_None at this point.
4441 */
4442 if ((offset1 == offset2) ||
4443 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4444 delta_cmp(offset1, offset2) == 0)) {
4445 diff = memcmp(((PyDateTime_Time *)self)->data,
4446 ((PyDateTime_Time *)other)->data,
4447 _PyDateTime_TIME_DATASIZE);
4448 result = diff_to_bool(diff, op);
4449 }
4450 /* The hard case: both aware with different UTC offsets */
4451 else if (offset1 != Py_None && offset2 != Py_None) {
4452 int offsecs1, offsecs2;
4453 assert(offset1 != offset2); /* else last "if" handled it */
4454 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4455 TIME_GET_MINUTE(self) * 60 +
4456 TIME_GET_SECOND(self) -
4457 GET_TD_DAYS(offset1) * 86400 -
4458 GET_TD_SECONDS(offset1);
4459 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4460 TIME_GET_MINUTE(other) * 60 +
4461 TIME_GET_SECOND(other) -
4462 GET_TD_DAYS(offset2) * 86400 -
4463 GET_TD_SECONDS(offset2);
4464 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004465 if (diff == 0)
4466 diff = TIME_GET_MICROSECOND(self) -
4467 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004468 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004469 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004470 else if (op == Py_EQ) {
4471 result = Py_False;
4472 Py_INCREF(result);
4473 }
4474 else if (op == Py_NE) {
4475 result = Py_True;
4476 Py_INCREF(result);
4477 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004478 else {
4479 PyErr_SetString(PyExc_TypeError,
4480 "can't compare offset-naive and "
4481 "offset-aware times");
4482 }
4483 done:
4484 Py_DECREF(offset1);
4485 Py_XDECREF(offset2);
4486 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004487}
4488
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004489static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004490time_hash(PyDateTime_Time *self)
4491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004492 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004493 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004494 if (TIME_GET_FOLD(self)) {
4495 self0 = new_time_ex2(TIME_GET_HOUR(self),
4496 TIME_GET_MINUTE(self),
4497 TIME_GET_SECOND(self),
4498 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004499 HASTZINFO(self) ? self->tzinfo : Py_None,
4500 0, Py_TYPE(self));
4501 if (self0 == NULL)
4502 return -1;
4503 }
4504 else {
4505 self0 = (PyObject *)self;
4506 Py_INCREF(self0);
4507 }
4508 offset = time_utcoffset(self0, NULL);
4509 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004510
4511 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004512 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004514 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004515 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004516 self->hashcode = generic_hash(
4517 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004518 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004519 PyObject *temp1, *temp2;
4520 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004521 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004522 seconds = TIME_GET_HOUR(self) * 3600 +
4523 TIME_GET_MINUTE(self) * 60 +
4524 TIME_GET_SECOND(self);
4525 microseconds = TIME_GET_MICROSECOND(self);
4526 temp1 = new_delta(0, seconds, microseconds, 1);
4527 if (temp1 == NULL) {
4528 Py_DECREF(offset);
4529 return -1;
4530 }
4531 temp2 = delta_subtract(temp1, offset);
4532 Py_DECREF(temp1);
4533 if (temp2 == NULL) {
4534 Py_DECREF(offset);
4535 return -1;
4536 }
4537 self->hashcode = PyObject_Hash(temp2);
4538 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004539 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004540 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004541 }
4542 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004543}
Tim Peters2a799bf2002-12-16 20:18:38 +00004544
Tim Peters12bf3392002-12-24 05:41:27 +00004545static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004546time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004548 PyObject *clone;
4549 PyObject *tuple;
4550 int hh = TIME_GET_HOUR(self);
4551 int mm = TIME_GET_MINUTE(self);
4552 int ss = TIME_GET_SECOND(self);
4553 int us = TIME_GET_MICROSECOND(self);
4554 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004555 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004556
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004557 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004558 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004559 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004560 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004561 if (fold != 0 && fold != 1) {
4562 PyErr_SetString(PyExc_ValueError,
4563 "fold must be either 0 or 1");
4564 return NULL;
4565 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004566 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4567 if (tuple == NULL)
4568 return NULL;
4569 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004570 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004571 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004572 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 Py_DECREF(tuple);
4574 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004575}
4576
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004577static PyObject *
4578time_fromisoformat(PyObject *cls, PyObject *tstr) {
4579 assert(tstr != NULL);
4580
4581 if (!PyUnicode_Check(tstr)) {
4582 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4583 return NULL;
4584 }
4585
4586 Py_ssize_t len;
4587 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4588
Paul Ganssle096329f2018-08-23 11:06:20 -04004589 if (p == NULL) {
4590 goto invalid_string_error;
4591 }
4592
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004593 int hour = 0, minute = 0, second = 0, microsecond = 0;
4594 int tzoffset, tzimicrosecond = 0;
4595 int rv = parse_isoformat_time(p, len,
4596 &hour, &minute, &second, &microsecond,
4597 &tzoffset, &tzimicrosecond);
4598
4599 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04004600 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004601 }
4602
4603 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4604 tzimicrosecond);
4605
4606 if (tzinfo == NULL) {
4607 return NULL;
4608 }
4609
4610 PyObject *t;
4611 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4612 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4613 } else {
4614 t = PyObject_CallFunction(cls, "iiiiO",
4615 hour, minute, second, microsecond, tzinfo);
4616 }
4617
4618 Py_DECREF(tzinfo);
4619 return t;
Paul Ganssle096329f2018-08-23 11:06:20 -04004620
4621invalid_string_error:
4622 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4623 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004624}
4625
4626
Tim Peters371935f2003-02-01 01:52:50 +00004627/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004628
Tim Peters33e0f382003-01-10 02:05:14 +00004629/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004630 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4631 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004632 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004633 */
4634static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004635time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004636{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004637 PyObject *basestate;
4638 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004640 basestate = PyBytes_FromStringAndSize((char *)self->data,
4641 _PyDateTime_TIME_DATASIZE);
4642 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004643 if (proto > 3 && TIME_GET_FOLD(self))
4644 /* Set the first bit of the first byte */
4645 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004646 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4647 result = PyTuple_Pack(1, basestate);
4648 else
4649 result = PyTuple_Pack(2, basestate, self->tzinfo);
4650 Py_DECREF(basestate);
4651 }
4652 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004653}
4654
4655static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004656time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004657{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004658 int proto;
4659 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004660 return NULL;
4661
4662 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004663}
4664
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004665static PyObject *
4666time_reduce(PyDateTime_Time *self, PyObject *arg)
4667{
4668 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4669}
4670
Tim Peters37f39822003-01-10 03:49:02 +00004671static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004672
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004673 {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS,
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004674 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4675 "[+HH:MM].\n\n"
4676 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004677
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004678 {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004679 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4682 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004684 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4685 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004687 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4688 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004690 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4691 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004692
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004693 {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004694 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004695
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004696 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4697 PyDoc_STR("string -> time from time.isoformat() output")},
4698
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004699 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004700 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004701
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004702 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4703 PyDoc_STR("__reduce__() -> (cls, state)")},
4704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004705 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004706};
4707
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004708static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004709PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4710\n\
4711All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004712a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004713
Neal Norwitz227b5332006-03-22 09:28:35 +00004714static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004715 PyVarObject_HEAD_INIT(NULL, 0)
4716 "datetime.time", /* tp_name */
4717 sizeof(PyDateTime_Time), /* tp_basicsize */
4718 0, /* tp_itemsize */
4719 (destructor)time_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004720 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004721 0, /* tp_getattr */
4722 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004723 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004724 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004725 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004726 0, /* tp_as_sequence */
4727 0, /* tp_as_mapping */
4728 (hashfunc)time_hash, /* tp_hash */
4729 0, /* tp_call */
4730 (reprfunc)time_str, /* tp_str */
4731 PyObject_GenericGetAttr, /* tp_getattro */
4732 0, /* tp_setattro */
4733 0, /* tp_as_buffer */
4734 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4735 time_doc, /* tp_doc */
4736 0, /* tp_traverse */
4737 0, /* tp_clear */
4738 time_richcompare, /* tp_richcompare */
4739 0, /* tp_weaklistoffset */
4740 0, /* tp_iter */
4741 0, /* tp_iternext */
4742 time_methods, /* tp_methods */
4743 0, /* tp_members */
4744 time_getset, /* tp_getset */
4745 0, /* tp_base */
4746 0, /* tp_dict */
4747 0, /* tp_descr_get */
4748 0, /* tp_descr_set */
4749 0, /* tp_dictoffset */
4750 0, /* tp_init */
4751 time_alloc, /* tp_alloc */
4752 time_new, /* tp_new */
4753 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004754};
4755
4756/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004757 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004758 */
4759
Tim Petersa9bc1682003-01-11 03:39:11 +00004760/* Accessor properties. Properties for day, month, and year are inherited
4761 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004762 */
4763
4764static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004765datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004767 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004768}
4769
Tim Petersa9bc1682003-01-11 03:39:11 +00004770static PyObject *
4771datetime_minute(PyDateTime_DateTime *self, void *unused)
4772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004773 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004774}
4775
4776static PyObject *
4777datetime_second(PyDateTime_DateTime *self, void *unused)
4778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004779 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004780}
4781
4782static PyObject *
4783datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4784{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004785 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004786}
4787
4788static PyObject *
4789datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4790{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004791 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4792 Py_INCREF(result);
4793 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004794}
4795
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004796static PyObject *
4797datetime_fold(PyDateTime_DateTime *self, void *unused)
4798{
4799 return PyLong_FromLong(DATE_GET_FOLD(self));
4800}
4801
Tim Petersa9bc1682003-01-11 03:39:11 +00004802static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004803 {"hour", (getter)datetime_hour},
4804 {"minute", (getter)datetime_minute},
4805 {"second", (getter)datetime_second},
4806 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004807 {"tzinfo", (getter)datetime_tzinfo},
4808 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004809 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004810};
4811
4812/*
4813 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004814 */
4815
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004816static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004817 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004818 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004819};
4820
Tim Peters2a799bf2002-12-16 20:18:38 +00004821static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004822datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4823{
4824 PyDateTime_DateTime *me;
4825 char aware = (char)(tzinfo != Py_None);
4826
4827 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4828 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4829 return NULL;
4830 }
4831
4832 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4833 if (me != NULL) {
4834 const char *pdata = PyBytes_AS_STRING(state);
4835
4836 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4837 me->hashcode = -1;
4838 me->hastzinfo = aware;
4839 if (aware) {
4840 Py_INCREF(tzinfo);
4841 me->tzinfo = tzinfo;
4842 }
4843 if (pdata[2] & (1 << 7)) {
4844 me->data[2] -= 128;
4845 me->fold = 1;
4846 }
4847 else {
4848 me->fold = 0;
4849 }
4850 }
4851 return (PyObject *)me;
4852}
4853
4854static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004855datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004857 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004858 int year;
4859 int month;
4860 int day;
4861 int hour = 0;
4862 int minute = 0;
4863 int second = 0;
4864 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004865 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004866 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004868 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004869 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4870 PyObject *state = PyTuple_GET_ITEM(args, 0);
4871 if (PyTuple_GET_SIZE(args) == 2) {
4872 tzinfo = PyTuple_GET_ITEM(args, 1);
4873 }
4874 if (PyBytes_Check(state)) {
4875 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4876 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4877 {
4878 return datetime_from_pickle(type, state, tzinfo);
4879 }
4880 }
4881 else if (PyUnicode_Check(state)) {
4882 if (PyUnicode_READY(state)) {
4883 return NULL;
4884 }
4885 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4886 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4887 {
4888 state = PyUnicode_AsLatin1String(state);
4889 if (state == NULL) {
4890 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4891 /* More informative error message. */
4892 PyErr_SetString(PyExc_ValueError,
4893 "Failed to encode latin1 string when unpickling "
4894 "a datetime object. "
4895 "pickle.load(data, encoding='latin1') is assumed.");
4896 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004897 return NULL;
4898 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004899 self = datetime_from_pickle(type, state, tzinfo);
4900 Py_DECREF(state);
4901 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004902 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004903 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004904 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004905 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004906
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004907 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004908 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004909 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004910 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004911 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004912 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004913 }
4914 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004915}
4916
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004917/* TM_FUNC is the shared type of _PyTime_localtime() and
4918 * _PyTime_gmtime(). */
4919typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004920
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004921/* As of version 2015f max fold in IANA database is
4922 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004923static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004924/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004925static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004926
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004927static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004928utc_to_seconds(int year, int month, int day,
4929 int hour, int minute, int second)
4930{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004931 long long ordinal;
4932
4933 /* ymd_to_ord() doesn't support year <= 0 */
4934 if (year < MINYEAR || year > MAXYEAR) {
4935 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4936 return -1;
4937 }
4938
4939 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004940 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4941}
4942
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004943static long long
4944local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004945{
4946 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004947 time_t t;
4948 u -= epoch;
4949 t = u;
4950 if (t != u) {
4951 PyErr_SetString(PyExc_OverflowError,
4952 "timestamp out of range for platform time_t");
4953 return -1;
4954 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004955 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004956 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004957 return utc_to_seconds(local_time.tm_year + 1900,
4958 local_time.tm_mon + 1,
4959 local_time.tm_mday,
4960 local_time.tm_hour,
4961 local_time.tm_min,
4962 local_time.tm_sec);
4963}
4964
Tim Petersa9bc1682003-01-11 03:39:11 +00004965/* Internal helper.
4966 * Build datetime from a time_t and a distinct count of microseconds.
4967 * Pass localtime or gmtime for f, to control the interpretation of timet.
4968 */
4969static PyObject *
4970datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004971 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004972{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004973 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004974 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004975
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004976 if (f(timet, &tm) != 0)
4977 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004978
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004979 year = tm.tm_year + 1900;
4980 month = tm.tm_mon + 1;
4981 day = tm.tm_mday;
4982 hour = tm.tm_hour;
4983 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004984 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004985 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004986 * except to the extent that passing them on to the datetime
4987 * constructor would raise ValueError for a reason that
4988 * made no sense to the user.
4989 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004990 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004991
Victor Stinnerb67f0962017-02-10 10:34:02 +01004992 /* local timezone requires to compute fold */
Ammar Askar96d1e692018-07-25 09:54:58 -07004993 if (tzinfo == Py_None && f == _PyTime_localtime
4994 /* On Windows, passing a negative value to local results
4995 * in an OSError because localtime_s on Windows does
4996 * not support negative timestamps. Unfortunately this
4997 * means that fold detection for time values between
4998 * 0 and max_fold_seconds will result in an identical
4999 * error since we subtract max_fold_seconds to detect a
5000 * fold. However, since we know there haven't been any
5001 * folds in the interval [0, max_fold_seconds) in any
5002 * timezone, we can hackily just forego fold detection
5003 * for this time range.
5004 */
5005#ifdef MS_WINDOWS
5006 && (timet - max_fold_seconds > 0)
5007#endif
5008 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005009 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005010
5011 result_seconds = utc_to_seconds(year, month, day,
5012 hour, minute, second);
5013 /* Probe max_fold_seconds to detect a fold. */
5014 probe_seconds = local(epoch + timet - max_fold_seconds);
5015 if (probe_seconds == -1)
5016 return NULL;
5017 transition = result_seconds - probe_seconds - max_fold_seconds;
5018 if (transition < 0) {
5019 probe_seconds = local(epoch + timet + transition);
5020 if (probe_seconds == -1)
5021 return NULL;
5022 if (probe_seconds == result_seconds)
5023 fold = 1;
5024 }
5025 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005026 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
5027 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00005028}
5029
5030/* Internal helper.
5031 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
5032 * to control the interpretation of the timestamp. Since a double doesn't
5033 * have enough bits to cover a datetime's full range of precision, it's
5034 * better to call datetime_from_timet_and_us provided you have a way
5035 * to get that much precision (e.g., C time() isn't good enough).
5036 */
5037static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01005038datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005039 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00005040{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005041 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01005042 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00005043
Victor Stinnere4a994d2015-03-30 01:10:14 +02005044 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02005045 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005046 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02005047
Victor Stinner21f58932012-03-14 00:15:40 +01005048 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00005049}
5050
5051/* Internal helper.
5052 * Build most accurate possible datetime for current time. Pass localtime or
5053 * gmtime for f as appropriate.
5054 */
5055static PyObject *
5056datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
5057{
Victor Stinner09e5cf22015-03-30 00:09:18 +02005058 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02005059 time_t secs;
5060 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02005061
Victor Stinner1e2b6882015-09-18 13:23:02 +02005062 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02005063 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02005064 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02005065
Victor Stinner1e2b6882015-09-18 13:23:02 +02005066 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00005067}
5068
Larry Hastings61272b72014-01-07 12:41:53 -08005069/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07005070
5071@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005072datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07005073
5074 tz: object = None
5075 Timezone object.
5076
5077Returns new datetime object representing current time local to tz.
5078
5079If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08005080[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07005081
Larry Hastings31826802013-10-19 00:09:25 -07005082static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08005083datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005084/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00005085{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005086 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005087
Larry Hastings31826802013-10-19 00:09:25 -07005088 /* Return best possible local time -- this isn't constrained by the
5089 * precision of a timestamp.
5090 */
5091 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005092 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00005093
Larry Hastings5c661892014-01-24 06:17:25 -08005094 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005095 tz == Py_None ? _PyTime_localtime :
5096 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07005097 tz);
5098 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005099 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02005100 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005101 }
5102 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005103}
5104
Tim Petersa9bc1682003-01-11 03:39:11 +00005105/* Return best possible UTC time -- this isn't constrained by the
5106 * precision of a timestamp.
5107 */
5108static PyObject *
5109datetime_utcnow(PyObject *cls, PyObject *dummy)
5110{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005111 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00005112}
5113
Tim Peters2a799bf2002-12-16 20:18:38 +00005114/* Return new local datetime from timestamp (Python timestamp -- a double). */
5115static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005116datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005117{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005118 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01005119 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005120 PyObject *tzinfo = Py_None;
5121 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00005122
Victor Stinner5d272cc2012-03-13 13:35:55 +01005123 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005124 keywords, &timestamp, &tzinfo))
5125 return NULL;
5126 if (check_tzinfo_subclass(tzinfo) < 0)
5127 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00005128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005129 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005130 tzinfo == Py_None ? _PyTime_localtime :
5131 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005132 timestamp,
5133 tzinfo);
5134 if (self != NULL && tzinfo != Py_None) {
5135 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02005136 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005137 }
5138 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005139}
5140
Tim Petersa9bc1682003-01-11 03:39:11 +00005141/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
5142static PyObject *
5143datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
5144{
Victor Stinner5d272cc2012-03-13 13:35:55 +01005145 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005146 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005147
Victor Stinner5d272cc2012-03-13 13:35:55 +01005148 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005149 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005150 Py_None);
5151 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005152}
5153
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005154/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005155static PyObject *
5156datetime_strptime(PyObject *cls, PyObject *args)
5157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005158 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005159 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02005160 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005161
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005162 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005163 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005164
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005165 if (module == NULL) {
5166 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00005167 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005168 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005169 }
Victor Stinner20401de2016-12-09 15:24:31 +01005170 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
5171 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005172}
5173
Tim Petersa9bc1682003-01-11 03:39:11 +00005174/* Return new datetime from date/datetime and time arguments. */
5175static PyObject *
5176datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
5177{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005178 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005179 PyObject *date;
5180 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005181 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005182 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00005183
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005184 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005185 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005186 &PyDateTime_TimeType, &time, &tzinfo)) {
5187 if (tzinfo == NULL) {
5188 if (HASTZINFO(time))
5189 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
5190 else
5191 tzinfo = Py_None;
5192 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005193 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
5194 GET_MONTH(date),
5195 GET_DAY(date),
5196 TIME_GET_HOUR(time),
5197 TIME_GET_MINUTE(time),
5198 TIME_GET_SECOND(time),
5199 TIME_GET_MICROSECOND(time),
5200 tzinfo,
5201 TIME_GET_FOLD(time),
5202 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005203 }
5204 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005205}
Tim Peters2a799bf2002-12-16 20:18:38 +00005206
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005207static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005208_sanitize_isoformat_str(PyObject *dtstr)
5209{
Paul Ganssle096329f2018-08-23 11:06:20 -04005210 // `fromisoformat` allows surrogate characters in exactly one position,
5211 // the separator; to allow datetime_fromisoformat to make the simplifying
5212 // assumption that all valid strings can be encoded in UTF-8, this function
5213 // replaces any surrogate character separators with `T`.
Paul Ganssle3df85402018-10-22 12:32:52 -04005214 //
5215 // The result of this, if not NULL, returns a new reference
Paul Ganssle096329f2018-08-23 11:06:20 -04005216 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005217 if (len < 0) {
5218 return NULL;
5219 }
5220
5221 if (len <= 10 ||
5222 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
5223 Py_INCREF(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005224 return dtstr;
5225 }
5226
Paul Ganssle3df85402018-10-22 12:32:52 -04005227 PyObject *str_out = _PyUnicode_Copy(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005228 if (str_out == NULL) {
5229 return NULL;
5230 }
5231
Paul Ganssle3df85402018-10-22 12:32:52 -04005232 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005233 Py_DECREF(str_out);
5234 return NULL;
5235 }
5236
Paul Ganssle096329f2018-08-23 11:06:20 -04005237 return str_out;
5238}
5239
5240static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005241datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5242{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005243 assert(dtstr != NULL);
5244
5245 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005246 PyErr_SetString(PyExc_TypeError,
5247 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005248 return NULL;
5249 }
5250
Paul Ganssle3df85402018-10-22 12:32:52 -04005251 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5252 if (dtstr_clean == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005253 goto error;
5254 }
5255
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005256 Py_ssize_t len;
Paul Ganssle3df85402018-10-22 12:32:52 -04005257 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04005258
5259 if (dt_ptr == NULL) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005260 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5261 // Encoding errors are invalid string errors at this point
5262 goto invalid_string_error;
5263 }
5264 else {
5265 goto error;
5266 }
Paul Ganssle096329f2018-08-23 11:06:20 -04005267 }
5268
5269 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005270
5271 int year = 0, month = 0, day = 0;
5272 int hour = 0, minute = 0, second = 0, microsecond = 0;
5273 int tzoffset = 0, tzusec = 0;
5274
5275 // date has a fixed length of 10
5276 int rv = parse_isoformat_date(p, &year, &month, &day);
5277
5278 if (!rv && len > 10) {
5279 // In UTF-8, the length of multi-byte characters is encoded in the MSB
5280 if ((p[10] & 0x80) == 0) {
5281 p += 11;
Paul Ganssle3df85402018-10-22 12:32:52 -04005282 }
5283 else {
5284 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005285 case 0xe0:
5286 p += 13;
5287 break;
5288 case 0xf0:
5289 p += 14;
5290 break;
5291 default:
5292 p += 12;
5293 break;
5294 }
5295 }
5296
5297 len -= (p - dt_ptr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005298 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5299 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005300 }
5301 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005302 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005303 }
5304
Paul Ganssle3df85402018-10-22 12:32:52 -04005305 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005306 if (tzinfo == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005307 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005308 }
5309
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005310 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5311 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005312
5313 Py_DECREF(tzinfo);
Paul Ganssle3df85402018-10-22 12:32:52 -04005314 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005315 return dt;
Paul Ganssle096329f2018-08-23 11:06:20 -04005316
5317invalid_string_error:
5318 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5319
5320error:
Paul Ganssle3df85402018-10-22 12:32:52 -04005321 Py_XDECREF(dtstr_clean);
Paul Ganssle096329f2018-08-23 11:06:20 -04005322
5323 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005324}
5325
Tim Peters2a799bf2002-12-16 20:18:38 +00005326/*
5327 * Destructor.
5328 */
5329
5330static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005331datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005332{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005333 if (HASTZINFO(self)) {
5334 Py_XDECREF(self->tzinfo);
5335 }
5336 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005337}
5338
5339/*
5340 * Indirect access to tzinfo methods.
5341 */
5342
Tim Peters2a799bf2002-12-16 20:18:38 +00005343/* These are all METH_NOARGS, so don't need to check the arglist. */
5344static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005345datetime_utcoffset(PyObject *self, PyObject *unused) {
5346 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005347}
5348
5349static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005350datetime_dst(PyObject *self, PyObject *unused) {
5351 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005352}
5353
5354static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005355datetime_tzname(PyObject *self, PyObject *unused) {
5356 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005357}
5358
5359/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005360 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005361 */
5362
Tim Petersa9bc1682003-01-11 03:39:11 +00005363/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5364 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005365 */
5366static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005367add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005368 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005370 /* Note that the C-level additions can't overflow, because of
5371 * invariant bounds on the member values.
5372 */
5373 int year = GET_YEAR(date);
5374 int month = GET_MONTH(date);
5375 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5376 int hour = DATE_GET_HOUR(date);
5377 int minute = DATE_GET_MINUTE(date);
5378 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5379 int microsecond = DATE_GET_MICROSECOND(date) +
5380 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005382 assert(factor == 1 || factor == -1);
5383 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005384 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005385 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005386 }
5387
Paul Ganssle89427cd2019-02-04 14:42:04 -05005388 return new_datetime_subclass_ex(year, month, day,
5389 hour, minute, second, microsecond,
5390 HASTZINFO(date) ? date->tzinfo : Py_None,
5391 (PyObject *)Py_TYPE(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00005392}
5393
5394static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005395datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005397 if (PyDateTime_Check(left)) {
5398 /* datetime + ??? */
5399 if (PyDelta_Check(right))
5400 /* datetime + delta */
5401 return add_datetime_timedelta(
5402 (PyDateTime_DateTime *)left,
5403 (PyDateTime_Delta *)right,
5404 1);
5405 }
5406 else if (PyDelta_Check(left)) {
5407 /* delta + datetime */
5408 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5409 (PyDateTime_Delta *) left,
5410 1);
5411 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005412 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005413}
5414
5415static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005416datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005418 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005420 if (PyDateTime_Check(left)) {
5421 /* datetime - ??? */
5422 if (PyDateTime_Check(right)) {
5423 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005424 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005425 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005426
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005427 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5428 offset2 = offset1 = Py_None;
5429 Py_INCREF(offset1);
5430 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005431 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005432 else {
5433 offset1 = datetime_utcoffset(left, NULL);
5434 if (offset1 == NULL)
5435 return NULL;
5436 offset2 = datetime_utcoffset(right, NULL);
5437 if (offset2 == NULL) {
5438 Py_DECREF(offset1);
5439 return NULL;
5440 }
5441 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5442 PyErr_SetString(PyExc_TypeError,
5443 "can't subtract offset-naive and "
5444 "offset-aware datetimes");
5445 Py_DECREF(offset1);
5446 Py_DECREF(offset2);
5447 return NULL;
5448 }
5449 }
5450 if ((offset1 != offset2) &&
5451 delta_cmp(offset1, offset2) != 0) {
5452 offdiff = delta_subtract(offset1, offset2);
5453 if (offdiff == NULL) {
5454 Py_DECREF(offset1);
5455 Py_DECREF(offset2);
5456 return NULL;
5457 }
5458 }
5459 Py_DECREF(offset1);
5460 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005461 delta_d = ymd_to_ord(GET_YEAR(left),
5462 GET_MONTH(left),
5463 GET_DAY(left)) -
5464 ymd_to_ord(GET_YEAR(right),
5465 GET_MONTH(right),
5466 GET_DAY(right));
5467 /* These can't overflow, since the values are
5468 * normalized. At most this gives the number of
5469 * seconds in one day.
5470 */
5471 delta_s = (DATE_GET_HOUR(left) -
5472 DATE_GET_HOUR(right)) * 3600 +
5473 (DATE_GET_MINUTE(left) -
5474 DATE_GET_MINUTE(right)) * 60 +
5475 (DATE_GET_SECOND(left) -
5476 DATE_GET_SECOND(right));
5477 delta_us = DATE_GET_MICROSECOND(left) -
5478 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005479 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005480 if (result == NULL)
5481 return NULL;
5482
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005483 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005484 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005485 Py_DECREF(offdiff);
5486 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005487 }
5488 else if (PyDelta_Check(right)) {
5489 /* datetime - delta */
5490 result = add_datetime_timedelta(
5491 (PyDateTime_DateTime *)left,
5492 (PyDateTime_Delta *)right,
5493 -1);
5494 }
5495 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005497 if (result == Py_NotImplemented)
5498 Py_INCREF(result);
5499 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005500}
5501
5502/* Various ways to turn a datetime into a string. */
5503
5504static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005505datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005506{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005507 const char *type_name = Py_TYPE(self)->tp_name;
5508 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005510 if (DATE_GET_MICROSECOND(self)) {
5511 baserepr = PyUnicode_FromFormat(
5512 "%s(%d, %d, %d, %d, %d, %d, %d)",
5513 type_name,
5514 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5515 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5516 DATE_GET_SECOND(self),
5517 DATE_GET_MICROSECOND(self));
5518 }
5519 else if (DATE_GET_SECOND(self)) {
5520 baserepr = PyUnicode_FromFormat(
5521 "%s(%d, %d, %d, %d, %d, %d)",
5522 type_name,
5523 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5524 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5525 DATE_GET_SECOND(self));
5526 }
5527 else {
5528 baserepr = PyUnicode_FromFormat(
5529 "%s(%d, %d, %d, %d, %d)",
5530 type_name,
5531 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5532 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5533 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005534 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5535 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005536 if (baserepr == NULL || ! HASTZINFO(self))
5537 return baserepr;
5538 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005539}
5540
Tim Petersa9bc1682003-01-11 03:39:11 +00005541static PyObject *
5542datetime_str(PyDateTime_DateTime *self)
5543{
Victor Stinner4c381542016-12-09 00:33:39 +01005544 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005545}
Tim Peters2a799bf2002-12-16 20:18:38 +00005546
5547static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005548datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005549{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005550 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005551 char *timespec = NULL;
5552 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005553 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005554 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005555 int us = DATE_GET_MICROSECOND(self);
Andy Lesterc3fa6342020-02-24 00:40:43 -06005556 static const char *specs[][2] = {
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005557 {"hours", "%04d-%02d-%02d%c%02d"},
5558 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5559 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5560 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5561 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5562 };
5563 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005564
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005565 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005566 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005567
5568 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5569 if (us == 0) {
5570 /* seconds */
5571 given_spec = 2;
5572 }
5573 else {
5574 /* microseconds */
5575 given_spec = 4;
5576 }
5577 }
5578 else {
5579 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5580 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5581 if (given_spec == 3) {
5582 us = us / 1000;
5583 }
5584 break;
5585 }
5586 }
5587 }
5588
5589 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5590 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5591 return NULL;
5592 }
5593 else {
5594 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005595 GET_YEAR(self), GET_MONTH(self),
5596 GET_DAY(self), (int)sep,
5597 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5598 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005599 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005601 if (!result || !HASTZINFO(self))
5602 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005604 /* We need to append the UTC offset. */
5605 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5606 (PyObject *)self) < 0) {
5607 Py_DECREF(result);
5608 return NULL;
5609 }
5610 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5611 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005612}
5613
Tim Petersa9bc1682003-01-11 03:39:11 +00005614static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305615datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005617 return format_ctime((PyDateTime_Date *)self,
5618 DATE_GET_HOUR(self),
5619 DATE_GET_MINUTE(self),
5620 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005621}
5622
Tim Peters2a799bf2002-12-16 20:18:38 +00005623/* Miscellaneous methods. */
5624
Tim Petersa9bc1682003-01-11 03:39:11 +00005625static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005626flip_fold(PyObject *dt)
5627{
5628 return new_datetime_ex2(GET_YEAR(dt),
5629 GET_MONTH(dt),
5630 GET_DAY(dt),
5631 DATE_GET_HOUR(dt),
5632 DATE_GET_MINUTE(dt),
5633 DATE_GET_SECOND(dt),
5634 DATE_GET_MICROSECOND(dt),
5635 HASTZINFO(dt) ?
5636 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5637 !DATE_GET_FOLD(dt),
5638 Py_TYPE(dt));
5639}
5640
5641static PyObject *
5642get_flip_fold_offset(PyObject *dt)
5643{
5644 PyObject *result, *flip_dt;
5645
5646 flip_dt = flip_fold(dt);
5647 if (flip_dt == NULL)
5648 return NULL;
5649 result = datetime_utcoffset(flip_dt, NULL);
5650 Py_DECREF(flip_dt);
5651 return result;
5652}
5653
5654/* PEP 495 exception: Whenever one or both of the operands in
5655 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakabac2d5b2018-03-28 22:14:26 +03005656 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005657 *
5658 * Return 1 if exception applies, 0 if not, and -1 on error.
5659 */
5660static int
5661pep495_eq_exception(PyObject *self, PyObject *other,
5662 PyObject *offset_self, PyObject *offset_other)
5663{
5664 int result = 0;
5665 PyObject *flip_offset;
5666
5667 flip_offset = get_flip_fold_offset(self);
5668 if (flip_offset == NULL)
5669 return -1;
5670 if (flip_offset != offset_self &&
5671 delta_cmp(flip_offset, offset_self))
5672 {
5673 result = 1;
5674 goto done;
5675 }
5676 Py_DECREF(flip_offset);
5677
5678 flip_offset = get_flip_fold_offset(other);
5679 if (flip_offset == NULL)
5680 return -1;
5681 if (flip_offset != offset_other &&
5682 delta_cmp(flip_offset, offset_other))
5683 result = 1;
5684 done:
5685 Py_DECREF(flip_offset);
5686 return result;
5687}
5688
5689static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005690datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005691{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005692 PyObject *result = NULL;
5693 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005694 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005695
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005696 if (! PyDateTime_Check(other)) {
5697 if (PyDate_Check(other)) {
5698 /* Prevent invocation of date_richcompare. We want to
5699 return NotImplemented here to give the other object
5700 a chance. But since DateTime is a subclass of
5701 Date, if the other object is a Date, it would
5702 compute an ordering based on the date part alone,
5703 and we don't want that. So force unequal or
5704 uncomparable here in that case. */
5705 if (op == Py_EQ)
5706 Py_RETURN_FALSE;
5707 if (op == Py_NE)
5708 Py_RETURN_TRUE;
5709 return cmperror(self, other);
5710 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005711 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005712 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005713
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005714 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005715 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5716 ((PyDateTime_DateTime *)other)->data,
5717 _PyDateTime_DATETIME_DATASIZE);
5718 return diff_to_bool(diff, op);
5719 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005720 offset1 = datetime_utcoffset(self, NULL);
5721 if (offset1 == NULL)
5722 return NULL;
5723 offset2 = datetime_utcoffset(other, NULL);
5724 if (offset2 == NULL)
5725 goto done;
5726 /* If they're both naive, or both aware and have the same offsets,
5727 * we get off cheap. Note that if they're both naive, offset1 ==
5728 * offset2 == Py_None at this point.
5729 */
5730 if ((offset1 == offset2) ||
5731 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5732 delta_cmp(offset1, offset2) == 0)) {
5733 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5734 ((PyDateTime_DateTime *)other)->data,
5735 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005736 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5737 int ex = pep495_eq_exception(self, other, offset1, offset2);
5738 if (ex == -1)
5739 goto done;
5740 if (ex)
5741 diff = 1;
5742 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005743 result = diff_to_bool(diff, op);
5744 }
5745 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005746 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005747
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005748 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005749 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5750 other);
5751 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005752 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005753 diff = GET_TD_DAYS(delta);
5754 if (diff == 0)
5755 diff = GET_TD_SECONDS(delta) |
5756 GET_TD_MICROSECONDS(delta);
5757 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005758 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5759 int ex = pep495_eq_exception(self, other, offset1, offset2);
5760 if (ex == -1)
5761 goto done;
5762 if (ex)
5763 diff = 1;
5764 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005765 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005766 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005767 else if (op == Py_EQ) {
5768 result = Py_False;
5769 Py_INCREF(result);
5770 }
5771 else if (op == Py_NE) {
5772 result = Py_True;
5773 Py_INCREF(result);
5774 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005775 else {
5776 PyErr_SetString(PyExc_TypeError,
5777 "can't compare offset-naive and "
5778 "offset-aware datetimes");
5779 }
5780 done:
5781 Py_DECREF(offset1);
5782 Py_XDECREF(offset2);
5783 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005784}
5785
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005786static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005787datetime_hash(PyDateTime_DateTime *self)
5788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005789 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005790 PyObject *offset, *self0;
5791 if (DATE_GET_FOLD(self)) {
5792 self0 = new_datetime_ex2(GET_YEAR(self),
5793 GET_MONTH(self),
5794 GET_DAY(self),
5795 DATE_GET_HOUR(self),
5796 DATE_GET_MINUTE(self),
5797 DATE_GET_SECOND(self),
5798 DATE_GET_MICROSECOND(self),
5799 HASTZINFO(self) ? self->tzinfo : Py_None,
5800 0, Py_TYPE(self));
5801 if (self0 == NULL)
5802 return -1;
5803 }
5804 else {
5805 self0 = (PyObject *)self;
5806 Py_INCREF(self0);
5807 }
5808 offset = datetime_utcoffset(self0, NULL);
5809 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005810
5811 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005812 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005814 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005815 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005816 self->hashcode = generic_hash(
5817 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005818 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005819 PyObject *temp1, *temp2;
5820 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005822 assert(HASTZINFO(self));
5823 days = ymd_to_ord(GET_YEAR(self),
5824 GET_MONTH(self),
5825 GET_DAY(self));
5826 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005827 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005828 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005829 temp1 = new_delta(days, seconds,
5830 DATE_GET_MICROSECOND(self),
5831 1);
5832 if (temp1 == NULL) {
5833 Py_DECREF(offset);
5834 return -1;
5835 }
5836 temp2 = delta_subtract(temp1, offset);
5837 Py_DECREF(temp1);
5838 if (temp2 == NULL) {
5839 Py_DECREF(offset);
5840 return -1;
5841 }
5842 self->hashcode = PyObject_Hash(temp2);
5843 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005844 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005845 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005846 }
5847 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005848}
Tim Peters2a799bf2002-12-16 20:18:38 +00005849
5850static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005851datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005852{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005853 PyObject *clone;
5854 PyObject *tuple;
5855 int y = GET_YEAR(self);
5856 int m = GET_MONTH(self);
5857 int d = GET_DAY(self);
5858 int hh = DATE_GET_HOUR(self);
5859 int mm = DATE_GET_MINUTE(self);
5860 int ss = DATE_GET_SECOND(self);
5861 int us = DATE_GET_MICROSECOND(self);
5862 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005863 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005864
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005865 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005866 datetime_kws,
5867 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005868 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005869 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005870 if (fold != 0 && fold != 1) {
5871 PyErr_SetString(PyExc_ValueError,
5872 "fold must be either 0 or 1");
5873 return NULL;
5874 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005875 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5876 if (tuple == NULL)
5877 return NULL;
5878 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005879 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005880 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005881 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005882 Py_DECREF(tuple);
5883 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005884}
5885
5886static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005887local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005888{
5889 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005890 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005891 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005892 PyObject *nameo = NULL;
5893 const char *zone = NULL;
5894
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005895 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005896 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005897#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005898 zone = local_time_tm.tm_zone;
5899 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005900#else /* HAVE_STRUCT_TM_TM_ZONE */
5901 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005902 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005903 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005904 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005905 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005906 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005907 local_time = new_datetime(local_time_tm.tm_year + 1900,
5908 local_time_tm.tm_mon + 1,
5909 local_time_tm.tm_mday,
5910 local_time_tm.tm_hour,
5911 local_time_tm.tm_min,
5912 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005913 if (local_time == NULL) {
5914 return NULL;
5915 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005916 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005917 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005918 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5919 utc_time_tm.tm_mon + 1,
5920 utc_time_tm.tm_mday,
5921 utc_time_tm.tm_hour,
5922 utc_time_tm.tm_min,
5923 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005924 if (utc_time == NULL) {
5925 Py_DECREF(local_time);
5926 return NULL;
5927 }
5928 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005929 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005930 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005931 }
5932#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005933 if (delta == NULL) {
5934 return NULL;
5935 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005936 if (zone != NULL) {
5937 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5938 if (nameo == NULL)
5939 goto error;
5940 }
5941 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005942 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005943 error:
5944 Py_DECREF(delta);
5945 return result;
5946}
5947
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005948static PyObject *
5949local_timezone(PyDateTime_DateTime *utc_time)
5950{
5951 time_t timestamp;
5952 PyObject *delta;
5953 PyObject *one_second;
5954 PyObject *seconds;
5955
5956 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5957 if (delta == NULL)
5958 return NULL;
5959 one_second = new_delta(0, 1, 0, 0);
5960 if (one_second == NULL) {
5961 Py_DECREF(delta);
5962 return NULL;
5963 }
5964 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5965 (PyDateTime_Delta *)one_second);
5966 Py_DECREF(one_second);
5967 Py_DECREF(delta);
5968 if (seconds == NULL)
5969 return NULL;
5970 timestamp = _PyLong_AsTime_t(seconds);
5971 Py_DECREF(seconds);
5972 if (timestamp == -1 && PyErr_Occurred())
5973 return NULL;
5974 return local_timezone_from_timestamp(timestamp);
5975}
5976
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005977static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005978local_to_seconds(int year, int month, int day,
5979 int hour, int minute, int second, int fold);
5980
5981static PyObject *
5982local_timezone_from_local(PyDateTime_DateTime *local_dt)
5983{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005984 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005985 time_t timestamp;
5986 seconds = local_to_seconds(GET_YEAR(local_dt),
5987 GET_MONTH(local_dt),
5988 GET_DAY(local_dt),
5989 DATE_GET_HOUR(local_dt),
5990 DATE_GET_MINUTE(local_dt),
5991 DATE_GET_SECOND(local_dt),
5992 DATE_GET_FOLD(local_dt));
5993 if (seconds == -1)
5994 return NULL;
5995 /* XXX: add bounds check */
5996 timestamp = seconds - epoch;
5997 return local_timezone_from_timestamp(timestamp);
5998}
5999
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006000static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00006001datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00006002{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006003 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006004 PyObject *offset;
6005 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006006 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006007 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006008 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00006009
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006010 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07006011 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006012 return NULL;
6013
6014 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006015 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00006016
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006017 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Alexander Belopolsky877b2322018-06-10 17:02:58 -04006018 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006019 self_tzinfo = local_timezone_from_local(self);
6020 if (self_tzinfo == NULL)
6021 return NULL;
6022 } else {
6023 self_tzinfo = self->tzinfo;
6024 Py_INCREF(self_tzinfo);
6025 }
Tim Peters521fc152002-12-31 17:36:56 +00006026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006027 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006028 if (self_tzinfo == tzinfo) {
6029 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006030 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006031 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006032 }
Tim Peters521fc152002-12-31 17:36:56 +00006033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006034 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006035 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
6036 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006037 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006038 return NULL;
Alexander Belopolsky877b2322018-06-10 17:02:58 -04006039 else if(offset == Py_None) {
6040 Py_DECREF(offset);
6041 goto naive;
6042 }
6043 else if (!PyDelta_Check(offset)) {
6044 Py_DECREF(offset);
6045 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
6046 " expected timedelta or None", Py_TYPE(offset)->tp_name);
6047 return NULL;
6048 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006049 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006050 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6051 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006052 Py_DECREF(offset);
6053 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006054 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00006055
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006056 /* Make sure result is aware and UTC. */
6057 if (!HASTZINFO(result)) {
6058 temp = (PyObject *)result;
6059 result = (PyDateTime_DateTime *)
6060 new_datetime_ex2(GET_YEAR(result),
6061 GET_MONTH(result),
6062 GET_DAY(result),
6063 DATE_GET_HOUR(result),
6064 DATE_GET_MINUTE(result),
6065 DATE_GET_SECOND(result),
6066 DATE_GET_MICROSECOND(result),
6067 PyDateTime_TimeZone_UTC,
6068 DATE_GET_FOLD(result),
6069 Py_TYPE(result));
6070 Py_DECREF(temp);
6071 if (result == NULL)
6072 return NULL;
6073 }
6074 else {
6075 /* Result is already aware - just replace tzinfo. */
6076 temp = result->tzinfo;
6077 result->tzinfo = PyDateTime_TimeZone_UTC;
6078 Py_INCREF(result->tzinfo);
6079 Py_DECREF(temp);
6080 }
6081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006082 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006083 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006084 if (tzinfo == Py_None) {
6085 tzinfo = local_timezone(result);
6086 if (tzinfo == NULL) {
6087 Py_DECREF(result);
6088 return NULL;
6089 }
6090 }
6091 else
6092 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006093 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006094 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00006095
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006096 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006097 result = (PyDateTime_DateTime *)
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02006098 _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006099 Py_DECREF(temp);
6100
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006101 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00006102}
6103
6104static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306105datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006106{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006107 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00006108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006109 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006110 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00006111
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006112 dst = call_dst(self->tzinfo, (PyObject *)self);
6113 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006114 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006115
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006116 if (dst != Py_None)
6117 dstflag = delta_bool((PyDateTime_Delta *)dst);
6118 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006119 }
6120 return build_struct_time(GET_YEAR(self),
6121 GET_MONTH(self),
6122 GET_DAY(self),
6123 DATE_GET_HOUR(self),
6124 DATE_GET_MINUTE(self),
6125 DATE_GET_SECOND(self),
6126 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00006127}
6128
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006129static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006130local_to_seconds(int year, int month, int day,
6131 int hour, int minute, int second, int fold)
6132{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006133 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006134 t = utc_to_seconds(year, month, day, hour, minute, second);
6135 /* Our goal is to solve t = local(u) for u. */
6136 lt = local(t);
6137 if (lt == -1)
6138 return -1;
6139 a = lt - t;
6140 u1 = t - a;
6141 t1 = local(u1);
6142 if (t1 == -1)
6143 return -1;
6144 if (t1 == t) {
6145 /* We found one solution, but it may not be the one we need.
6146 * Look for an earlier solution (if `fold` is 0), or a
6147 * later one (if `fold` is 1). */
6148 if (fold)
6149 u2 = u1 + max_fold_seconds;
6150 else
6151 u2 = u1 - max_fold_seconds;
6152 lt = local(u2);
6153 if (lt == -1)
6154 return -1;
6155 b = lt - u2;
6156 if (a == b)
6157 return u1;
6158 }
6159 else {
6160 b = t1 - u1;
6161 assert(a != b);
6162 }
6163 u2 = t - b;
6164 t2 = local(u2);
6165 if (t2 == -1)
6166 return -1;
6167 if (t2 == t)
6168 return u2;
6169 if (t1 == t)
6170 return u1;
6171 /* We have found both offsets a and b, but neither t - a nor t - b is
6172 * a solution. This means t is in the gap. */
6173 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
6174}
6175
6176/* date(1970,1,1).toordinal() == 719163 */
6177#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
6178
Tim Peters2a799bf2002-12-16 20:18:38 +00006179static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306180datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolskya4415142012-06-08 12:33:09 -04006181{
6182 PyObject *result;
6183
6184 if (HASTZINFO(self) && self->tzinfo != Py_None) {
6185 PyObject *delta;
6186 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
6187 if (delta == NULL)
6188 return NULL;
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306189 result = delta_total_seconds(delta, NULL);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006190 Py_DECREF(delta);
6191 }
6192 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006193 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006194 seconds = local_to_seconds(GET_YEAR(self),
6195 GET_MONTH(self),
6196 GET_DAY(self),
6197 DATE_GET_HOUR(self),
6198 DATE_GET_MINUTE(self),
6199 DATE_GET_SECOND(self),
6200 DATE_GET_FOLD(self));
6201 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04006202 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006203 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
6204 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006205 }
6206 return result;
6207}
6208
6209static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306210datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006212 return new_date(GET_YEAR(self),
6213 GET_MONTH(self),
6214 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006215}
6216
6217static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306218datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006220 return new_time(DATE_GET_HOUR(self),
6221 DATE_GET_MINUTE(self),
6222 DATE_GET_SECOND(self),
6223 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006224 Py_None,
6225 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006226}
6227
6228static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306229datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006231 return new_time(DATE_GET_HOUR(self),
6232 DATE_GET_MINUTE(self),
6233 DATE_GET_SECOND(self),
6234 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006235 GET_DT_TZINFO(self),
6236 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006237}
6238
6239static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306240datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006241{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006242 int y, m, d, hh, mm, ss;
6243 PyObject *tzinfo;
6244 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006245
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006246 tzinfo = GET_DT_TZINFO(self);
6247 if (tzinfo == Py_None) {
6248 utcself = self;
6249 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006250 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006251 else {
6252 PyObject *offset;
6253 offset = call_utcoffset(tzinfo, (PyObject *)self);
6254 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006255 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006256 if (offset == Py_None) {
6257 Py_DECREF(offset);
6258 utcself = self;
6259 Py_INCREF(utcself);
6260 }
6261 else {
6262 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6263 (PyDateTime_Delta *)offset, -1);
6264 Py_DECREF(offset);
6265 if (utcself == NULL)
6266 return NULL;
6267 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006268 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006269 y = GET_YEAR(utcself);
6270 m = GET_MONTH(utcself);
6271 d = GET_DAY(utcself);
6272 hh = DATE_GET_HOUR(utcself);
6273 mm = DATE_GET_MINUTE(utcself);
6274 ss = DATE_GET_SECOND(utcself);
6275
6276 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006277 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006278}
6279
Tim Peters371935f2003-02-01 01:52:50 +00006280/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006281
Tim Petersa9bc1682003-01-11 03:39:11 +00006282/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006283 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6284 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006285 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006286 */
6287static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006288datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006290 PyObject *basestate;
6291 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006293 basestate = PyBytes_FromStringAndSize((char *)self->data,
6294 _PyDateTime_DATETIME_DATASIZE);
6295 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006296 if (proto > 3 && DATE_GET_FOLD(self))
6297 /* Set the first bit of the third byte */
6298 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006299 if (! HASTZINFO(self) || self->tzinfo == Py_None)
6300 result = PyTuple_Pack(1, basestate);
6301 else
6302 result = PyTuple_Pack(2, basestate, self->tzinfo);
6303 Py_DECREF(basestate);
6304 }
6305 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00006306}
6307
6308static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006309datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006310{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006311 int proto;
6312 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006313 return NULL;
6314
6315 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006316}
6317
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006318static PyObject *
6319datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6320{
6321 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6322}
6323
Tim Petersa9bc1682003-01-11 03:39:11 +00006324static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006326 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006327
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006328 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006330 {"utcnow", (PyCFunction)datetime_utcnow,
6331 METH_NOARGS | METH_CLASS,
6332 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006333
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006334 {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006335 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6336 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006338 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6339 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006340 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006342 {"strptime", (PyCFunction)datetime_strptime,
6343 METH_VARARGS | METH_CLASS,
6344 PyDoc_STR("string, format -> new datetime parsed from a string "
6345 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006346
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006347 {"combine", (PyCFunction)(void(*)(void))datetime_combine,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006348 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6349 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006350
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006351 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6352 METH_O | METH_CLASS,
6353 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006355 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006357 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6358 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006360 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6361 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006363 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6364 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006366 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6367 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006369 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6370 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006371
Alexander Belopolskya4415142012-06-08 12:33:09 -04006372 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6373 PyDoc_STR("Return POSIX timestamp as float.")},
6374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006375 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6376 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006377
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006378 {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006379 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006380 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006381 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006382 "defaults to 'T'.\n"
6383 "timespec specifies what components of the time to include"
6384 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6385 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006387 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6388 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006390 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6391 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006393 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6394 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006395
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006396 {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006397 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006398
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006399 {"astimezone", (PyCFunction)(void(*)(void))datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006400 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006401
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006402 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006403 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006404
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006405 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6406 PyDoc_STR("__reduce__() -> (cls, state)")},
6407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006408 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006409};
6410
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006411static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006412PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6413\n\
6414The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006415instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006416
Tim Petersa9bc1682003-01-11 03:39:11 +00006417static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006418 datetime_add, /* nb_add */
6419 datetime_subtract, /* nb_subtract */
6420 0, /* nb_multiply */
6421 0, /* nb_remainder */
6422 0, /* nb_divmod */
6423 0, /* nb_power */
6424 0, /* nb_negative */
6425 0, /* nb_positive */
6426 0, /* nb_absolute */
6427 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006428};
6429
Neal Norwitz227b5332006-03-22 09:28:35 +00006430static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006431 PyVarObject_HEAD_INIT(NULL, 0)
6432 "datetime.datetime", /* tp_name */
6433 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6434 0, /* tp_itemsize */
6435 (destructor)datetime_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006436 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006437 0, /* tp_getattr */
6438 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006439 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006440 (reprfunc)datetime_repr, /* tp_repr */
6441 &datetime_as_number, /* tp_as_number */
6442 0, /* tp_as_sequence */
6443 0, /* tp_as_mapping */
6444 (hashfunc)datetime_hash, /* tp_hash */
6445 0, /* tp_call */
6446 (reprfunc)datetime_str, /* tp_str */
6447 PyObject_GenericGetAttr, /* tp_getattro */
6448 0, /* tp_setattro */
6449 0, /* tp_as_buffer */
6450 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6451 datetime_doc, /* tp_doc */
6452 0, /* tp_traverse */
6453 0, /* tp_clear */
6454 datetime_richcompare, /* tp_richcompare */
6455 0, /* tp_weaklistoffset */
6456 0, /* tp_iter */
6457 0, /* tp_iternext */
6458 datetime_methods, /* tp_methods */
6459 0, /* tp_members */
6460 datetime_getset, /* tp_getset */
Miss Islington (bot)eceee542020-05-28 09:41:41 -07006461 0, /* tp_base; filled in
6462 PyInit__datetime */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006463 0, /* tp_dict */
6464 0, /* tp_descr_get */
6465 0, /* tp_descr_set */
6466 0, /* tp_dictoffset */
6467 0, /* tp_init */
6468 datetime_alloc, /* tp_alloc */
6469 datetime_new, /* tp_new */
6470 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006471};
6472
6473/* ---------------------------------------------------------------------------
6474 * Module methods and initialization.
6475 */
6476
6477static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006478 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006479};
6480
Tim Peters9ddf40b2004-06-20 22:41:32 +00006481/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6482 * datetime.h.
6483 */
6484static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006485 &PyDateTime_DateType,
6486 &PyDateTime_DateTimeType,
6487 &PyDateTime_TimeType,
6488 &PyDateTime_DeltaType,
6489 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006490 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006491 new_date_ex,
6492 new_datetime_ex,
6493 new_time_ex,
6494 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006495 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006496 datetime_fromtimestamp,
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04006497 datetime_date_fromtimestamp_capi,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006498 new_datetime_ex2,
6499 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006500};
6501
6502
Martin v. Löwis1a214512008-06-11 05:26:20 +00006503
6504static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006505 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006506 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006507 "Fast implementation of the datetime type.",
6508 -1,
6509 module_methods,
6510 NULL,
6511 NULL,
6512 NULL,
6513 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006514};
6515
Tim Peters2a799bf2002-12-16 20:18:38 +00006516PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006517PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006519 PyObject *m; /* a module object */
6520 PyObject *d; /* its dict */
6521 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006522 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006524 m = PyModule_Create(&datetimemodule);
6525 if (m == NULL)
6526 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006527
Miss Islington (bot)eceee542020-05-28 09:41:41 -07006528 // `&...` is not a constant expression according to a strict reading
6529 // of C standards. Fill tp_base at run-time rather than statically.
6530 // See https://bugs.python.org/issue40777
6531 PyDateTime_IsoCalendarDateType.tp_base = &PyTuple_Type;
6532 PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType;
6533 PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType;
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006534
Dong-hee Na37fcbb62020-03-25 07:08:51 +09006535 PyTypeObject *types[] = {
6536 &PyDateTime_DateType,
6537 &PyDateTime_DateTimeType,
6538 &PyDateTime_TimeType,
6539 &PyDateTime_DeltaType,
6540 &PyDateTime_TZInfoType,
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006541 &PyDateTime_TimeZoneType,
Dong-hee Na37fcbb62020-03-25 07:08:51 +09006542 };
6543
6544 for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
6545 if (PyModule_AddType(m, types[i]) < 0) {
6546 return NULL;
6547 }
6548 }
Tim Peters2a799bf2002-12-16 20:18:38 +00006549
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006550 if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) {
6551 return NULL;
6552 }
6553 Py_INCREF(&PyDateTime_IsoCalendarDateType);
6554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006555 /* timedelta values */
6556 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006558 x = new_delta(0, 0, 1, 0);
6559 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6560 return NULL;
6561 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006563 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6564 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6565 return NULL;
6566 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006568 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6569 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6570 return NULL;
6571 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006573 /* date values */
6574 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006576 x = new_date(1, 1, 1);
6577 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6578 return NULL;
6579 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006581 x = new_date(MAXYEAR, 12, 31);
6582 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6583 return NULL;
6584 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006586 x = new_delta(1, 0, 0, 0);
6587 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6588 return NULL;
6589 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006591 /* time values */
6592 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006593
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006594 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006595 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6596 return NULL;
6597 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006598
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006599 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006600 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6601 return NULL;
6602 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006604 x = new_delta(0, 0, 1, 0);
6605 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6606 return NULL;
6607 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006609 /* datetime values */
6610 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006611
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006612 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006613 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6614 return NULL;
6615 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006616
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006617 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006618 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6619 return NULL;
6620 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006622 x = new_delta(0, 0, 1, 0);
6623 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6624 return NULL;
6625 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006626
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006627 /* timezone values */
6628 d = PyDateTime_TimeZoneType.tp_dict;
6629
6630 delta = new_delta(0, 0, 0, 0);
6631 if (delta == NULL)
6632 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006633 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006634 Py_DECREF(delta);
6635 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6636 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006637 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006638 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006639
Ngalim Siregar92c7e302019-08-09 21:22:16 +07006640 /* bpo-37642: These attributes are rounded to the nearest minute for backwards
6641 * compatibility, even though the constructor will accept a wider range of
6642 * values. This may change in the future.*/
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006643 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6644 if (delta == NULL)
6645 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006646 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006647 Py_DECREF(delta);
6648 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6649 return NULL;
6650 Py_DECREF(x);
6651
6652 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6653 if (delta == NULL)
6654 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006655 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006656 Py_DECREF(delta);
6657 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6658 return NULL;
6659 Py_DECREF(x);
6660
Alexander Belopolskya4415142012-06-08 12:33:09 -04006661 /* Epoch */
6662 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006663 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006664 if (PyDateTime_Epoch == NULL)
6665 return NULL;
6666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006667 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006668 PyModule_AddIntMacro(m, MINYEAR);
6669 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006671 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6672 if (x == NULL)
6673 return NULL;
6674 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006676 /* A 4-year cycle has an extra leap day over what we'd get from
6677 * pasting together 4 single years.
6678 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006679 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006680 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006682 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6683 * get from pasting together 4 100-year cycles.
6684 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006685 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006686 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006688 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6689 * pasting together 25 4-year cycles.
6690 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006691 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006692 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006694 us_per_ms = PyLong_FromLong(1000);
6695 us_per_second = PyLong_FromLong(1000000);
6696 us_per_minute = PyLong_FromLong(60000000);
6697 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006698 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006699 us_per_minute == NULL || seconds_per_day == NULL)
6700 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006702 /* The rest are too big for 32-bit ints, but even
6703 * us_per_week fits in 40 bits, so doubles should be exact.
6704 */
6705 us_per_hour = PyLong_FromDouble(3600000000.0);
6706 us_per_day = PyLong_FromDouble(86400000000.0);
6707 us_per_week = PyLong_FromDouble(604800000000.0);
6708 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6709 return NULL;
6710 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006711}
Tim Petersf3615152003-01-01 21:51:37 +00006712
6713/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006714Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006715 x.n = x stripped of its timezone -- its naive time.
6716 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006717 return None
Tim Petersf3615152003-01-01 21:51:37 +00006718 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006719 return None
Tim Petersf3615152003-01-01 21:51:37 +00006720 x.s = x's standard offset, x.o - x.d
6721
6722Now some derived rules, where k is a duration (timedelta).
6723
67241. x.o = x.s + x.d
6725 This follows from the definition of x.s.
6726
Tim Petersc5dc4da2003-01-02 17:55:03 +000067272. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006728 This is actually a requirement, an assumption we need to make about
6729 sane tzinfo classes.
6730
67313. The naive UTC time corresponding to x is x.n - x.o.
6732 This is again a requirement for a sane tzinfo class.
6733
67344. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006735 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006736
Tim Petersc5dc4da2003-01-02 17:55:03 +000067375. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006738 Again follows from how arithmetic is defined.
6739
Tim Peters8bb5ad22003-01-24 02:44:45 +00006740Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006741(meaning that the various tzinfo methods exist, and don't blow up or return
6742None when called).
6743
Tim Petersa9bc1682003-01-11 03:39:11 +00006744The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006745x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006746
6747By #3, we want
6748
Tim Peters8bb5ad22003-01-24 02:44:45 +00006749 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006750
6751The algorithm starts by attaching tz to x.n, and calling that y. So
6752x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6753becomes true; in effect, we want to solve [2] for k:
6754
Tim Peters8bb5ad22003-01-24 02:44:45 +00006755 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006756
6757By #1, this is the same as
6758
Tim Peters8bb5ad22003-01-24 02:44:45 +00006759 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006760
6761By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6762Substituting that into [3],
6763
Tim Peters8bb5ad22003-01-24 02:44:45 +00006764 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6765 k - (y+k).s - (y+k).d = 0; rearranging,
6766 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6767 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006768
Tim Peters8bb5ad22003-01-24 02:44:45 +00006769On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6770approximate k by ignoring the (y+k).d term at first. Note that k can't be
6771very large, since all offset-returning methods return a duration of magnitude
6772less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6773be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006774
6775In any case, the new value is
6776
Tim Peters8bb5ad22003-01-24 02:44:45 +00006777 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006778
Tim Peters8bb5ad22003-01-24 02:44:45 +00006779It's helpful to step back at look at [4] from a higher level: it's simply
6780mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006781
6782At this point, if
6783
Tim Peters8bb5ad22003-01-24 02:44:45 +00006784 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006785
6786we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006787at the start of daylight time. Picture US Eastern for concreteness. The wall
6788time 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 +00006789sense then. The docs ask that an Eastern tzinfo class consider such a time to
6790be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6791on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006792the only spelling that makes sense on the local wall clock.
6793
Tim Petersc5dc4da2003-01-02 17:55:03 +00006794In fact, if [5] holds at this point, we do have the standard-time spelling,
6795but that takes a bit of proof. We first prove a stronger result. What's the
6796difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006797
Tim Peters8bb5ad22003-01-24 02:44:45 +00006798 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006799
Tim Petersc5dc4da2003-01-02 17:55:03 +00006800Now
6801 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006802 (y + y.s).n = by #5
6803 y.n + y.s = since y.n = x.n
6804 x.n + y.s = since z and y are have the same tzinfo member,
6805 y.s = z.s by #2
6806 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006807
Tim Petersc5dc4da2003-01-02 17:55:03 +00006808Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006809
Tim Petersc5dc4da2003-01-02 17:55:03 +00006810 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006811 x.n - ((x.n + z.s) - z.o) = expanding
6812 x.n - x.n - z.s + z.o = cancelling
6813 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006814 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006815
Tim Petersc5dc4da2003-01-02 17:55:03 +00006816So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006817
Tim Petersc5dc4da2003-01-02 17:55:03 +00006818If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006819spelling we wanted in the endcase described above. We're done. Contrarily,
6820if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006821
Tim Petersc5dc4da2003-01-02 17:55:03 +00006822If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6823add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006824local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006825
Tim Petersc5dc4da2003-01-02 17:55:03 +00006826Let
Tim Petersf3615152003-01-01 21:51:37 +00006827
Tim Peters4fede1a2003-01-04 00:26:59 +00006828 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006829
Tim Peters4fede1a2003-01-04 00:26:59 +00006830and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006831
Tim Peters8bb5ad22003-01-24 02:44:45 +00006832 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006833
Tim Peters8bb5ad22003-01-24 02:44:45 +00006834If so, we're done. If not, the tzinfo class is insane, according to the
6835assumptions we've made. This also requires a bit of proof. As before, let's
6836compute the difference between the LHS and RHS of [8] (and skipping some of
6837the justifications for the kinds of substitutions we've done several times
6838already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006839
Tim Peters8bb5ad22003-01-24 02:44:45 +00006840 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006841 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6842 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6843 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6844 - z.n + z.n - z.o + z'.o = cancel z.n
6845 - z.o + z'.o = #1 twice
6846 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6847 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006848
6849So 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 +00006850we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6851return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006852
Tim Peters8bb5ad22003-01-24 02:44:45 +00006853How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6854a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6855would have to change the result dst() returns: we start in DST, and moving
6856a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006857
Tim Peters8bb5ad22003-01-24 02:44:45 +00006858There isn't a sane case where this can happen. The closest it gets is at
6859the end of DST, where there's an hour in UTC with no spelling in a hybrid
6860tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6861that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6862UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6863time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6864clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6865standard time. Since that's what the local clock *does*, we want to map both
6866UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006867in local time, but so it goes -- it's the way the local clock works.
6868
Tim Peters8bb5ad22003-01-24 02:44:45 +00006869When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6870so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6871z' = 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 +00006872(correctly) concludes that z' is not UTC-equivalent to x.
6873
6874Because we know z.d said z was in daylight time (else [5] would have held and
6875we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006876and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006877return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6878but the reasoning doesn't depend on the example -- it depends on there being
6879two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006880z' must be in standard time, and is the spelling we want in this case.
6881
6882Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6883concerned (because it takes z' as being in standard time rather than the
6884daylight time we intend here), but returning it gives the real-life "local
6885clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6886tz.
6887
6888When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6889the 1:MM standard time spelling we want.
6890
6891So how can this break? One of the assumptions must be violated. Two
6892possibilities:
6893
68941) [2] effectively says that y.s is invariant across all y belong to a given
6895 time zone. This isn't true if, for political reasons or continental drift,
6896 a region decides to change its base offset from UTC.
6897
68982) There may be versions of "double daylight" time where the tail end of
6899 the analysis gives up a step too early. I haven't thought about that
6900 enough to say.
6901
6902In any case, it's clear that the default fromutc() is strong enough to handle
6903"almost all" time zones: so long as the standard offset is invariant, it
6904doesn't matter if daylight time transition points change from year to year, or
6905if daylight time is skipped in some years; it doesn't matter how large or
6906small dst() may get within its bounds; and it doesn't even matter if some
6907perverse time zone returns a negative dst()). So a breaking case must be
6908pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006909--------------------------------------------------------------------------- */