blob: 74a54e74ae0fec93fe10bcb488f333c74fc3933a [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"
Victor Stinner04fc4f22020-06-16 01:28:07 +020011#include "pycore_object.h" // _PyObject_Init()
Paul Ganssle0d126722018-11-13 03:02:25 -050012#include "datetime.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020013#include "structmember.h" // PyMemberDef
Tim Peters2a799bf2002-12-16 20:18:38 +000014
15#include <time.h>
16
Victor Stinner09e5cf22015-03-30 00:09:18 +020017#ifdef MS_WINDOWS
18# include <winsock2.h> /* struct timeval */
19#endif
20
Paul Ganssle0d126722018-11-13 03:02:25 -050021#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090022#define PyDate_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateType)
Paul Ganssle0d126722018-11-13 03:02:25 -050023
24#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090025#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateTimeType)
Paul Ganssle0d126722018-11-13 03:02:25 -050026
27#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090028#define PyTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TimeType)
Paul Ganssle0d126722018-11-13 03:02:25 -050029
30#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090031#define PyDelta_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DeltaType)
Paul Ganssle0d126722018-11-13 03:02:25 -050032
33#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090034#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TZInfoType)
Paul Ganssle0d126722018-11-13 03:02:25 -050035
Pablo Galindo4be11c02019-08-22 20:24:25 +010036#define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType)
Tim Peters2a799bf2002-12-16 20:18:38 +000037
Larry Hastings61272b72014-01-07 12:41:53 -080038/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080039module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080040class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +020041class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType"
Paul Ganssle1b97b9b2020-05-16 10:02:59 -040042class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCalendarDateType"
Larry Hastings61272b72014-01-07 12:41:53 -080043[clinic start generated code]*/
Paul Ganssle1b97b9b2020-05-16 10:02:59 -040044/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81bec0fa19837f63]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080045
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030046#include "clinic/_datetimemodule.c.h"
47
Tim Peters2a799bf2002-12-16 20:18:38 +000048/* We require that C int be at least 32 bits, and use int virtually
49 * everywhere. In just a few cases we use a temp long, where a Python
50 * API returns a C long. In such cases, we have to ensure that the
51 * final result fits in a C int (this can be an issue on 64-bit boxes).
52 */
53#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000054# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000055#endif
56
57#define MINYEAR 1
58#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000059#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000060
61/* Nine decimal digits is easy to communicate, and leaves enough room
62 * so that two delta days can be added w/o fear of overflowing a signed
63 * 32-bit int, and with plenty of room left over to absorb any possible
64 * carries from adding seconds.
65 */
66#define MAX_DELTA_DAYS 999999999
67
68/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069#define GET_YEAR PyDateTime_GET_YEAR
70#define GET_MONTH PyDateTime_GET_MONTH
71#define GET_DAY PyDateTime_GET_DAY
72#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
73#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
74#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
75#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040076#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000077
78/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
80 ((o)->data[1] = ((v) & 0x00ff)))
81#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
82#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000083
84/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
86#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
87#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
88#define DATE_SET_MICROSECOND(o, v) \
89 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
90 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
91 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040092#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000093
94/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
96#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
97#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
98#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040099#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
101#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
102#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
103#define TIME_SET_MICROSECOND(o, v) \
104 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
105 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
106 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400107#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000108
109/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
111#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
112#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114#define SET_TD_DAYS(o, v) ((o)->days = (v))
115#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000116#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
117
Tim Petersa032d2e2003-01-11 00:15:54 +0000118/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
119 * p->hastzinfo.
120 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000121#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
122#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
123 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
124#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
125 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000126/* M is a char or int claiming to be a valid month. The macro is equivalent
127 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000129 */
130#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
131
Tim Peters2a799bf2002-12-16 20:18:38 +0000132/* Forward declarations. */
133static PyTypeObject PyDateTime_DateType;
134static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000135static PyTypeObject PyDateTime_DeltaType;
Paul Ganssle1b97b9b2020-05-16 10:02:59 -0400136static PyTypeObject PyDateTime_IsoCalendarDateType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000137static PyTypeObject PyDateTime_TimeType;
138static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000139static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000140
Victor Stinnerb67f0962017-02-10 10:34:02 +0100141static int check_tzinfo_subclass(PyObject *p);
142
Martin v. Löwise75fc142013-11-07 18:46:53 +0100143_Py_IDENTIFIER(as_integer_ratio);
144_Py_IDENTIFIER(fromutc);
145_Py_IDENTIFIER(isoformat);
146_Py_IDENTIFIER(strftime);
147
Tim Peters2a799bf2002-12-16 20:18:38 +0000148/* ---------------------------------------------------------------------------
149 * Math utilities.
150 */
151
152/* k = i+j overflows iff k differs in sign from both inputs,
153 * iff k^i has sign bit set and k^j has sign bit set,
154 * iff (k^i)&(k^j) has sign bit set.
155 */
156#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000158
159/* Compute Python divmod(x, y), returning the quotient and storing the
160 * remainder into *r. The quotient is the floor of x/y, and that's
161 * the real point of this. C will probably truncate instead (C99
162 * requires truncation; C89 left it implementation-defined).
163 * Simplification: we *require* that y > 0 here. That's appropriate
164 * for all the uses made of it. This simplifies the code and makes
165 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
166 * overflow case).
167 */
168static int
169divmod(int x, int y, int *r)
170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 assert(y > 0);
174 quo = x / y;
175 *r = x - quo * y;
176 if (*r < 0) {
177 --quo;
178 *r += y;
179 }
180 assert(0 <= *r && *r < y);
181 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000182}
183
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000184/* Nearest integer to m / n for integers m and n. Half-integer results
185 * are rounded to even.
186 */
187static PyObject *
188divide_nearest(PyObject *m, PyObject *n)
189{
190 PyObject *result;
191 PyObject *temp;
192
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000193 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000194 if (temp == NULL)
195 return NULL;
196 result = PyTuple_GET_ITEM(temp, 0);
197 Py_INCREF(result);
198 Py_DECREF(temp);
199
200 return result;
201}
202
Tim Peters2a799bf2002-12-16 20:18:38 +0000203/* ---------------------------------------------------------------------------
204 * General calendrical helper functions
205 */
206
207/* For each month ordinal in 1..12, the number of days in that month,
208 * and the number of days before that month in the same year. These
209 * are correct for non-leap years only.
210 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200211static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 0, /* unused; this vector uses 1-based indexing */
213 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000214};
215
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200216static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 0, /* unused; this vector uses 1-based indexing */
218 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000219};
220
221/* year -> 1 if leap year, else 0. */
222static int
223is_leap(int year)
224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 /* Cast year to unsigned. The result is the same either way, but
226 * C can generate faster code for unsigned mod than for signed
227 * mod (especially for % 4 -- a good compiler should just grab
228 * the last 2 bits when the LHS is unsigned).
229 */
230 const unsigned int ayear = (unsigned int)year;
231 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000232}
233
234/* year, month -> number of days in that month in that year */
235static int
236days_in_month(int year, int month)
237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 assert(month >= 1);
239 assert(month <= 12);
240 if (month == 2 && is_leap(year))
241 return 29;
242 else
243 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000244}
245
Martin Panter46f50722016-05-26 05:35:26 +0000246/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000247static int
248days_before_month(int year, int month)
249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 assert(month >= 1);
253 assert(month <= 12);
254 days = _days_before_month[month];
255 if (month > 2 && is_leap(year))
256 ++days;
257 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000258}
259
260/* year -> number of days before January 1st of year. Remember that we
261 * start with year 1, so days_before_year(1) == 0.
262 */
263static int
264days_before_year(int year)
265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 int y = year - 1;
267 /* This is incorrect if year <= 0; we really want the floor
268 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000269 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000271 assert (year >= 1);
272 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000273}
274
275/* Number of days in 4, 100, and 400 year cycles. That these have
276 * the correct values is asserted in the module init function.
277 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278#define DI4Y 1461 /* days_before_year(5); days in 4 years */
279#define DI100Y 36524 /* days_before_year(101); days in 100 years */
280#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000281
282/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
283static void
284ord_to_ymd(int ordinal, int *year, int *month, int *day)
285{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
289 * leap years repeats exactly every 400 years. The basic strategy is
290 * to find the closest 400-year boundary at or before ordinal, then
291 * work with the offset from that boundary to ordinal. Life is much
292 * clearer if we subtract 1 from ordinal first -- then the values
293 * of ordinal at 400-year boundaries are exactly those divisible
294 * by DI400Y:
295 *
296 * D M Y n n-1
297 * -- --- ---- ---------- ----------------
298 * 31 Dec -400 -DI400Y -DI400Y -1
299 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
300 * ...
301 * 30 Dec 000 -1 -2
302 * 31 Dec 000 0 -1
303 * 1 Jan 001 1 0 400-year boundary
304 * 2 Jan 001 2 1
305 * 3 Jan 001 3 2
306 * ...
307 * 31 Dec 400 DI400Y DI400Y -1
308 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
309 */
310 assert(ordinal >= 1);
311 --ordinal;
312 n400 = ordinal / DI400Y;
313 n = ordinal % DI400Y;
314 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 /* Now n is the (non-negative) offset, in days, from January 1 of
317 * year, to the desired date. Now compute how many 100-year cycles
318 * precede n.
319 * Note that it's possible for n100 to equal 4! In that case 4 full
320 * 100-year cycles precede the desired day, which implies the
321 * desired day is December 31 at the end of a 400-year cycle.
322 */
323 n100 = n / DI100Y;
324 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 /* Now compute how many 4-year cycles precede it. */
327 n4 = n / DI4Y;
328 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 /* And now how many single years. Again n1 can be 4, and again
331 * meaning that the desired day is December 31 at the end of the
332 * 4-year cycle.
333 */
334 n1 = n / 365;
335 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 *year += n100 * 100 + n4 * 4 + n1;
338 if (n1 == 4 || n100 == 4) {
339 assert(n == 0);
340 *year -= 1;
341 *month = 12;
342 *day = 31;
343 return;
344 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 /* Now the year is correct, and n is the offset from January 1. We
347 * find the month via an estimate that's either exact or one too
348 * large.
349 */
350 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
351 assert(leapyear == is_leap(*year));
352 *month = (n + 50) >> 5;
353 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
354 if (preceding > n) {
355 /* estimate is too large */
356 *month -= 1;
357 preceding -= days_in_month(*year, *month);
358 }
359 n -= preceding;
360 assert(0 <= n);
361 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000364}
365
366/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
367static int
368ymd_to_ord(int year, int month, int day)
369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000371}
372
373/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
374static int
375weekday(int year, int month, int day)
376{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000378}
379
380/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
381 * first calendar week containing a Thursday.
382 */
383static int
384iso_week1_monday(int year)
385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
387 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
388 int first_weekday = (first_day + 6) % 7;
389 /* ordinal of closest Monday at or before 1/1 */
390 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
393 week1_monday += 7;
394 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000395}
396
397/* ---------------------------------------------------------------------------
398 * Range checkers.
399 */
400
401/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
402 * If not, raise OverflowError and return -1.
403 */
404static int
405check_delta_day_range(int days)
406{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
408 return 0;
409 PyErr_Format(PyExc_OverflowError,
410 "days=%d; must have magnitude <= %d",
411 days, MAX_DELTA_DAYS);
412 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000413}
414
415/* Check that date arguments are in range. Return 0 if they are. If they
416 * aren't, raise ValueError and return -1.
417 */
418static int
419check_date_args(int year, int month, int day)
420{
421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 if (year < MINYEAR || year > MAXYEAR) {
Victor Stinnerb67f0962017-02-10 10:34:02 +0100423 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 return -1;
425 }
426 if (month < 1 || month > 12) {
427 PyErr_SetString(PyExc_ValueError,
428 "month must be in 1..12");
429 return -1;
430 }
431 if (day < 1 || day > days_in_month(year, month)) {
432 PyErr_SetString(PyExc_ValueError,
433 "day is out of range for month");
434 return -1;
435 }
436 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000437}
438
439/* Check that time arguments are in range. Return 0 if they are. If they
440 * aren't, raise ValueError and return -1.
441 */
442static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400443check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 if (h < 0 || h > 23) {
446 PyErr_SetString(PyExc_ValueError,
447 "hour must be in 0..23");
448 return -1;
449 }
450 if (m < 0 || m > 59) {
451 PyErr_SetString(PyExc_ValueError,
452 "minute must be in 0..59");
453 return -1;
454 }
455 if (s < 0 || s > 59) {
456 PyErr_SetString(PyExc_ValueError,
457 "second must be in 0..59");
458 return -1;
459 }
460 if (us < 0 || us > 999999) {
461 PyErr_SetString(PyExc_ValueError,
462 "microsecond must be in 0..999999");
463 return -1;
464 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400465 if (fold != 0 && fold != 1) {
466 PyErr_SetString(PyExc_ValueError,
467 "fold must be either 0 or 1");
468 return -1;
469 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000471}
472
473/* ---------------------------------------------------------------------------
474 * Normalization utilities.
475 */
476
477/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
478 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
479 * at least factor, enough of *lo is converted into "hi" units so that
480 * 0 <= *lo < factor. The input values must be such that int overflow
481 * is impossible.
482 */
483static void
484normalize_pair(int *hi, int *lo, int factor)
485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 assert(factor > 0);
487 assert(lo != hi);
488 if (*lo < 0 || *lo >= factor) {
489 const int num_hi = divmod(*lo, factor, lo);
490 const int new_hi = *hi + num_hi;
491 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
492 *hi = new_hi;
493 }
494 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000495}
496
497/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 * 0 <= *s < 24*3600
499 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000500 * The input values must be such that the internals don't overflow.
501 * The way this routine is used, we don't get close.
502 */
503static void
504normalize_d_s_us(int *d, int *s, int *us)
505{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 if (*us < 0 || *us >= 1000000) {
507 normalize_pair(s, us, 1000000);
508 /* |s| can't be bigger than about
509 * |original s| + |original us|/1000000 now.
510 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 }
513 if (*s < 0 || *s >= 24*3600) {
514 normalize_pair(d, s, 24*3600);
515 /* |d| can't be bigger than about
516 * |original d| +
517 * (|original s| + |original us|/1000000) / (24*3600) now.
518 */
519 }
520 assert(0 <= *s && *s < 24*3600);
521 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000522}
523
524/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 * 1 <= *m <= 12
526 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000527 * The input values must be such that the internals don't overflow.
528 * The way this routine is used, we don't get close.
529 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000530static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000531normalize_y_m_d(int *y, int *m, int *d)
532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000534
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000535 /* In actual use, m is always the month component extracted from a
536 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 /* Now only day can be out of bounds (year may also be out of bounds
542 * for a datetime object, but we don't care about that here).
543 * If day is out of bounds, what to do is arguable, but at least the
544 * method here is principled and explainable.
545 */
546 dim = days_in_month(*y, *m);
547 if (*d < 1 || *d > dim) {
548 /* Move day-1 days from the first of the month. First try to
549 * get off cheap if we're only one day out of range
550 * (adjustments for timezone alone can't be worse than that).
551 */
552 if (*d == 0) {
553 --*m;
554 if (*m > 0)
555 *d = days_in_month(*y, *m);
556 else {
557 --*y;
558 *m = 12;
559 *d = 31;
560 }
561 }
562 else if (*d == dim + 1) {
563 /* move forward a day */
564 ++*m;
565 *d = 1;
566 if (*m > 12) {
567 *m = 1;
568 ++*y;
569 }
570 }
571 else {
572 int ordinal = ymd_to_ord(*y, *m, 1) +
573 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000574 if (ordinal < 1 || ordinal > MAXORDINAL) {
575 goto error;
576 } else {
577 ord_to_ymd(ordinal, y, m, d);
578 return 0;
579 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 }
581 }
582 assert(*m > 0);
583 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000584 if (MINYEAR <= *y && *y <= MAXYEAR)
585 return 0;
586 error:
587 PyErr_SetString(PyExc_OverflowError,
588 "date value out of range");
589 return -1;
590
Tim Peters2a799bf2002-12-16 20:18:38 +0000591}
592
593/* Fiddle out-of-bounds months and days so that the result makes some kind
594 * of sense. The parameters are both inputs and outputs. Returns < 0 on
595 * failure, where failure means the adjusted year is out of bounds.
596 */
597static int
598normalize_date(int *year, int *month, int *day)
599{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000600 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000601}
602
603/* Force all the datetime fields into range. The parameters are both
604 * inputs and outputs. Returns < 0 on error.
605 */
606static int
607normalize_datetime(int *year, int *month, int *day,
608 int *hour, int *minute, int *second,
609 int *microsecond)
610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 normalize_pair(second, microsecond, 1000000);
612 normalize_pair(minute, second, 60);
613 normalize_pair(hour, minute, 60);
614 normalize_pair(day, hour, 24);
615 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000616}
617
618/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000619 * Basic object allocation: tp_alloc implementations. These allocate
620 * Python objects of the right size and type, and do the Python object-
621 * initialization bit. If there's not enough memory, they return NULL after
622 * setting MemoryError. All data members remain uninitialized trash.
623 *
624 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000625 * member is needed. This is ugly, imprecise, and possibly insecure.
626 * tp_basicsize for the time and datetime types is set to the size of the
627 * struct that has room for the tzinfo member, so subclasses in Python will
628 * allocate enough space for a tzinfo member whether or not one is actually
629 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
630 * part is that PyType_GenericAlloc() (which subclasses in Python end up
631 * using) just happens today to effectively ignore the nitems argument
632 * when tp_itemsize is 0, which it is for these type objects. If that
633 * changes, perhaps the callers of tp_alloc slots in this file should
634 * be changed to force a 0 nitems argument unless the type being allocated
635 * is a base type implemented in this file (so that tp_alloc is time_alloc
636 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000637 */
638
639static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000640time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000641{
Victor Stinner04fc4f22020-06-16 01:28:07 +0200642 size_t size = aware ? sizeof(PyDateTime_Time) : sizeof(_PyDateTime_BaseTime);
643 PyObject *self = (PyObject *)PyObject_Malloc(size);
644 if (self == NULL) {
645 return PyErr_NoMemory();
646 }
647 _PyObject_Init(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000649}
650
651static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000652datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000653{
Victor Stinner04fc4f22020-06-16 01:28:07 +0200654 size_t size = aware ? sizeof(PyDateTime_DateTime) : sizeof(_PyDateTime_BaseDateTime);
655 PyObject *self = (PyObject *)PyObject_Malloc(size);
656 if (self == NULL) {
657 return PyErr_NoMemory();
658 }
659 _PyObject_Init(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000661}
662
663/* ---------------------------------------------------------------------------
664 * Helpers for setting object fields. These work on pointers to the
665 * appropriate base class.
666 */
667
668/* For date and datetime. */
669static void
670set_date_fields(PyDateTime_Date *self, int y, int m, int d)
671{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 self->hashcode = -1;
673 SET_YEAR(self, y);
674 SET_MONTH(self, m);
675 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000676}
677
678/* ---------------------------------------------------------------------------
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500679 * String parsing utilities and helper functions
680 */
681
Paul Ganssle3df85402018-10-22 12:32:52 -0400682static const char *
683parse_digits(const char *ptr, int *var, size_t num_digits)
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500684{
685 for (size_t i = 0; i < num_digits; ++i) {
686 unsigned int tmp = (unsigned int)(*(ptr++) - '0');
687 if (tmp > 9) {
688 return NULL;
689 }
690 *var *= 10;
691 *var += (signed int)tmp;
692 }
693
694 return ptr;
695}
696
Paul Ganssle3df85402018-10-22 12:32:52 -0400697static int
698parse_isoformat_date(const char *dtstr, int *year, int *month, int *day)
699{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500700 /* Parse the date components of the result of date.isoformat()
Paul Ganssle3df85402018-10-22 12:32:52 -0400701 *
702 * Return codes:
703 * 0: Success
704 * -1: Failed to parse date component
705 * -2: Failed to parse dateseparator
706 */
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500707 const char *p = dtstr;
708 p = parse_digits(p, year, 4);
709 if (NULL == p) {
710 return -1;
711 }
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100712
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500713 if (*(p++) != '-') {
714 return -2;
715 }
716
717 p = parse_digits(p, month, 2);
718 if (NULL == p) {
719 return -1;
720 }
721
722 if (*(p++) != '-') {
723 return -2;
724 }
725
726 p = parse_digits(p, day, 2);
727 if (p == NULL) {
728 return -1;
729 }
730
731 return 0;
732}
733
734static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400735parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
736 int *minute, int *second, int *microsecond)
737{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500738 const char *p = tstr;
739 const char *p_end = tstr_end;
740 int *vals[3] = {hour, minute, second};
741
742 // Parse [HH[:MM[:SS]]]
743 for (size_t i = 0; i < 3; ++i) {
744 p = parse_digits(p, vals[i], 2);
745 if (NULL == p) {
746 return -3;
747 }
748
749 char c = *(p++);
750 if (p >= p_end) {
751 return c != '\0';
Paul Ganssle3df85402018-10-22 12:32:52 -0400752 }
753 else if (c == ':') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500754 continue;
Paul Ganssle3df85402018-10-22 12:32:52 -0400755 }
756 else if (c == '.') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500757 break;
Paul Ganssle3df85402018-10-22 12:32:52 -0400758 }
759 else {
760 return -4; // Malformed time separator
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500761 }
762 }
763
764 // Parse .fff[fff]
765 size_t len_remains = p_end - p;
766 if (!(len_remains == 6 || len_remains == 3)) {
767 return -3;
768 }
769
770 p = parse_digits(p, microsecond, len_remains);
771 if (NULL == p) {
772 return -3;
773 }
774
775 if (len_remains == 3) {
776 *microsecond *= 1000;
777 }
778
779 // Return 1 if it's not the end of the string
780 return *p != '\0';
781}
782
783static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400784parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
785 int *second, int *microsecond, int *tzoffset,
786 int *tzmicrosecond)
787{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500788 // Parse the time portion of a datetime.isoformat() string
789 //
790 // Return codes:
791 // 0: Success (no tzoffset)
792 // 1: Success (with tzoffset)
793 // -3: Failed to parse time component
794 // -4: Failed to parse time separator
795 // -5: Malformed timezone string
796
797 const char *p = dtstr;
798 const char *p_end = dtstr + dtlen;
799
800 const char *tzinfo_pos = p;
801 do {
802 if (*tzinfo_pos == '+' || *tzinfo_pos == '-') {
803 break;
804 }
Paul Ganssle3df85402018-10-22 12:32:52 -0400805 } while (++tzinfo_pos < p_end);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500806
Paul Ganssle3df85402018-10-22 12:32:52 -0400807 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second,
808 microsecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500809
810 if (rv < 0) {
811 return rv;
Paul Ganssle3df85402018-10-22 12:32:52 -0400812 }
813 else if (tzinfo_pos == p_end) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500814 // We know that there's no time zone, so if there's stuff at the
815 // end of the string it's an error.
816 if (rv == 1) {
817 return -5;
Paul Ganssle3df85402018-10-22 12:32:52 -0400818 }
819 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500820 return 0;
821 }
822 }
823
824 // Parse time zone component
825 // Valid formats are:
826 // - +HH:MM (len 6)
827 // - +HH:MM:SS (len 9)
828 // - +HH:MM:SS.ffffff (len 16)
829 size_t tzlen = p_end - tzinfo_pos;
830 if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) {
831 return -5;
832 }
833
Paul Ganssle3df85402018-10-22 12:32:52 -0400834 int tzsign = (*tzinfo_pos == '-') ? -1 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500835 tzinfo_pos++;
836 int tzhour = 0, tzminute = 0, tzsecond = 0;
Paul Ganssle3df85402018-10-22 12:32:52 -0400837 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond,
838 tzmicrosecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500839
840 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
841 *tzmicrosecond *= tzsign;
842
Paul Ganssle3df85402018-10-22 12:32:52 -0400843 return rv ? -5 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500844}
845
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500846/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000847 * Create various objects, mostly without range checking.
848 */
849
850/* Create a date instance with no range checking. */
851static PyObject *
852new_date_ex(int year, int month, int day, PyTypeObject *type)
853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000855
Victor Stinnerb67f0962017-02-10 10:34:02 +0100856 if (check_date_args(year, month, day) < 0) {
857 return NULL;
858 }
859
Paul Ganssle3df85402018-10-22 12:32:52 -0400860 self = (PyDateTime_Date *)(type->tp_alloc(type, 0));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 if (self != NULL)
862 set_date_fields(self, year, month, day);
Paul Ganssle3df85402018-10-22 12:32:52 -0400863 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000864}
865
866#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000868
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500869// Forward declaration
Paul Ganssle3df85402018-10-22 12:32:52 -0400870static PyObject *
871new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500872
873/* Create date instance with no range checking, or call subclass constructor */
874static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -0400875new_date_subclass_ex(int year, int month, int day, PyObject *cls)
876{
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500877 PyObject *result;
878 // We have "fast path" constructors for two subclasses: date and datetime
879 if ((PyTypeObject *)cls == &PyDateTime_DateType) {
880 result = new_date_ex(year, month, day, (PyTypeObject *)cls);
Paul Ganssle3df85402018-10-22 12:32:52 -0400881 }
882 else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500883 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
884 (PyTypeObject *)cls);
Paul Ganssle3df85402018-10-22 12:32:52 -0400885 }
886 else {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500887 result = PyObject_CallFunction(cls, "iii", year, month, day);
888 }
889
890 return result;
891}
892
Tim Petersb0c854d2003-05-17 15:57:00 +0000893/* Create a datetime instance with no range checking. */
894static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400895new_datetime_ex2(int year, int month, int day, int hour, int minute,
896 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 PyDateTime_DateTime *self;
899 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000900
Victor Stinnerb67f0962017-02-10 10:34:02 +0100901 if (check_date_args(year, month, day) < 0) {
902 return NULL;
903 }
904 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
905 return NULL;
906 }
907 if (check_tzinfo_subclass(tzinfo) < 0) {
908 return NULL;
909 }
910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
912 if (self != NULL) {
913 self->hastzinfo = aware;
914 set_date_fields((PyDateTime_Date *)self, year, month, day);
915 DATE_SET_HOUR(self, hour);
916 DATE_SET_MINUTE(self, minute);
917 DATE_SET_SECOND(self, second);
918 DATE_SET_MICROSECOND(self, usecond);
919 if (aware) {
920 Py_INCREF(tzinfo);
921 self->tzinfo = tzinfo;
922 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400923 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 }
925 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000926}
927
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400928static PyObject *
929new_datetime_ex(int year, int month, int day, int hour, int minute,
930 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
931{
932 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
933 tzinfo, 0, type);
934}
935
936#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
937 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000939
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500940static PyObject *
941new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
942 int second, int usecond, PyObject *tzinfo,
943 int fold, PyObject *cls) {
944 PyObject* dt;
945 if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) {
946 // Use the fast path constructor
947 dt = new_datetime(year, month, day, hour, minute, second, usecond,
948 tzinfo, fold);
949 } else {
950 // Subclass
951 dt = PyObject_CallFunction(cls, "iiiiiiiO",
952 year,
953 month,
954 day,
955 hour,
956 minute,
957 second,
958 usecond,
959 tzinfo);
960 }
961
962 return dt;
963}
964
965static PyObject *
966new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
967 int second, int usecond, PyObject *tzinfo,
968 PyObject *cls) {
969 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
970 second, usecond, tzinfo, 0,
971 cls);
972}
973
Tim Petersb0c854d2003-05-17 15:57:00 +0000974/* Create a time instance with no range checking. */
975static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400976new_time_ex2(int hour, int minute, int second, int usecond,
977 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000978{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 PyDateTime_Time *self;
980 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000981
Victor Stinnerb67f0962017-02-10 10:34:02 +0100982 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
983 return NULL;
984 }
985 if (check_tzinfo_subclass(tzinfo) < 0) {
986 return NULL;
987 }
988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
990 if (self != NULL) {
991 self->hastzinfo = aware;
992 self->hashcode = -1;
993 TIME_SET_HOUR(self, hour);
994 TIME_SET_MINUTE(self, minute);
995 TIME_SET_SECOND(self, second);
996 TIME_SET_MICROSECOND(self, usecond);
997 if (aware) {
998 Py_INCREF(tzinfo);
999 self->tzinfo = tzinfo;
1000 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001001 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 }
1003 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001004}
1005
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001006static PyObject *
1007new_time_ex(int hour, int minute, int second, int usecond,
1008 PyObject *tzinfo, PyTypeObject *type)
1009{
1010 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
1011}
1012
1013#define new_time(hh, mm, ss, us, tzinfo, fold) \
1014 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001015
1016/* Create a timedelta instance. Normalize the members iff normalize is
1017 * true. Passing false is a speed optimization, if you know for sure
1018 * that seconds and microseconds are already in their proper ranges. In any
1019 * case, raises OverflowError and returns NULL if the normalized days is out
1020 * of range).
1021 */
1022static PyObject *
1023new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +00001025{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 if (normalize)
1029 normalize_d_s_us(&days, &seconds, &microseconds);
1030 assert(0 <= seconds && seconds < 24*3600);
1031 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +00001032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 if (check_delta_day_range(days) < 0)
1034 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +00001035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1037 if (self != NULL) {
1038 self->hashcode = -1;
1039 SET_TD_DAYS(self, days);
1040 SET_TD_SECONDS(self, seconds);
1041 SET_TD_MICROSECONDS(self, microseconds);
1042 }
1043 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001044}
1045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046#define new_delta(d, s, us, normalize) \
1047 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001048
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001049
1050typedef struct
1051{
1052 PyObject_HEAD
1053 PyObject *offset;
1054 PyObject *name;
1055} PyDateTime_TimeZone;
1056
Victor Stinner6ced7c42011-03-21 18:15:42 +01001057/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001058static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -04001059/* The interned Epoch datetime instance */
1060static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00001061
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001062/* Create new timezone instance checking offset range. This
1063 function does not check the name argument. Caller must assure
1064 that offset is a timedelta instance and name is either NULL
1065 or a unicode object. */
1066static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001067create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001068{
1069 PyDateTime_TimeZone *self;
1070 PyTypeObject *type = &PyDateTime_TimeZoneType;
1071
1072 assert(offset != NULL);
1073 assert(PyDelta_Check(offset));
1074 assert(name == NULL || PyUnicode_Check(name));
1075
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001076 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1077 if (self == NULL) {
1078 return NULL;
1079 }
1080 Py_INCREF(offset);
1081 self->offset = offset;
1082 Py_XINCREF(name);
1083 self->name = name;
1084 return (PyObject *)self;
1085}
1086
1087static int delta_bool(PyDateTime_Delta *self);
1088
1089static PyObject *
1090new_timezone(PyObject *offset, PyObject *name)
1091{
1092 assert(offset != NULL);
1093 assert(PyDelta_Check(offset));
1094 assert(name == NULL || PyUnicode_Check(name));
1095
1096 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
1097 Py_INCREF(PyDateTime_TimeZone_UTC);
1098 return PyDateTime_TimeZone_UTC;
1099 }
Ngalim Siregar92c7e302019-08-09 21:22:16 +07001100 if ((GET_TD_DAYS(offset) == -1 &&
1101 GET_TD_SECONDS(offset) == 0 &&
1102 GET_TD_MICROSECONDS(offset) < 1) ||
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001103 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1104 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1105 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04001106 " timedelta(hours=24),"
1107 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001108 return NULL;
1109 }
1110
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001111 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001112}
1113
Tim Petersb0c854d2003-05-17 15:57:00 +00001114/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001115 * tzinfo helpers.
1116 */
1117
Tim Peters855fe882002-12-22 03:43:39 +00001118/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
1119 * raise TypeError and return -1.
1120 */
1121static int
1122check_tzinfo_subclass(PyObject *p)
1123{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 if (p == Py_None || PyTZInfo_Check(p))
1125 return 0;
1126 PyErr_Format(PyExc_TypeError,
1127 "tzinfo argument must be None or of a tzinfo subclass, "
1128 "not type '%s'",
1129 Py_TYPE(p)->tp_name);
1130 return -1;
Tim Peters855fe882002-12-22 03:43:39 +00001131}
1132
Tim Peters2a799bf2002-12-16 20:18:38 +00001133/* If self has a tzinfo member, return a BORROWED reference to it. Else
1134 * return NULL, which is NOT AN ERROR. There are no error returns here,
1135 * and the caller must not decref the result.
1136 */
1137static PyObject *
1138get_tzinfo_member(PyObject *self)
1139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 if (PyDateTime_Check(self) && HASTZINFO(self))
1143 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1144 else if (PyTime_Check(self) && HASTZINFO(self))
1145 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001148}
1149
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001150/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
1151 * be an instance of the tzinfo class. If the method returns None, this
1152 * returns None. If the method doesn't return None or timedelta, TypeError is
1153 * raised and this returns NULL. If it returns a timedelta and the value is
1154 * out of range or isn't a whole number of minutes, ValueError is raised and
1155 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +00001156 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001157static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001158call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001159{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001160 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001163 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001165
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001166 if (tzinfo == Py_None)
1167 Py_RETURN_NONE;
1168 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1169 if (offset == Py_None || offset == NULL)
1170 return offset;
1171 if (PyDelta_Check(offset)) {
Ngalim Siregar92c7e302019-08-09 21:22:16 +07001172 if ((GET_TD_DAYS(offset) == -1 &&
1173 GET_TD_SECONDS(offset) == 0 &&
1174 GET_TD_MICROSECONDS(offset) < 1) ||
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001175 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1176 Py_DECREF(offset);
1177 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1178 " strictly between -timedelta(hours=24) and"
1179 " timedelta(hours=24).");
1180 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 }
1182 }
1183 else {
1184 PyErr_Format(PyExc_TypeError,
1185 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001186 "timedelta, not '%.200s'",
1187 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07001188 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001189 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001191
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001192 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001193}
1194
1195/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1196 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
1197 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +00001198 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001199 * If utcoffset() returns an out of range timedelta,
1200 * ValueError is raised and this returns -1. Else *none is
1201 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001202 */
Tim Peters855fe882002-12-22 03:43:39 +00001203static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001204call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1205{
1206 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001207}
1208
Tim Peters2a799bf2002-12-16 20:18:38 +00001209/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1210 * result. tzinfo must be an instance of the tzinfo class. If dst()
1211 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001212 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00001213 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +00001214 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001215 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001216 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001217static PyObject *
1218call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001219{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001220 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001221}
1222
Tim Petersbad8ff02002-12-30 20:52:32 +00001223/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +00001224 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001225 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001226 * returns NULL. If the result is a string, we ensure it is a Unicode
1227 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001228 */
1229static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001230call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001233 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 assert(tzinfo != NULL);
1236 assert(check_tzinfo_subclass(tzinfo) >= 0);
1237 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001240 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001241
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001242 result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001243
1244 if (result == NULL || result == Py_None)
1245 return result;
1246
1247 if (!PyUnicode_Check(result)) {
1248 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1249 "return None or a string, not '%s'",
1250 Py_TYPE(result)->tp_name);
1251 Py_DECREF(result);
1252 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001254
1255 return result;
Tim Peters00237032002-12-27 02:21:51 +00001256}
1257
Tim Peters2a799bf2002-12-16 20:18:38 +00001258/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1259 * stuff
1260 * ", tzinfo=" + repr(tzinfo)
1261 * before the closing ")".
1262 */
1263static PyObject *
1264append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 assert(PyUnicode_Check(repr));
1269 assert(tzinfo);
1270 if (tzinfo == Py_None)
1271 return repr;
1272 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001273 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1274 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 Py_DECREF(repr);
1276 if (temp == NULL)
1277 return NULL;
1278 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1279 Py_DECREF(temp);
1280 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001281}
1282
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001283/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1284 * stuff
1285 * ", fold=" + repr(tzinfo)
1286 * before the closing ")".
1287 */
1288static PyObject *
1289append_keyword_fold(PyObject *repr, int fold)
1290{
1291 PyObject *temp;
1292
1293 assert(PyUnicode_Check(repr));
1294 if (fold == 0)
1295 return repr;
1296 /* Get rid of the trailing ')'. */
1297 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1298 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1299 Py_DECREF(repr);
1300 if (temp == NULL)
1301 return NULL;
1302 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1303 Py_DECREF(temp);
1304 return repr;
1305}
1306
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001307static inline PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04001308tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
1309{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001310 PyObject *tzinfo;
1311 if (rv == 1) {
1312 // Create a timezone from offset in seconds (0 returns UTC)
1313 if (tzoffset == 0) {
1314 Py_INCREF(PyDateTime_TimeZone_UTC);
1315 return PyDateTime_TimeZone_UTC;
1316 }
1317
1318 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001319 if (delta == NULL) {
1320 return NULL;
1321 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001322 tzinfo = new_timezone(delta, NULL);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001323 Py_DECREF(delta);
Paul Ganssle3df85402018-10-22 12:32:52 -04001324 }
1325 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001326 tzinfo = Py_None;
1327 Py_INCREF(Py_None);
1328 }
1329
1330 return tzinfo;
1331}
1332
Tim Peters2a799bf2002-12-16 20:18:38 +00001333/* ---------------------------------------------------------------------------
1334 * String format helpers.
1335 */
1336
1337static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001338format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001339{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001340 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1342 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001343 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1345 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1346 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1351 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1352 GET_DAY(date), hours, minutes, seconds,
1353 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001354}
1355
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001356static PyObject *delta_negative(PyDateTime_Delta *self);
1357
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001358/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001359 * buflen bytes remaining. The UTC offset is gotten by calling
1360 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1361 * *buf, and that's all. Else the returned value is checked for sanity (an
1362 * integer in range), and if that's OK it's converted to an hours & minutes
1363 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001364 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001365 * Returns 0 if everything is OK. If the return value from utcoffset() is
1366 * bogus, an appropriate exception is set and -1 is returned.
1367 */
1368static int
Tim Peters328fff72002-12-20 01:31:27 +00001369format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001371{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001372 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001373 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001377
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001378 offset = call_utcoffset(tzinfo, tzinfoarg);
1379 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001381 if (offset == Py_None) {
1382 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 *buf = '\0';
1384 return 0;
1385 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001386 /* Offset is normalized, so it is negative if days < 0 */
1387 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001389 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001390 if (offset == NULL)
1391 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001393 else {
1394 sign = '+';
1395 }
1396 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001397 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001398 seconds = GET_TD_SECONDS(offset);
1399 Py_DECREF(offset);
1400 minutes = divmod(seconds, 60, &seconds);
1401 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001402 if (microseconds) {
1403 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1404 hours, sep, minutes, sep, seconds, microseconds);
1405 return 0;
1406 }
1407 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001408 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1409 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001410 return 0;
1411 }
1412 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001414}
1415
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001416static PyObject *
1417make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 PyObject *temp;
1420 PyObject *tzinfo = get_tzinfo_member(object);
1421 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001422 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 if (Zreplacement == NULL)
1425 return NULL;
1426 if (tzinfo == Py_None || tzinfo == NULL)
1427 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 assert(tzinfoarg != NULL);
1430 temp = call_tzname(tzinfo, tzinfoarg);
1431 if (temp == NULL)
1432 goto Error;
1433 if (temp == Py_None) {
1434 Py_DECREF(temp);
1435 return Zreplacement;
1436 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 assert(PyUnicode_Check(temp));
1439 /* Since the tzname is getting stuffed into the
1440 * format, we have to double any % signs so that
1441 * strftime doesn't treat them as format codes.
1442 */
1443 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001444 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 Py_DECREF(temp);
1446 if (Zreplacement == NULL)
1447 return NULL;
1448 if (!PyUnicode_Check(Zreplacement)) {
1449 PyErr_SetString(PyExc_TypeError,
1450 "tzname.replace() did not return a string");
1451 goto Error;
1452 }
1453 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001454
1455 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 Py_DECREF(Zreplacement);
1457 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001458}
1459
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001460static PyObject *
1461make_freplacement(PyObject *object)
1462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 char freplacement[64];
1464 if (PyTime_Check(object))
1465 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1466 else if (PyDateTime_Check(object))
1467 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1468 else
1469 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001472}
1473
Tim Peters2a799bf2002-12-16 20:18:38 +00001474/* I sure don't want to reproduce the strftime code from the time module,
1475 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001476 * giving special meanings to the %z, %Z and %f format codes via a
1477 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001478 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1479 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001480 */
1481static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001482wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1488 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1489 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 const char *pin; /* pointer to next char in input format */
1492 Py_ssize_t flen; /* length of input format */
1493 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 PyObject *newfmt = NULL; /* py string, the output format */
1496 char *pnew; /* pointer to available byte in output format */
1497 size_t totalnew; /* number bytes total in output format buffer,
1498 exclusive of trailing \0 */
1499 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 const char *ptoappend; /* ptr to string to append to output buffer */
1502 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 assert(object && format && timetuple);
1505 assert(PyUnicode_Check(format));
1506 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001507 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 if (!pin)
1509 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 /* Scan the input format, looking for %z/%Z/%f escapes, building
1512 * a new format. Since computing the replacements for those codes
1513 * is expensive, don't unless they're actually used.
1514 */
1515 if (flen > INT_MAX - 1) {
1516 PyErr_NoMemory();
1517 goto Done;
1518 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 totalnew = flen + 1; /* realistic if no %z/%Z */
1521 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1522 if (newfmt == NULL) goto Done;
1523 pnew = PyBytes_AsString(newfmt);
1524 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 while ((ch = *pin++) != '\0') {
1527 if (ch != '%') {
1528 ptoappend = pin - 1;
1529 ntoappend = 1;
1530 }
1531 else if ((ch = *pin++) == '\0') {
Victor Stinner2ff58a22019-06-17 14:27:23 +02001532 /* Null byte follows %, copy only '%'.
1533 *
MichaelSaah454b3d42019-01-14 05:23:39 -05001534 * Back the pin up one char so that we catch the null check
1535 * the next time through the loop.*/
1536 pin--;
1537 ptoappend = pin - 1;
1538 ntoappend = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 }
1540 /* A % has been seen and ch is the character after it. */
1541 else if (ch == 'z') {
1542 if (zreplacement == NULL) {
1543 /* format utcoffset */
1544 char buf[100];
1545 PyObject *tzinfo = get_tzinfo_member(object);
1546 zreplacement = PyBytes_FromStringAndSize("", 0);
1547 if (zreplacement == NULL) goto Done;
1548 if (tzinfo != Py_None && tzinfo != NULL) {
1549 assert(tzinfoarg != NULL);
1550 if (format_utcoffset(buf,
1551 sizeof(buf),
1552 "",
1553 tzinfo,
1554 tzinfoarg) < 0)
1555 goto Done;
1556 Py_DECREF(zreplacement);
1557 zreplacement =
1558 PyBytes_FromStringAndSize(buf,
1559 strlen(buf));
1560 if (zreplacement == NULL)
1561 goto Done;
1562 }
1563 }
1564 assert(zreplacement != NULL);
1565 ptoappend = PyBytes_AS_STRING(zreplacement);
1566 ntoappend = PyBytes_GET_SIZE(zreplacement);
1567 }
1568 else if (ch == 'Z') {
1569 /* format tzname */
1570 if (Zreplacement == NULL) {
1571 Zreplacement = make_Zreplacement(object,
1572 tzinfoarg);
1573 if (Zreplacement == NULL)
1574 goto Done;
1575 }
1576 assert(Zreplacement != NULL);
1577 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001578 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001580 if (ptoappend == NULL)
1581 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 }
1583 else if (ch == 'f') {
1584 /* format microseconds */
1585 if (freplacement == NULL) {
1586 freplacement = make_freplacement(object);
1587 if (freplacement == NULL)
1588 goto Done;
1589 }
1590 assert(freplacement != NULL);
1591 assert(PyBytes_Check(freplacement));
1592 ptoappend = PyBytes_AS_STRING(freplacement);
1593 ntoappend = PyBytes_GET_SIZE(freplacement);
1594 }
1595 else {
1596 /* percent followed by neither z nor Z */
1597 ptoappend = pin - 2;
1598 ntoappend = 2;
1599 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 /* Append the ntoappend chars starting at ptoappend to
1602 * the new format.
1603 */
1604 if (ntoappend == 0)
1605 continue;
1606 assert(ptoappend != NULL);
1607 assert(ntoappend > 0);
1608 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001609 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 PyErr_NoMemory();
1611 goto Done;
1612 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001613 totalnew <<= 1;
1614 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 pnew = PyBytes_AsString(newfmt) + usednew;
1617 }
1618 memcpy(pnew, ptoappend, ntoappend);
1619 pnew += ntoappend;
1620 usednew += ntoappend;
1621 assert(usednew <= totalnew);
1622 } /* end while() */
Victor Stinner2ff58a22019-06-17 14:27:23 +02001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1625 goto Done;
1626 {
1627 PyObject *format;
1628 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 if (time == NULL)
1631 goto Done;
1632 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1633 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001634 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1635 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 Py_DECREF(format);
1637 }
1638 Py_DECREF(time);
1639 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001640 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 Py_XDECREF(freplacement);
1642 Py_XDECREF(zreplacement);
1643 Py_XDECREF(Zreplacement);
1644 Py_XDECREF(newfmt);
1645 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001646}
1647
Tim Peters2a799bf2002-12-16 20:18:38 +00001648/* ---------------------------------------------------------------------------
1649 * Wrap functions from the time module. These aren't directly available
1650 * from C. Perhaps they should be.
1651 */
1652
1653/* Call time.time() and return its result (a Python float). */
1654static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001655time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001656{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 PyObject *result = NULL;
1658 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001661 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001662
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001663 result = _PyObject_CallMethodIdNoArgs(time, &PyId_time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 Py_DECREF(time);
1665 }
1666 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001667}
1668
1669/* Build a time.struct_time. The weekday and day number are automatically
1670 * computed from the y,m,d args.
1671 */
1672static PyObject *
1673build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1674{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001676 PyObject *result;
1677 _Py_IDENTIFIER(struct_time);
1678 PyObject *args;
1679
Tim Peters2a799bf2002-12-16 20:18:38 +00001680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001682 if (time == NULL) {
1683 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 }
Victor Stinner2b635972016-12-09 00:38:16 +01001685
1686 args = Py_BuildValue("iiiiiiiii",
1687 y, m, d,
1688 hh, mm, ss,
1689 weekday(y, m, d),
1690 days_before_month(y, m) + d,
1691 dstflag);
1692 if (args == NULL) {
1693 Py_DECREF(time);
1694 return NULL;
1695 }
1696
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001697 result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args);
Victor Stinner2b635972016-12-09 00:38:16 +01001698 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001699 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001701}
1702
1703/* ---------------------------------------------------------------------------
1704 * Miscellaneous helpers.
1705 */
1706
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001707/* The comparisons here all most naturally compute a cmp()-like result.
Tim Peters2a799bf2002-12-16 20:18:38 +00001708 * This little helper turns that into a bool result for rich comparisons.
1709 */
1710static PyObject *
1711diff_to_bool(int diff, int op)
1712{
stratakise8b19652017-11-02 11:32:54 +01001713 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001714}
1715
Tim Peters07534a62003-02-07 22:50:28 +00001716/* Raises a "can't compare" TypeError and returns NULL. */
1717static PyObject *
1718cmperror(PyObject *a, PyObject *b)
1719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 PyErr_Format(PyExc_TypeError,
1721 "can't compare %s to %s",
1722 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1723 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001724}
1725
Tim Peters2a799bf2002-12-16 20:18:38 +00001726/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001727 * Cached Python objects; these are set by the module init function.
1728 */
1729
1730/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731static PyObject *us_per_ms = NULL; /* 1000 */
1732static PyObject *us_per_second = NULL; /* 1000000 */
1733static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001734static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1735static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1736static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001737static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1738
Tim Peters2a799bf2002-12-16 20:18:38 +00001739/* ---------------------------------------------------------------------------
1740 * Class implementations.
1741 */
1742
1743/*
1744 * PyDateTime_Delta implementation.
1745 */
1746
1747/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001749 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001750 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1751 * due to ubiquitous overflow possibilities.
1752 */
1753static PyObject *
1754delta_to_microseconds(PyDateTime_Delta *self)
1755{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 PyObject *x1 = NULL;
1757 PyObject *x2 = NULL;
1758 PyObject *x3 = NULL;
1759 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1762 if (x1 == NULL)
1763 goto Done;
1764 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1765 if (x2 == NULL)
1766 goto Done;
1767 Py_DECREF(x1);
1768 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 /* x2 has days in seconds */
1771 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1772 if (x1 == NULL)
1773 goto Done;
1774 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1775 if (x3 == NULL)
1776 goto Done;
1777 Py_DECREF(x1);
1778 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001779 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 /* x3 has days+seconds in seconds */
1782 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1783 if (x1 == NULL)
1784 goto Done;
1785 Py_DECREF(x3);
1786 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 /* x1 has days+seconds in us */
1789 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1790 if (x2 == NULL)
1791 goto Done;
1792 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001793 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001794
1795Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 Py_XDECREF(x1);
1797 Py_XDECREF(x2);
1798 Py_XDECREF(x3);
1799 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001800}
1801
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001802static PyObject *
1803checked_divmod(PyObject *a, PyObject *b)
1804{
1805 PyObject *result = PyNumber_Divmod(a, b);
1806 if (result != NULL) {
1807 if (!PyTuple_Check(result)) {
1808 PyErr_Format(PyExc_TypeError,
1809 "divmod() returned non-tuple (type %.200s)",
Victor Stinnerdaa97562020-02-07 03:37:06 +01001810 Py_TYPE(result)->tp_name);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001811 Py_DECREF(result);
1812 return NULL;
1813 }
1814 if (PyTuple_GET_SIZE(result) != 2) {
1815 PyErr_Format(PyExc_TypeError,
1816 "divmod() returned a tuple of size %zd",
1817 PyTuple_GET_SIZE(result));
1818 Py_DECREF(result);
1819 return NULL;
1820 }
1821 }
1822 return result;
1823}
1824
Serhiy Storchaka95949422013-08-27 19:40:23 +03001825/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001826 */
1827static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001828microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 int us;
1831 int s;
1832 int d;
Tim Peters2a799bf2002-12-16 20:18:38 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 PyObject *tuple = NULL;
1835 PyObject *num = NULL;
1836 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001837
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001838 tuple = checked_divmod(pyus, us_per_second);
1839 if (tuple == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 goto Done;
1841 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001842
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001843 num = PyTuple_GET_ITEM(tuple, 1); /* us */
1844 us = _PyLong_AsInt(num);
1845 num = NULL;
1846 if (us == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 goto Done;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001848 }
1849 if (!(0 <= us && us < 1000000)) {
1850 goto BadDivmod;
1851 }
1852
1853 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 Py_INCREF(num);
1855 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001856
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001857 tuple = checked_divmod(num, seconds_per_day);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 if (tuple == NULL)
1859 goto Done;
1860 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001861
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001862 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */
1863 s = _PyLong_AsInt(num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 num = NULL;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001865 if (s == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 goto Done;
1867 }
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001868 if (!(0 <= s && s < 24*3600)) {
1869 goto BadDivmod;
1870 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001871
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001872 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 Py_INCREF(num);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001874 d = _PyLong_AsInt(num);
1875 if (d == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 goto Done;
1877 }
1878 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001879
1880Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 Py_XDECREF(tuple);
1882 Py_XDECREF(num);
1883 return result;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001884
1885BadDivmod:
1886 PyErr_SetString(PyExc_TypeError,
1887 "divmod() returned a value out of range");
1888 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001889}
1890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891#define microseconds_to_delta(pymicros) \
1892 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001893
Tim Peters2a799bf2002-12-16 20:18:38 +00001894static PyObject *
1895multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 PyObject *pyus_in;
1898 PyObject *pyus_out;
1899 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 pyus_in = delta_to_microseconds(delta);
1902 if (pyus_in == NULL)
1903 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001904
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001905 pyus_out = PyNumber_Multiply(intobj, pyus_in);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 Py_DECREF(pyus_in);
1907 if (pyus_out == NULL)
1908 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 result = microseconds_to_delta(pyus_out);
1911 Py_DECREF(pyus_out);
1912 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001913}
1914
1915static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001916get_float_as_integer_ratio(PyObject *floatobj)
1917{
1918 PyObject *ratio;
1919
1920 assert(floatobj && PyFloat_Check(floatobj));
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001921 ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio);
Oren Milman865e4b42017-09-19 15:58:11 +03001922 if (ratio == NULL) {
1923 return NULL;
1924 }
1925 if (!PyTuple_Check(ratio)) {
1926 PyErr_Format(PyExc_TypeError,
1927 "unexpected return type from as_integer_ratio(): "
1928 "expected tuple, got '%.200s'",
1929 Py_TYPE(ratio)->tp_name);
1930 Py_DECREF(ratio);
1931 return NULL;
1932 }
1933 if (PyTuple_Size(ratio) != 2) {
1934 PyErr_SetString(PyExc_ValueError,
1935 "as_integer_ratio() must return a 2-tuple");
1936 Py_DECREF(ratio);
1937 return NULL;
1938 }
1939 return ratio;
1940}
1941
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001942/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001943static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001944multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001945{
1946 PyObject *result = NULL;
1947 PyObject *pyus_in = NULL, *temp, *pyus_out;
1948 PyObject *ratio = NULL;
1949
1950 pyus_in = delta_to_microseconds(delta);
1951 if (pyus_in == NULL)
1952 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001953 ratio = get_float_as_integer_ratio(floatobj);
1954 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001955 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001956 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001957 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001958 Py_DECREF(pyus_in);
1959 pyus_in = NULL;
1960 if (temp == NULL)
1961 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001962 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001963 Py_DECREF(temp);
1964 if (pyus_out == NULL)
1965 goto error;
1966 result = microseconds_to_delta(pyus_out);
1967 Py_DECREF(pyus_out);
1968 error:
1969 Py_XDECREF(pyus_in);
1970 Py_XDECREF(ratio);
1971
1972 return result;
1973}
1974
1975static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001976divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 PyObject *pyus_in;
1979 PyObject *pyus_out;
1980 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 pyus_in = delta_to_microseconds(delta);
1983 if (pyus_in == NULL)
1984 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1987 Py_DECREF(pyus_in);
1988 if (pyus_out == NULL)
1989 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 result = microseconds_to_delta(pyus_out);
1992 Py_DECREF(pyus_out);
1993 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001994}
1995
1996static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001997divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 PyObject *pyus_left;
2000 PyObject *pyus_right;
2001 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 pyus_left = delta_to_microseconds(left);
2004 if (pyus_left == NULL)
2005 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 pyus_right = delta_to_microseconds(right);
2008 if (pyus_right == NULL) {
2009 Py_DECREF(pyus_left);
2010 return NULL;
2011 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 result = PyNumber_FloorDivide(pyus_left, pyus_right);
2014 Py_DECREF(pyus_left);
2015 Py_DECREF(pyus_right);
2016 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002017}
2018
2019static PyObject *
2020truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2021{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 PyObject *pyus_left;
2023 PyObject *pyus_right;
2024 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 pyus_left = delta_to_microseconds(left);
2027 if (pyus_left == NULL)
2028 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 pyus_right = delta_to_microseconds(right);
2031 if (pyus_right == NULL) {
2032 Py_DECREF(pyus_left);
2033 return NULL;
2034 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2037 Py_DECREF(pyus_left);
2038 Py_DECREF(pyus_right);
2039 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002040}
2041
2042static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002043truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2044{
2045 PyObject *result;
2046 PyObject *pyus_in, *pyus_out;
2047 pyus_in = delta_to_microseconds(delta);
2048 if (pyus_in == NULL)
2049 return NULL;
2050 pyus_out = divide_nearest(pyus_in, i);
2051 Py_DECREF(pyus_in);
2052 if (pyus_out == NULL)
2053 return NULL;
2054 result = microseconds_to_delta(pyus_out);
2055 Py_DECREF(pyus_out);
2056
2057 return result;
2058}
2059
2060static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002061delta_add(PyObject *left, PyObject *right)
2062{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2066 /* delta + delta */
2067 /* The C-level additions can't overflow because of the
2068 * invariant bounds.
2069 */
2070 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2071 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2072 int microseconds = GET_TD_MICROSECONDS(left) +
2073 GET_TD_MICROSECONDS(right);
2074 result = new_delta(days, seconds, microseconds, 1);
2075 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 if (result == Py_NotImplemented)
2078 Py_INCREF(result);
2079 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002080}
2081
2082static PyObject *
2083delta_negative(PyDateTime_Delta *self)
2084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 return new_delta(-GET_TD_DAYS(self),
2086 -GET_TD_SECONDS(self),
2087 -GET_TD_MICROSECONDS(self),
2088 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002089}
2090
2091static PyObject *
2092delta_positive(PyDateTime_Delta *self)
2093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 /* Could optimize this (by returning self) if this isn't a
2095 * subclass -- but who uses unary + ? Approximately nobody.
2096 */
2097 return new_delta(GET_TD_DAYS(self),
2098 GET_TD_SECONDS(self),
2099 GET_TD_MICROSECONDS(self),
2100 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002101}
2102
2103static PyObject *
2104delta_abs(PyDateTime_Delta *self)
2105{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 assert(GET_TD_MICROSECONDS(self) >= 0);
2109 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 if (GET_TD_DAYS(self) < 0)
2112 result = delta_negative(self);
2113 else
2114 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002117}
2118
2119static PyObject *
2120delta_subtract(PyObject *left, PyObject *right)
2121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2125 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002126 /* The C-level additions can't overflow because of the
2127 * invariant bounds.
2128 */
2129 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2130 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2131 int microseconds = GET_TD_MICROSECONDS(left) -
2132 GET_TD_MICROSECONDS(right);
2133 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002134 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 if (result == Py_NotImplemented)
2137 Py_INCREF(result);
2138 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002139}
2140
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002141static int
2142delta_cmp(PyObject *self, PyObject *other)
2143{
2144 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2145 if (diff == 0) {
2146 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2147 if (diff == 0)
2148 diff = GET_TD_MICROSECONDS(self) -
2149 GET_TD_MICROSECONDS(other);
2150 }
2151 return diff;
2152}
2153
Tim Peters2a799bf2002-12-16 20:18:38 +00002154static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002155delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002158 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 return diff_to_bool(diff, op);
2160 }
2161 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002162 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002164}
2165
2166static PyObject *delta_getstate(PyDateTime_Delta *self);
2167
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002168static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002169delta_hash(PyDateTime_Delta *self)
2170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 if (self->hashcode == -1) {
2172 PyObject *temp = delta_getstate(self);
2173 if (temp != NULL) {
2174 self->hashcode = PyObject_Hash(temp);
2175 Py_DECREF(temp);
2176 }
2177 }
2178 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002179}
2180
2181static PyObject *
2182delta_multiply(PyObject *left, PyObject *right)
2183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 if (PyDelta_Check(left)) {
2187 /* delta * ??? */
2188 if (PyLong_Check(right))
2189 result = multiply_int_timedelta(right,
2190 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002191 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002192 result = multiply_truedivide_timedelta_float(
2193 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 }
2195 else if (PyLong_Check(left))
2196 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002197 (PyDateTime_Delta *) right);
2198 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002199 result = multiply_truedivide_timedelta_float(
2200 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002202 if (result == Py_NotImplemented)
2203 Py_INCREF(result);
2204 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002205}
2206
2207static PyObject *
2208delta_divide(PyObject *left, PyObject *right)
2209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002212 if (PyDelta_Check(left)) {
2213 /* delta * ??? */
2214 if (PyLong_Check(right))
2215 result = divide_timedelta_int(
2216 (PyDateTime_Delta *)left,
2217 right);
2218 else if (PyDelta_Check(right))
2219 result = divide_timedelta_timedelta(
2220 (PyDateTime_Delta *)left,
2221 (PyDateTime_Delta *)right);
2222 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 if (result == Py_NotImplemented)
2225 Py_INCREF(result);
2226 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002227}
2228
Mark Dickinson7c186e22010-04-20 22:32:49 +00002229static PyObject *
2230delta_truedivide(PyObject *left, PyObject *right)
2231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 if (PyDelta_Check(left)) {
2235 if (PyDelta_Check(right))
2236 result = truedivide_timedelta_timedelta(
2237 (PyDateTime_Delta *)left,
2238 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002239 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002240 result = multiply_truedivide_timedelta_float(
2241 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002242 else if (PyLong_Check(right))
2243 result = truedivide_timedelta_int(
2244 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 if (result == Py_NotImplemented)
2248 Py_INCREF(result);
2249 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002250}
2251
2252static PyObject *
2253delta_remainder(PyObject *left, PyObject *right)
2254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 PyObject *pyus_left;
2256 PyObject *pyus_right;
2257 PyObject *pyus_remainder;
2258 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002259
Brian Curtindfc80e32011-08-10 20:28:54 -05002260 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2261 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2264 if (pyus_left == NULL)
2265 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2268 if (pyus_right == NULL) {
2269 Py_DECREF(pyus_left);
2270 return NULL;
2271 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2274 Py_DECREF(pyus_left);
2275 Py_DECREF(pyus_right);
2276 if (pyus_remainder == NULL)
2277 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 remainder = microseconds_to_delta(pyus_remainder);
2280 Py_DECREF(pyus_remainder);
2281 if (remainder == NULL)
2282 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002285}
2286
2287static PyObject *
2288delta_divmod(PyObject *left, PyObject *right)
2289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 PyObject *pyus_left;
2291 PyObject *pyus_right;
2292 PyObject *divmod;
2293 PyObject *delta;
2294 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002295
Brian Curtindfc80e32011-08-10 20:28:54 -05002296 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2297 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2300 if (pyus_left == NULL)
2301 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002303 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2304 if (pyus_right == NULL) {
2305 Py_DECREF(pyus_left);
2306 return NULL;
2307 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002308
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002309 divmod = checked_divmod(pyus_left, pyus_right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002310 Py_DECREF(pyus_left);
2311 Py_DECREF(pyus_right);
2312 if (divmod == NULL)
2313 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2316 if (delta == NULL) {
2317 Py_DECREF(divmod);
2318 return NULL;
2319 }
2320 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2321 Py_DECREF(delta);
2322 Py_DECREF(divmod);
2323 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002324}
2325
Tim Peters2a799bf2002-12-16 20:18:38 +00002326/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2327 * timedelta constructor. sofar is the # of microseconds accounted for
2328 * so far, and there are factor microseconds per current unit, the number
2329 * of which is given by num. num * factor is added to sofar in a
2330 * numerically careful way, and that's the result. Any fractional
2331 * microseconds left over (this can happen if num is a float type) are
2332 * added into *leftover.
2333 * Note that there are many ways this can give an error (NULL) return.
2334 */
2335static PyObject *
2336accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2337 double *leftover)
2338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339 PyObject *prod;
2340 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002342 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 if (PyLong_Check(num)) {
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002345 prod = PyNumber_Multiply(num, factor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346 if (prod == NULL)
2347 return NULL;
2348 sum = PyNumber_Add(sofar, prod);
2349 Py_DECREF(prod);
2350 return sum;
2351 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 if (PyFloat_Check(num)) {
2354 double dnum;
2355 double fracpart;
2356 double intpart;
2357 PyObject *x;
2358 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 /* The Plan: decompose num into an integer part and a
2361 * fractional part, num = intpart + fracpart.
2362 * Then num * factor ==
2363 * intpart * factor + fracpart * factor
2364 * and the LHS can be computed exactly in long arithmetic.
2365 * The RHS is again broken into an int part and frac part.
2366 * and the frac part is added into *leftover.
2367 */
2368 dnum = PyFloat_AsDouble(num);
2369 if (dnum == -1.0 && PyErr_Occurred())
2370 return NULL;
2371 fracpart = modf(dnum, &intpart);
2372 x = PyLong_FromDouble(intpart);
2373 if (x == NULL)
2374 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 prod = PyNumber_Multiply(x, factor);
2377 Py_DECREF(x);
2378 if (prod == NULL)
2379 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 sum = PyNumber_Add(sofar, prod);
2382 Py_DECREF(prod);
2383 if (sum == NULL)
2384 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 if (fracpart == 0.0)
2387 return sum;
2388 /* So far we've lost no information. Dealing with the
2389 * fractional part requires float arithmetic, and may
2390 * lose a little info.
2391 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002392 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 dnum *= fracpart;
2396 fracpart = modf(dnum, &intpart);
2397 x = PyLong_FromDouble(intpart);
2398 if (x == NULL) {
2399 Py_DECREF(sum);
2400 return NULL;
2401 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 y = PyNumber_Add(sum, x);
2404 Py_DECREF(sum);
2405 Py_DECREF(x);
2406 *leftover += fracpart;
2407 return y;
2408 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 PyErr_Format(PyExc_TypeError,
2411 "unsupported type for timedelta %s component: %s",
2412 tag, Py_TYPE(num)->tp_name);
2413 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002414}
2415
2416static PyObject *
2417delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 /* Argument objects. */
2422 PyObject *day = NULL;
2423 PyObject *second = NULL;
2424 PyObject *us = NULL;
2425 PyObject *ms = NULL;
2426 PyObject *minute = NULL;
2427 PyObject *hour = NULL;
2428 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 PyObject *x = NULL; /* running sum of microseconds */
2431 PyObject *y = NULL; /* temp sum of microseconds */
2432 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 static char *keywords[] = {
2435 "days", "seconds", "microseconds", "milliseconds",
2436 "minutes", "hours", "weeks", NULL
2437 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2440 keywords,
2441 &day, &second, &us,
2442 &ms, &minute, &hour, &week) == 0)
2443 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 x = PyLong_FromLong(0);
2446 if (x == NULL)
2447 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002449#define CLEANUP \
2450 Py_DECREF(x); \
2451 x = y; \
2452 if (x == NULL) \
2453 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002456 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 CLEANUP;
2458 }
2459 if (ms) {
2460 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2461 CLEANUP;
2462 }
2463 if (second) {
2464 y = accum("seconds", x, second, us_per_second, &leftover_us);
2465 CLEANUP;
2466 }
2467 if (minute) {
2468 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2469 CLEANUP;
2470 }
2471 if (hour) {
2472 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2473 CLEANUP;
2474 }
2475 if (day) {
2476 y = accum("days", x, day, us_per_day, &leftover_us);
2477 CLEANUP;
2478 }
2479 if (week) {
2480 y = accum("weeks", x, week, us_per_week, &leftover_us);
2481 CLEANUP;
2482 }
2483 if (leftover_us) {
2484 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002485 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002486 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002487 PyObject *temp;
2488
Victor Stinner69cc4872015-09-08 23:58:54 +02002489 if (fabs(whole_us - leftover_us) == 0.5) {
2490 /* We're exactly halfway between two integers. In order
2491 * to do round-half-to-even, we must determine whether x
2492 * is odd. Note that x is odd when it's last bit is 1. The
2493 * code below uses bitwise and operation to check the last
2494 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002495 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002496 if (temp == NULL) {
2497 Py_DECREF(x);
2498 goto Done;
2499 }
2500 x_is_odd = PyObject_IsTrue(temp);
2501 Py_DECREF(temp);
2502 if (x_is_odd == -1) {
2503 Py_DECREF(x);
2504 goto Done;
2505 }
2506 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2507 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002508
Victor Stinner36a5a062013-08-28 01:53:39 +02002509 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 if (temp == NULL) {
2512 Py_DECREF(x);
2513 goto Done;
2514 }
2515 y = PyNumber_Add(x, temp);
2516 Py_DECREF(temp);
2517 CLEANUP;
2518 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 self = microseconds_to_delta_ex(x, type);
2521 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002522Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002524
2525#undef CLEANUP
2526}
2527
2528static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002529delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002530{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002531 return (GET_TD_DAYS(self) != 0
2532 || GET_TD_SECONDS(self) != 0
2533 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002534}
2535
2536static PyObject *
2537delta_repr(PyDateTime_Delta *self)
2538{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002539 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002540
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002541 if (args == NULL) {
2542 return NULL;
2543 }
2544
2545 const char *sep = "";
2546
2547 if (GET_TD_DAYS(self) != 0) {
2548 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2549 if (args == NULL) {
2550 return NULL;
2551 }
2552 sep = ", ";
2553 }
2554
2555 if (GET_TD_SECONDS(self) != 0) {
2556 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2557 GET_TD_SECONDS(self)));
2558 if (args == NULL) {
2559 return NULL;
2560 }
2561 sep = ", ";
2562 }
2563
2564 if (GET_TD_MICROSECONDS(self) != 0) {
2565 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2566 GET_TD_MICROSECONDS(self)));
2567 if (args == NULL) {
2568 return NULL;
2569 }
2570 }
2571
2572 if (PyUnicode_GET_LENGTH(args) == 0) {
2573 Py_SETREF(args, PyUnicode_FromString("0"));
2574 if (args == NULL) {
2575 return NULL;
2576 }
2577 }
2578
2579 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2580 args);
2581 Py_DECREF(args);
2582 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002583}
2584
2585static PyObject *
2586delta_str(PyDateTime_Delta *self)
2587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002588 int us = GET_TD_MICROSECONDS(self);
2589 int seconds = GET_TD_SECONDS(self);
2590 int minutes = divmod(seconds, 60, &seconds);
2591 int hours = divmod(minutes, 60, &minutes);
2592 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 if (days) {
2595 if (us)
2596 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2597 days, (days == 1 || days == -1) ? "" : "s",
2598 hours, minutes, seconds, us);
2599 else
2600 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2601 days, (days == 1 || days == -1) ? "" : "s",
2602 hours, minutes, seconds);
2603 } else {
2604 if (us)
2605 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2606 hours, minutes, seconds, us);
2607 else
2608 return PyUnicode_FromFormat("%d:%02d:%02d",
2609 hours, minutes, seconds);
2610 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002611
Tim Peters2a799bf2002-12-16 20:18:38 +00002612}
2613
Tim Peters371935f2003-02-01 01:52:50 +00002614/* Pickle support, a simple use of __reduce__. */
2615
Tim Petersb57f8f02003-02-01 02:54:15 +00002616/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002617static PyObject *
2618delta_getstate(PyDateTime_Delta *self)
2619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002620 return Py_BuildValue("iii", GET_TD_DAYS(self),
2621 GET_TD_SECONDS(self),
2622 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002623}
2624
Tim Peters2a799bf2002-12-16 20:18:38 +00002625static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302626delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitroube6859d2009-11-25 23:02:32 +00002627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002628 PyObject *total_seconds;
2629 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2632 if (total_microseconds == NULL)
2633 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002634
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002635 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002637 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002638 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002639}
2640
2641static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302642delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00002643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002644 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002645}
2646
2647#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2648
2649static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002651 {"days", T_INT, OFFSET(days), READONLY,
2652 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 {"seconds", T_INT, OFFSET(seconds), READONLY,
2655 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002657 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2658 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2659 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002660};
2661
2662static PyMethodDef delta_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302663 {"total_seconds", delta_total_seconds, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002664 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002666 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2667 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002669 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002670};
2671
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002672static const char delta_doc[] =
Chris Barkerd6a61f22018-10-19 15:43:24 -07002673PyDoc_STR("Difference between two datetime values.\n\n"
2674 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2675 "minutes=0, hours=0, weeks=0)\n\n"
2676 "All arguments are optional and default to 0.\n"
2677 "Arguments may be integers or floats, and may be positive or negative.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002678
2679static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002680 delta_add, /* nb_add */
2681 delta_subtract, /* nb_subtract */
2682 delta_multiply, /* nb_multiply */
2683 delta_remainder, /* nb_remainder */
2684 delta_divmod, /* nb_divmod */
2685 0, /* nb_power */
2686 (unaryfunc)delta_negative, /* nb_negative */
2687 (unaryfunc)delta_positive, /* nb_positive */
2688 (unaryfunc)delta_abs, /* nb_absolute */
2689 (inquiry)delta_bool, /* nb_bool */
2690 0, /*nb_invert*/
2691 0, /*nb_lshift*/
2692 0, /*nb_rshift*/
2693 0, /*nb_and*/
2694 0, /*nb_xor*/
2695 0, /*nb_or*/
2696 0, /*nb_int*/
2697 0, /*nb_reserved*/
2698 0, /*nb_float*/
2699 0, /*nb_inplace_add*/
2700 0, /*nb_inplace_subtract*/
2701 0, /*nb_inplace_multiply*/
2702 0, /*nb_inplace_remainder*/
2703 0, /*nb_inplace_power*/
2704 0, /*nb_inplace_lshift*/
2705 0, /*nb_inplace_rshift*/
2706 0, /*nb_inplace_and*/
2707 0, /*nb_inplace_xor*/
2708 0, /*nb_inplace_or*/
2709 delta_divide, /* nb_floor_divide */
2710 delta_truedivide, /* nb_true_divide */
2711 0, /* nb_inplace_floor_divide */
2712 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002713};
2714
2715static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002716 PyVarObject_HEAD_INIT(NULL, 0)
2717 "datetime.timedelta", /* tp_name */
2718 sizeof(PyDateTime_Delta), /* tp_basicsize */
2719 0, /* tp_itemsize */
2720 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002721 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002722 0, /* tp_getattr */
2723 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002724 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002725 (reprfunc)delta_repr, /* tp_repr */
2726 &delta_as_number, /* tp_as_number */
2727 0, /* tp_as_sequence */
2728 0, /* tp_as_mapping */
2729 (hashfunc)delta_hash, /* tp_hash */
2730 0, /* tp_call */
2731 (reprfunc)delta_str, /* tp_str */
2732 PyObject_GenericGetAttr, /* tp_getattro */
2733 0, /* tp_setattro */
2734 0, /* tp_as_buffer */
2735 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2736 delta_doc, /* tp_doc */
2737 0, /* tp_traverse */
2738 0, /* tp_clear */
2739 delta_richcompare, /* tp_richcompare */
2740 0, /* tp_weaklistoffset */
2741 0, /* tp_iter */
2742 0, /* tp_iternext */
2743 delta_methods, /* tp_methods */
2744 delta_members, /* tp_members */
2745 0, /* tp_getset */
2746 0, /* tp_base */
2747 0, /* tp_dict */
2748 0, /* tp_descr_get */
2749 0, /* tp_descr_set */
2750 0, /* tp_dictoffset */
2751 0, /* tp_init */
2752 0, /* tp_alloc */
2753 delta_new, /* tp_new */
2754 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002755};
2756
2757/*
2758 * PyDateTime_Date implementation.
2759 */
2760
2761/* Accessor properties. */
2762
2763static PyObject *
2764date_year(PyDateTime_Date *self, void *unused)
2765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002766 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002767}
2768
2769static PyObject *
2770date_month(PyDateTime_Date *self, void *unused)
2771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002773}
2774
2775static PyObject *
2776date_day(PyDateTime_Date *self, void *unused)
2777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002778 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002779}
2780
2781static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002782 {"year", (getter)date_year},
2783 {"month", (getter)date_month},
2784 {"day", (getter)date_day},
2785 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002786};
2787
2788/* Constructors. */
2789
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002790static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002791
Tim Peters2a799bf2002-12-16 20:18:38 +00002792static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002793date_from_pickle(PyTypeObject *type, PyObject *state)
2794{
2795 PyDateTime_Date *me;
2796
2797 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2798 if (me != NULL) {
2799 const char *pdata = PyBytes_AS_STRING(state);
2800 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2801 me->hashcode = -1;
2802 }
2803 return (PyObject *)me;
2804}
2805
2806static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002807date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002809 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 int year;
2811 int month;
2812 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka1133a8c2018-12-07 16:48:21 +02002815 if (PyTuple_GET_SIZE(args) == 1) {
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002816 PyObject *state = PyTuple_GET_ITEM(args, 0);
2817 if (PyBytes_Check(state)) {
2818 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2819 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2820 {
2821 return date_from_pickle(type, state);
Victor Stinnerb37672d2018-11-22 03:37:50 +01002822 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002823 }
2824 else if (PyUnicode_Check(state)) {
2825 if (PyUnicode_READY(state)) {
2826 return NULL;
2827 }
2828 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
2829 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
2830 {
2831 state = PyUnicode_AsLatin1String(state);
2832 if (state == NULL) {
2833 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
2834 /* More informative error message. */
2835 PyErr_SetString(PyExc_ValueError,
2836 "Failed to encode latin1 string when unpickling "
2837 "a date object. "
2838 "pickle.load(data, encoding='latin1') is assumed.");
2839 }
2840 return NULL;
2841 }
2842 self = date_from_pickle(type, state);
2843 Py_DECREF(state);
2844 return self;
2845 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002846 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2850 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 self = new_date_ex(year, month, day, type);
2852 }
2853 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002854}
2855
Tim Peters2a799bf2002-12-16 20:18:38 +00002856static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002857date_fromtimestamp(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002858{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002859 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002860 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002861
Victor Stinnere4a994d2015-03-30 01:10:14 +02002862 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002863 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002864
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002865 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002866 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002867
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002868 return new_date_subclass_ex(tm.tm_year + 1900,
2869 tm.tm_mon + 1,
2870 tm.tm_mday,
2871 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002872}
2873
2874/* Return new date from current time.
2875 * We say this is equivalent to fromtimestamp(time.time()), and the
2876 * only way to be sure of that is to *call* time.time(). That's not
2877 * generally the same as calling C's time.
2878 */
2879static PyObject *
2880date_today(PyObject *cls, PyObject *dummy)
2881{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002882 PyObject *time;
2883 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002884 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002886 time = time_time();
2887 if (time == NULL)
2888 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 /* Note well: today() is a class method, so this may not call
2891 * date.fromtimestamp. For example, it may call
2892 * datetime.fromtimestamp. That's why we need all the accuracy
2893 * time.time() delivers; if someone were gonzo about optimization,
2894 * date.today() could get away with plain C time().
2895 */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02002896 result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002897 Py_DECREF(time);
2898 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002899}
2900
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002901/*[clinic input]
2902@classmethod
2903datetime.date.fromtimestamp
2904
2905 timestamp: object
2906 /
2907
2908Create a date from a POSIX timestamp.
2909
2910The timestamp is a number, e.g. created via time.time(), that is interpreted
2911as local time.
2912[clinic start generated code]*/
2913
Tim Peters2a799bf2002-12-16 20:18:38 +00002914static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002915datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp)
2916/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00002917{
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002918 return date_fromtimestamp((PyObject *) type, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002919}
2920
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04002921/* bpo-36025: This is a wrapper for API compatibility with the public C API,
2922 * which expects a function that takes an *args tuple, whereas the argument
2923 * clinic generates code that takes METH_O.
2924 */
2925static PyObject *
2926datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args)
2927{
2928 PyObject *timestamp;
2929 PyObject *result = NULL;
2930
2931 if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, &timestamp)) {
2932 result = date_fromtimestamp(cls, timestamp);
2933 }
2934
2935 return result;
2936}
2937
Tim Peters2a799bf2002-12-16 20:18:38 +00002938/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2939 * the ordinal is out of range.
2940 */
2941static PyObject *
2942date_fromordinal(PyObject *cls, PyObject *args)
2943{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002944 PyObject *result = NULL;
2945 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002947 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2948 int year;
2949 int month;
2950 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002952 if (ordinal < 1)
2953 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2954 ">= 1");
2955 else {
2956 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002957 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002958 }
2959 }
2960 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002961}
2962
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002963/* Return the new date from a string as generated by date.isoformat() */
2964static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04002965date_fromisoformat(PyObject *cls, PyObject *dtstr)
2966{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002967 assert(dtstr != NULL);
2968
2969 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04002970 PyErr_SetString(PyExc_TypeError,
2971 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002972 return NULL;
2973 }
2974
2975 Py_ssize_t len;
2976
Paul Ganssle3df85402018-10-22 12:32:52 -04002977 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04002978 if (dt_ptr == NULL) {
2979 goto invalid_string_error;
2980 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002981
2982 int year = 0, month = 0, day = 0;
2983
2984 int rv;
2985 if (len == 10) {
2986 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
Paul Ganssle3df85402018-10-22 12:32:52 -04002987 }
2988 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002989 rv = -1;
2990 }
2991
2992 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04002993 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002994 }
2995
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002996 return new_date_subclass_ex(year, month, day, cls);
Paul Ganssle096329f2018-08-23 11:06:20 -04002997
2998invalid_string_error:
Paul Ganssle3df85402018-10-22 12:32:52 -04002999 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04003000 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003001}
3002
Paul Ganssle88c09372019-04-29 09:22:03 -04003003
3004static PyObject *
3005date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw)
3006{
3007 static char *keywords[] = {
3008 "year", "week", "day", NULL
3009 };
3010
3011 int year, week, day;
3012 if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar",
3013 keywords,
3014 &year, &week, &day) == 0) {
3015 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
3016 PyErr_Format(PyExc_ValueError,
3017 "ISO calendar component out of range");
3018
3019 }
3020 return NULL;
3021 }
3022
3023 // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
3024 if (year < MINYEAR || year > MAXYEAR) {
3025 PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
3026 return NULL;
3027 }
3028
3029 if (week <= 0 || week >= 53) {
3030 int out_of_range = 1;
3031 if (week == 53) {
3032 // ISO years have 53 weeks in it on years starting with a Thursday
3033 // and on leap years starting on Wednesday
3034 int first_weekday = weekday(year, 1, 1);
3035 if (first_weekday == 3 || (first_weekday == 2 && is_leap(year))) {
3036 out_of_range = 0;
3037 }
3038 }
3039
3040 if (out_of_range) {
3041 PyErr_Format(PyExc_ValueError, "Invalid week: %d", week);
3042 return NULL;
3043 }
3044 }
3045
3046 if (day <= 0 || day >= 8) {
3047 PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])",
3048 day);
3049 return NULL;
3050 }
3051
3052 // Convert (Y, W, D) to (Y, M, D) in-place
3053 int day_1 = iso_week1_monday(year);
3054
3055 int month = week;
3056 int day_offset = (month - 1)*7 + day - 1;
3057
3058 ord_to_ymd(day_1 + day_offset, &year, &month, &day);
3059
3060 return new_date_subclass_ex(year, month, day, cls);
3061}
3062
3063
Tim Peters2a799bf2002-12-16 20:18:38 +00003064/*
3065 * Date arithmetic.
3066 */
3067
3068/* date + timedelta -> date. If arg negate is true, subtract the timedelta
3069 * instead.
3070 */
3071static PyObject *
3072add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
3073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003074 PyObject *result = NULL;
3075 int year = GET_YEAR(date);
3076 int month = GET_MONTH(date);
3077 int deltadays = GET_TD_DAYS(delta);
3078 /* C-level overflow is impossible because |deltadays| < 1e9. */
3079 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00003080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003081 if (normalize_date(&year, &month, &day) >= 0)
Paul Ganssle89427cd2019-02-04 14:42:04 -05003082 result = new_date_subclass_ex(year, month, day,
3083 (PyObject* )Py_TYPE(date));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003084 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003085}
3086
3087static PyObject *
3088date_add(PyObject *left, PyObject *right)
3089{
Brian Curtindfc80e32011-08-10 20:28:54 -05003090 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3091 Py_RETURN_NOTIMPLEMENTED;
3092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003093 if (PyDate_Check(left)) {
3094 /* date + ??? */
3095 if (PyDelta_Check(right))
3096 /* date + delta */
3097 return add_date_timedelta((PyDateTime_Date *) left,
3098 (PyDateTime_Delta *) right,
3099 0);
3100 }
3101 else {
3102 /* ??? + date
3103 * 'right' must be one of us, or we wouldn't have been called
3104 */
3105 if (PyDelta_Check(left))
3106 /* delta + date */
3107 return add_date_timedelta((PyDateTime_Date *) right,
3108 (PyDateTime_Delta *) left,
3109 0);
3110 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003111 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003112}
3113
3114static PyObject *
3115date_subtract(PyObject *left, PyObject *right)
3116{
Brian Curtindfc80e32011-08-10 20:28:54 -05003117 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3118 Py_RETURN_NOTIMPLEMENTED;
3119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003120 if (PyDate_Check(left)) {
3121 if (PyDate_Check(right)) {
3122 /* date - date */
3123 int left_ord = ymd_to_ord(GET_YEAR(left),
3124 GET_MONTH(left),
3125 GET_DAY(left));
3126 int right_ord = ymd_to_ord(GET_YEAR(right),
3127 GET_MONTH(right),
3128 GET_DAY(right));
3129 return new_delta(left_ord - right_ord, 0, 0, 0);
3130 }
3131 if (PyDelta_Check(right)) {
3132 /* date - delta */
3133 return add_date_timedelta((PyDateTime_Date *) left,
3134 (PyDateTime_Delta *) right,
3135 1);
3136 }
3137 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003138 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003139}
3140
3141
3142/* Various ways to turn a date into a string. */
3143
3144static PyObject *
3145date_repr(PyDateTime_Date *self)
3146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003147 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3148 Py_TYPE(self)->tp_name,
3149 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003150}
3151
3152static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303153date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003155 return PyUnicode_FromFormat("%04d-%02d-%02d",
3156 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003157}
3158
Tim Peterse2df5ff2003-05-02 18:39:55 +00003159/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003160static PyObject *
3161date_str(PyDateTime_Date *self)
3162{
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02003163 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
Tim Peters2a799bf2002-12-16 20:18:38 +00003164}
3165
3166
3167static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303168date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003170 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003171}
3172
3173static PyObject *
3174date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003176 /* This method can be inherited, and needs to call the
3177 * timetuple() method appropriate to self's class.
3178 */
3179 PyObject *result;
3180 PyObject *tuple;
3181 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003182 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003183 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003185 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3186 &format))
3187 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003188
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02003189 tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003190 if (tuple == NULL)
3191 return NULL;
3192 result = wrap_strftime((PyObject *)self, format, tuple,
3193 (PyObject *)self);
3194 Py_DECREF(tuple);
3195 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003196}
3197
Eric Smith1ba31142007-09-11 18:06:02 +00003198static PyObject *
3199date_format(PyDateTime_Date *self, PyObject *args)
3200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003201 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003203 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3204 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003206 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003207 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003209
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02003210 return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime,
3211 format);
Eric Smith1ba31142007-09-11 18:06:02 +00003212}
3213
Tim Peters2a799bf2002-12-16 20:18:38 +00003214/* ISO methods. */
3215
3216static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303217date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003218{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003219 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003221 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003222}
3223
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003224PyDoc_STRVAR(iso_calendar_date__doc__,
3225"The result of date.isocalendar() or datetime.isocalendar()\n\n\
3226This object may be accessed either as a tuple of\n\
3227 ((year, week, weekday)\n\
3228or via the object attributes as named in the above tuple.");
3229
3230typedef struct {
3231 PyTupleObject tuple;
3232} PyDateTime_IsoCalendarDate;
3233
3234static PyObject *
3235iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self)
3236{
3237 PyObject* year = PyTuple_GetItem((PyObject *)self, 0);
3238 if (year == NULL) {
3239 return NULL;
3240 }
3241 PyObject* week = PyTuple_GetItem((PyObject *)self, 1);
3242 if (week == NULL) {
3243 return NULL;
3244 }
3245 PyObject* weekday = PyTuple_GetItem((PyObject *)self, 2);
3246 if (weekday == NULL) {
3247 return NULL;
3248 }
3249
3250 return PyUnicode_FromFormat("%.200s(year=%S, week=%S, weekday=%S)",
3251 Py_TYPE(self)->tp_name, year, week, weekday);
3252}
3253
3254static PyObject *
3255iso_calendar_date_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
3256{
3257 // Construct the tuple that this reduces to
3258 PyObject * reduce_tuple = Py_BuildValue(
3259 "O((OOO))", &PyTuple_Type,
3260 PyTuple_GET_ITEM(self, 0),
3261 PyTuple_GET_ITEM(self, 1),
3262 PyTuple_GET_ITEM(self, 2)
3263 );
3264
3265 return reduce_tuple;
3266}
3267
3268static PyObject *
3269iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused)
3270{
3271 PyObject *year = PyTuple_GetItem((PyObject *)self, 0);
3272 if (year == NULL) {
3273 return NULL;
3274 }
3275 Py_INCREF(year);
3276 return year;
3277}
3278
3279static PyObject *
3280iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused)
3281{
3282 PyObject *week = PyTuple_GetItem((PyObject *)self, 1);
3283 if (week == NULL) {
3284 return NULL;
3285 }
3286 Py_INCREF(week);
3287 return week;
3288}
3289
3290static PyObject *
3291iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused)
3292{
3293 PyObject *weekday = PyTuple_GetItem((PyObject *)self, 2);
3294 if (weekday == NULL) {
3295 return NULL;
3296 }
3297 Py_INCREF(weekday);
3298 return weekday;
3299}
3300
3301static PyGetSetDef iso_calendar_date_getset[] = {
3302 {"year", (getter)iso_calendar_date_year},
3303 {"week", (getter)iso_calendar_date_week},
3304 {"weekday", (getter)iso_calendar_date_weekday},
3305 {NULL}
3306};
3307
3308static PyMethodDef iso_calendar_date_methods[] = {
3309 {"__reduce__", (PyCFunction)iso_calendar_date_reduce, METH_NOARGS,
3310 PyDoc_STR("__reduce__() -> (cls, state)")},
3311 {NULL, NULL},
3312};
3313
3314static PyTypeObject PyDateTime_IsoCalendarDateType = {
3315 PyVarObject_HEAD_INIT(NULL, 0)
3316 .tp_name = "datetime.IsoCalendarDate",
3317 .tp_basicsize = sizeof(PyDateTime_IsoCalendarDate),
3318 .tp_repr = (reprfunc) iso_calendar_date_repr,
3319 .tp_flags = Py_TPFLAGS_DEFAULT,
3320 .tp_doc = iso_calendar_date__doc__,
3321 .tp_methods = iso_calendar_date_methods,
3322 .tp_getset = iso_calendar_date_getset,
Petr Viktorin459acc52020-05-28 18:14:46 +02003323 // .tp_base = &PyTuple_Type, // filled in PyInit__datetime
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003324 .tp_new = iso_calendar_date_new,
3325};
3326
3327/*[clinic input]
3328@classmethod
3329datetime.IsoCalendarDate.__new__ as iso_calendar_date_new
3330 year: int
3331 week: int
3332 weekday: int
3333[clinic start generated code]*/
3334
3335static PyObject *
3336iso_calendar_date_new_impl(PyTypeObject *type, int year, int week,
3337 int weekday)
3338/*[clinic end generated code: output=383d33d8dc7183a2 input=4f2c663c9d19c4ee]*/
3339
3340{
3341 PyDateTime_IsoCalendarDate *self;
3342 self = (PyDateTime_IsoCalendarDate *) type->tp_alloc(type, 3);
3343 if (self == NULL) {
3344 return NULL;
3345 }
3346
3347 PyTuple_SET_ITEM(self, 0, PyLong_FromLong(year));
3348 PyTuple_SET_ITEM(self, 1, PyLong_FromLong(week));
3349 PyTuple_SET_ITEM(self, 2, PyLong_FromLong(weekday));
3350
3351 return (PyObject *)self;
3352}
3353
Tim Peters2a799bf2002-12-16 20:18:38 +00003354static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303355date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003356{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003357 int year = GET_YEAR(self);
3358 int week1_monday = iso_week1_monday(year);
3359 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3360 int week;
3361 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003363 week = divmod(today - week1_monday, 7, &day);
3364 if (week < 0) {
3365 --year;
3366 week1_monday = iso_week1_monday(year);
3367 week = divmod(today - week1_monday, 7, &day);
3368 }
3369 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3370 ++year;
3371 week = 0;
3372 }
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003373
3374 PyObject* v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType,
3375 year, week + 1, day + 1);
3376 if (v == NULL) {
3377 return NULL;
3378 }
3379 return v;
Tim Peters2a799bf2002-12-16 20:18:38 +00003380}
3381
3382/* Miscellaneous methods. */
3383
Tim Peters2a799bf2002-12-16 20:18:38 +00003384static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003385date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003387 if (PyDate_Check(other)) {
3388 int diff = memcmp(((PyDateTime_Date *)self)->data,
3389 ((PyDateTime_Date *)other)->data,
3390 _PyDateTime_DATE_DATASIZE);
3391 return diff_to_bool(diff, op);
3392 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003393 else
3394 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003395}
3396
3397static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303398date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003400 return build_struct_time(GET_YEAR(self),
3401 GET_MONTH(self),
3402 GET_DAY(self),
3403 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003404}
3405
Tim Peters12bf3392002-12-24 05:41:27 +00003406static PyObject *
3407date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003409 PyObject *clone;
3410 PyObject *tuple;
3411 int year = GET_YEAR(self);
3412 int month = GET_MONTH(self);
3413 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003415 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3416 &year, &month, &day))
3417 return NULL;
3418 tuple = Py_BuildValue("iii", year, month, day);
3419 if (tuple == NULL)
3420 return NULL;
3421 clone = date_new(Py_TYPE(self), tuple, NULL);
3422 Py_DECREF(tuple);
3423 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003424}
3425
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003426static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003427generic_hash(unsigned char *data, int len)
3428{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003429 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003430}
3431
3432
3433static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003434
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003435static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003436date_hash(PyDateTime_Date *self)
3437{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003438 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003439 self->hashcode = generic_hash(
3440 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003441 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003443 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003444}
3445
3446static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303447date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003449 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3450 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003451}
3452
3453static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303454date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003456 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003458 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003459}
3460
Tim Peters371935f2003-02-01 01:52:50 +00003461/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003462
Tim Petersb57f8f02003-02-01 02:54:15 +00003463/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003464static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003465date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003466{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003467 PyObject* field;
3468 field = PyBytes_FromStringAndSize((char*)self->data,
3469 _PyDateTime_DATE_DATASIZE);
3470 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003471}
3472
3473static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003474date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003476 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003477}
3478
3479static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003481 /* Class methods: */
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02003482 DATETIME_DATE_FROMTIMESTAMP_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00003483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003484 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3485 METH_CLASS,
3486 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3487 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003488
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003489 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3490 METH_CLASS,
3491 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3492
Paul Ganssle88c09372019-04-29 09:22:03 -04003493 {"fromisocalendar", (PyCFunction)(void(*)(void))date_fromisocalendar,
3494 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
3495 PyDoc_STR("int, int, int -> Construct a date from the ISO year, week "
3496 "number and weekday.\n\n"
3497 "This is the inverse of the date.isocalendar() function")},
3498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003499 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3500 PyDoc_STR("Current date or datetime: same as "
3501 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003503 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003505 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3506 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003507
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003508 {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003509 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003511 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3512 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003514 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3515 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003517 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003518 PyDoc_STR("Return a named tuple containing ISO year, week number, and "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003519 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003521 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3522 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003524 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3525 PyDoc_STR("Return the day of the week represented by the date.\n"
3526 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003528 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3529 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3530 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003532 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3533 PyDoc_STR("Return the day of the week represented by the date.\n"
3534 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003535
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003536 {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003537 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003539 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3540 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003542 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003543};
3544
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003545static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003546PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003547
3548static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003549 date_add, /* nb_add */
3550 date_subtract, /* nb_subtract */
3551 0, /* nb_multiply */
3552 0, /* nb_remainder */
3553 0, /* nb_divmod */
3554 0, /* nb_power */
3555 0, /* nb_negative */
3556 0, /* nb_positive */
3557 0, /* nb_absolute */
3558 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003559};
3560
3561static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003562 PyVarObject_HEAD_INIT(NULL, 0)
3563 "datetime.date", /* tp_name */
3564 sizeof(PyDateTime_Date), /* tp_basicsize */
3565 0, /* tp_itemsize */
3566 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003567 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 0, /* tp_getattr */
3569 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003570 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003571 (reprfunc)date_repr, /* tp_repr */
3572 &date_as_number, /* tp_as_number */
3573 0, /* tp_as_sequence */
3574 0, /* tp_as_mapping */
3575 (hashfunc)date_hash, /* tp_hash */
3576 0, /* tp_call */
3577 (reprfunc)date_str, /* tp_str */
3578 PyObject_GenericGetAttr, /* tp_getattro */
3579 0, /* tp_setattro */
3580 0, /* tp_as_buffer */
3581 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3582 date_doc, /* tp_doc */
3583 0, /* tp_traverse */
3584 0, /* tp_clear */
3585 date_richcompare, /* tp_richcompare */
3586 0, /* tp_weaklistoffset */
3587 0, /* tp_iter */
3588 0, /* tp_iternext */
3589 date_methods, /* tp_methods */
3590 0, /* tp_members */
3591 date_getset, /* tp_getset */
3592 0, /* tp_base */
3593 0, /* tp_dict */
3594 0, /* tp_descr_get */
3595 0, /* tp_descr_set */
3596 0, /* tp_dictoffset */
3597 0, /* tp_init */
3598 0, /* tp_alloc */
3599 date_new, /* tp_new */
3600 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003601};
3602
3603/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003604 * PyDateTime_TZInfo implementation.
3605 */
3606
3607/* This is a pure abstract base class, so doesn't do anything beyond
3608 * raising NotImplemented exceptions. Real tzinfo classes need
3609 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003610 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003611 * be subclasses of this tzinfo class, which is easy and quick to check).
3612 *
3613 * Note: For reasons having to do with pickling of subclasses, we have
3614 * to allow tzinfo objects to be instantiated. This wasn't an issue
3615 * in the Python implementation (__init__() could raise NotImplementedError
3616 * there without ill effect), but doing so in the C implementation hit a
3617 * brick wall.
3618 */
3619
3620static PyObject *
3621tzinfo_nogo(const char* methodname)
3622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003623 PyErr_Format(PyExc_NotImplementedError,
3624 "a tzinfo subclass must implement %s()",
3625 methodname);
3626 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003627}
3628
3629/* Methods. A subclass must implement these. */
3630
Tim Peters52dcce22003-01-23 16:36:11 +00003631static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003632tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3633{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003634 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003635}
3636
Tim Peters52dcce22003-01-23 16:36:11 +00003637static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003638tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3639{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003640 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003641}
3642
Tim Peters52dcce22003-01-23 16:36:11 +00003643static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003644tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003646 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003647}
3648
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003649
3650static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3651 PyDateTime_Delta *delta,
3652 int factor);
3653static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3654static PyObject *datetime_dst(PyObject *self, PyObject *);
3655
Tim Peters52dcce22003-01-23 16:36:11 +00003656static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003657tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003658{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003659 PyObject *result = NULL;
3660 PyObject *off = NULL, *dst = NULL;
3661 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003662
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003663 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003664 PyErr_SetString(PyExc_TypeError,
3665 "fromutc: argument must be a datetime");
3666 return NULL;
3667 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003668 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003669 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3670 "is not self");
3671 return NULL;
3672 }
Tim Peters52dcce22003-01-23 16:36:11 +00003673
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003674 off = datetime_utcoffset(dt, NULL);
3675 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003676 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003677 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003678 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3679 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003680 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003681 }
Tim Peters52dcce22003-01-23 16:36:11 +00003682
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003683 dst = datetime_dst(dt, NULL);
3684 if (dst == NULL)
3685 goto Fail;
3686 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003687 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3688 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003689 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003690 }
Tim Peters52dcce22003-01-23 16:36:11 +00003691
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003692 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3693 if (delta == NULL)
3694 goto Fail;
3695 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003696 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003697 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003698
3699 Py_DECREF(dst);
3700 dst = call_dst(GET_DT_TZINFO(dt), result);
3701 if (dst == NULL)
3702 goto Fail;
3703 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003704 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003705 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003706 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003707 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003708 if (result == NULL)
3709 goto Fail;
3710 }
3711 Py_DECREF(delta);
3712 Py_DECREF(dst);
3713 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003714 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003715
3716Inconsistent:
Serhiy Storchaka34fd4c22018-11-05 16:20:25 +02003717 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003718 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003719
Leo Ariasc3d95082018-02-03 18:36:10 -06003720 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003721Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003722 Py_XDECREF(off);
3723 Py_XDECREF(dst);
3724 Py_XDECREF(delta);
3725 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003726 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003727}
3728
Tim Peters2a799bf2002-12-16 20:18:38 +00003729/*
3730 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003731 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003732 */
3733
Guido van Rossum177e41a2003-01-30 22:06:23 +00003734static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303735tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003736{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003737 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003738 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003739 _Py_IDENTIFIER(__getinitargs__);
3740 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003741
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003742 if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) {
3743 return NULL;
3744 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003745 if (getinitargs != NULL) {
Victor Stinner2ff58a22019-06-17 14:27:23 +02003746 args = PyObject_CallNoArgs(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003747 Py_DECREF(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003748 }
3749 else {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003750 args = PyTuple_New(0);
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003751 }
3752 if (args == NULL) {
3753 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003754 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003755
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003756 if (_PyObject_LookupAttrId(self, &PyId___getstate__, &getstate) < 0) {
3757 Py_DECREF(args);
3758 return NULL;
3759 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003760 if (getstate != NULL) {
Victor Stinner2ff58a22019-06-17 14:27:23 +02003761 state = PyObject_CallNoArgs(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003762 Py_DECREF(getstate);
3763 if (state == NULL) {
3764 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003765 return NULL;
3766 }
3767 }
3768 else {
3769 PyObject **dictptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003770 state = Py_None;
3771 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003772 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003773 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003774 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003775 Py_INCREF(state);
3776 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003778 if (state == Py_None) {
3779 Py_DECREF(state);
3780 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3781 }
3782 else
3783 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003784}
Tim Peters2a799bf2002-12-16 20:18:38 +00003785
3786static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003788 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3789 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003791 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003792 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3793 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003795 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003796 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003798 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003799 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003800
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303801 {"__reduce__", tzinfo_reduce, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003802 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003804 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003805};
3806
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003807static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003808PyDoc_STR("Abstract base class for time zone info objects.");
3809
Neal Norwitz227b5332006-03-22 09:28:35 +00003810static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003811 PyVarObject_HEAD_INIT(NULL, 0)
3812 "datetime.tzinfo", /* tp_name */
3813 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3814 0, /* tp_itemsize */
3815 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003816 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003817 0, /* tp_getattr */
3818 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003819 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003820 0, /* tp_repr */
3821 0, /* tp_as_number */
3822 0, /* tp_as_sequence */
3823 0, /* tp_as_mapping */
3824 0, /* tp_hash */
3825 0, /* tp_call */
3826 0, /* tp_str */
3827 PyObject_GenericGetAttr, /* tp_getattro */
3828 0, /* tp_setattro */
3829 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003830 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003831 tzinfo_doc, /* tp_doc */
3832 0, /* tp_traverse */
3833 0, /* tp_clear */
3834 0, /* tp_richcompare */
3835 0, /* tp_weaklistoffset */
3836 0, /* tp_iter */
3837 0, /* tp_iternext */
3838 tzinfo_methods, /* tp_methods */
3839 0, /* tp_members */
3840 0, /* tp_getset */
3841 0, /* tp_base */
3842 0, /* tp_dict */
3843 0, /* tp_descr_get */
3844 0, /* tp_descr_set */
3845 0, /* tp_dictoffset */
3846 0, /* tp_init */
3847 0, /* tp_alloc */
3848 PyType_GenericNew, /* tp_new */
3849 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003850};
3851
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003852static char *timezone_kws[] = {"offset", "name", NULL};
3853
3854static PyObject *
3855timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3856{
3857 PyObject *offset;
3858 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003859 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3860 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003861 return new_timezone(offset, name);
3862
3863 return NULL;
3864}
3865
3866static void
3867timezone_dealloc(PyDateTime_TimeZone *self)
3868{
3869 Py_CLEAR(self->offset);
3870 Py_CLEAR(self->name);
3871 Py_TYPE(self)->tp_free((PyObject *)self);
3872}
3873
3874static PyObject *
3875timezone_richcompare(PyDateTime_TimeZone *self,
3876 PyDateTime_TimeZone *other, int op)
3877{
Brian Curtindfc80e32011-08-10 20:28:54 -05003878 if (op != Py_EQ && op != Py_NE)
3879 Py_RETURN_NOTIMPLEMENTED;
Pablo Galindo4be11c02019-08-22 20:24:25 +01003880 if (!PyTimezone_Check(other)) {
Serhiy Storchaka17e52642019-08-04 12:38:46 +03003881 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003882 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003883 return delta_richcompare(self->offset, other->offset, op);
3884}
3885
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003886static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003887timezone_hash(PyDateTime_TimeZone *self)
3888{
3889 return delta_hash((PyDateTime_Delta *)self->offset);
3890}
3891
3892/* Check argument type passed to tzname, utcoffset, or dst methods.
3893 Returns 0 for good argument. Returns -1 and sets exception info
3894 otherwise.
3895 */
3896static int
3897_timezone_check_argument(PyObject *dt, const char *meth)
3898{
3899 if (dt == Py_None || PyDateTime_Check(dt))
3900 return 0;
3901 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3902 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3903 return -1;
3904}
3905
3906static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003907timezone_repr(PyDateTime_TimeZone *self)
3908{
3909 /* Note that although timezone is not subclassable, it is convenient
3910 to use Py_TYPE(self)->tp_name here. */
3911 const char *type_name = Py_TYPE(self)->tp_name;
3912
3913 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3914 return PyUnicode_FromFormat("%s.utc", type_name);
3915
3916 if (self->name == NULL)
3917 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3918
3919 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3920 self->name);
3921}
3922
3923
3924static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003925timezone_str(PyDateTime_TimeZone *self)
3926{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003927 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003928 PyObject *offset;
3929 char sign;
3930
3931 if (self->name != NULL) {
3932 Py_INCREF(self->name);
3933 return self->name;
3934 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003935 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003936 (GET_TD_DAYS(self->offset) == 0 &&
3937 GET_TD_SECONDS(self->offset) == 0 &&
3938 GET_TD_MICROSECONDS(self->offset) == 0))
3939 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003940 /* Offset is normalized, so it is negative if days < 0 */
3941 if (GET_TD_DAYS(self->offset) < 0) {
3942 sign = '-';
3943 offset = delta_negative((PyDateTime_Delta *)self->offset);
3944 if (offset == NULL)
3945 return NULL;
3946 }
3947 else {
3948 sign = '+';
3949 offset = self->offset;
3950 Py_INCREF(offset);
3951 }
3952 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003953 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003954 seconds = GET_TD_SECONDS(offset);
3955 Py_DECREF(offset);
3956 minutes = divmod(seconds, 60, &seconds);
3957 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003958 if (microseconds != 0) {
3959 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3960 sign, hours, minutes,
3961 seconds, microseconds);
3962 }
3963 if (seconds != 0) {
3964 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3965 sign, hours, minutes, seconds);
3966 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003967 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003968}
3969
3970static PyObject *
3971timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3972{
3973 if (_timezone_check_argument(dt, "tzname") == -1)
3974 return NULL;
3975
3976 return timezone_str(self);
3977}
3978
3979static PyObject *
3980timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3981{
3982 if (_timezone_check_argument(dt, "utcoffset") == -1)
3983 return NULL;
3984
3985 Py_INCREF(self->offset);
3986 return self->offset;
3987}
3988
3989static PyObject *
3990timezone_dst(PyObject *self, PyObject *dt)
3991{
3992 if (_timezone_check_argument(dt, "dst") == -1)
3993 return NULL;
3994
3995 Py_RETURN_NONE;
3996}
3997
3998static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003999timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
4000{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004001 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004002 PyErr_SetString(PyExc_TypeError,
4003 "fromutc: argument must be a datetime");
4004 return NULL;
4005 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004006 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004007 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
4008 "is not self");
4009 return NULL;
4010 }
4011
4012 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
4013}
4014
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00004015static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304016timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00004017{
4018 if (self->name == NULL)
4019 return Py_BuildValue("(O)", self->offset);
4020 return Py_BuildValue("(OO)", self->offset, self->name);
4021}
4022
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004023static PyMethodDef timezone_methods[] = {
4024 {"tzname", (PyCFunction)timezone_tzname, METH_O,
4025 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00004026 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004027
4028 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00004029 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004030
4031 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00004032 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004033
4034 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
4035 PyDoc_STR("datetime in UTC -> datetime in local time.")},
4036
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00004037 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
4038 PyDoc_STR("pickle support")},
4039
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004040 {NULL, NULL}
4041};
4042
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004043static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004044PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
4045
4046static PyTypeObject PyDateTime_TimeZoneType = {
4047 PyVarObject_HEAD_INIT(NULL, 0)
4048 "datetime.timezone", /* tp_name */
4049 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
4050 0, /* tp_itemsize */
4051 (destructor)timezone_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004052 0, /* tp_vectorcall_offset */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004053 0, /* tp_getattr */
4054 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004055 0, /* tp_as_async */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00004056 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004057 0, /* tp_as_number */
4058 0, /* tp_as_sequence */
4059 0, /* tp_as_mapping */
4060 (hashfunc)timezone_hash, /* tp_hash */
4061 0, /* tp_call */
4062 (reprfunc)timezone_str, /* tp_str */
4063 0, /* tp_getattro */
4064 0, /* tp_setattro */
4065 0, /* tp_as_buffer */
4066 Py_TPFLAGS_DEFAULT, /* tp_flags */
4067 timezone_doc, /* tp_doc */
4068 0, /* tp_traverse */
4069 0, /* tp_clear */
4070 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
4071 0, /* tp_weaklistoffset */
4072 0, /* tp_iter */
4073 0, /* tp_iternext */
4074 timezone_methods, /* tp_methods */
4075 0, /* tp_members */
4076 0, /* tp_getset */
Petr Viktorin459acc52020-05-28 18:14:46 +02004077 0, /* tp_base; filled in PyInit__datetime */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004078 0, /* tp_dict */
4079 0, /* tp_descr_get */
4080 0, /* tp_descr_set */
4081 0, /* tp_dictoffset */
4082 0, /* tp_init */
4083 0, /* tp_alloc */
4084 timezone_new, /* tp_new */
4085};
4086
Tim Peters2a799bf2002-12-16 20:18:38 +00004087/*
Tim Peters37f39822003-01-10 03:49:02 +00004088 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004089 */
4090
Tim Peters37f39822003-01-10 03:49:02 +00004091/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00004092 */
4093
4094static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004095time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004097 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004098}
4099
Tim Peters37f39822003-01-10 03:49:02 +00004100static PyObject *
4101time_minute(PyDateTime_Time *self, void *unused)
4102{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004103 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00004104}
4105
4106/* The name time_second conflicted with some platform header file. */
4107static PyObject *
4108py_time_second(PyDateTime_Time *self, void *unused)
4109{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004110 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00004111}
4112
4113static PyObject *
4114time_microsecond(PyDateTime_Time *self, void *unused)
4115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004116 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00004117}
4118
4119static PyObject *
4120time_tzinfo(PyDateTime_Time *self, void *unused)
4121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004122 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4123 Py_INCREF(result);
4124 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004125}
4126
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004127static PyObject *
4128time_fold(PyDateTime_Time *self, void *unused)
4129{
4130 return PyLong_FromLong(TIME_GET_FOLD(self));
4131}
4132
Tim Peters37f39822003-01-10 03:49:02 +00004133static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004134 {"hour", (getter)time_hour},
4135 {"minute", (getter)time_minute},
4136 {"second", (getter)py_time_second},
4137 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004138 {"tzinfo", (getter)time_tzinfo},
4139 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004140 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004141};
4142
4143/*
4144 * Constructors.
4145 */
4146
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004147static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004148 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00004149
Tim Peters2a799bf2002-12-16 20:18:38 +00004150static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004151time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4152{
4153 PyDateTime_Time *me;
4154 char aware = (char)(tzinfo != Py_None);
4155
4156 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4157 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4158 return NULL;
4159 }
4160
4161 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
4162 if (me != NULL) {
4163 const char *pdata = PyBytes_AS_STRING(state);
4164
4165 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
4166 me->hashcode = -1;
4167 me->hastzinfo = aware;
4168 if (aware) {
4169 Py_INCREF(tzinfo);
4170 me->tzinfo = tzinfo;
4171 }
4172 if (pdata[0] & (1 << 7)) {
4173 me->data[0] -= 128;
4174 me->fold = 1;
4175 }
4176 else {
4177 me->fold = 0;
4178 }
4179 }
4180 return (PyObject *)me;
4181}
4182
4183static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004184time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004185{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004186 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004187 int hour = 0;
4188 int minute = 0;
4189 int second = 0;
4190 int usecond = 0;
4191 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004192 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004194 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004195 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4196 PyObject *state = PyTuple_GET_ITEM(args, 0);
4197 if (PyTuple_GET_SIZE(args) == 2) {
4198 tzinfo = PyTuple_GET_ITEM(args, 1);
4199 }
4200 if (PyBytes_Check(state)) {
4201 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
4202 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
4203 {
4204 return time_from_pickle(type, state, tzinfo);
4205 }
4206 }
4207 else if (PyUnicode_Check(state)) {
4208 if (PyUnicode_READY(state)) {
4209 return NULL;
4210 }
4211 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
Justin Blanchard122376d2019-08-29 03:36:15 -04004212 (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24)
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004213 {
4214 state = PyUnicode_AsLatin1String(state);
4215 if (state == NULL) {
4216 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4217 /* More informative error message. */
4218 PyErr_SetString(PyExc_ValueError,
4219 "Failed to encode latin1 string when unpickling "
4220 "a time object. "
4221 "pickle.load(data, encoding='latin1') is assumed.");
4222 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004223 return NULL;
4224 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004225 self = time_from_pickle(type, state, tzinfo);
4226 Py_DECREF(state);
4227 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004228 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004229 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004230 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004231 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004232
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004233 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004235 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004236 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4237 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004238 }
4239 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004240}
4241
4242/*
4243 * Destructor.
4244 */
4245
4246static void
Tim Peters37f39822003-01-10 03:49:02 +00004247time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004248{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004249 if (HASTZINFO(self)) {
4250 Py_XDECREF(self->tzinfo);
4251 }
4252 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004253}
4254
4255/*
Tim Peters855fe882002-12-22 03:43:39 +00004256 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004257 */
4258
Tim Peters2a799bf2002-12-16 20:18:38 +00004259/* These are all METH_NOARGS, so don't need to check the arglist. */
4260static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004261time_utcoffset(PyObject *self, PyObject *unused) {
4262 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004263}
4264
4265static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004266time_dst(PyObject *self, PyObject *unused) {
4267 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004268}
4269
4270static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004271time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004272 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004273}
4274
4275/*
Tim Peters37f39822003-01-10 03:49:02 +00004276 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004277 */
4278
4279static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004280time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004282 const char *type_name = Py_TYPE(self)->tp_name;
4283 int h = TIME_GET_HOUR(self);
4284 int m = TIME_GET_MINUTE(self);
4285 int s = TIME_GET_SECOND(self);
4286 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004287 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004288 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004290 if (us)
4291 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4292 type_name, h, m, s, us);
4293 else if (s)
4294 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4295 type_name, h, m, s);
4296 else
4297 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4298 if (result != NULL && HASTZINFO(self))
4299 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004300 if (result != NULL && fold)
4301 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004302 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004303}
4304
Tim Peters37f39822003-01-10 03:49:02 +00004305static PyObject *
4306time_str(PyDateTime_Time *self)
4307{
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02004308 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
Tim Peters37f39822003-01-10 03:49:02 +00004309}
Tim Peters2a799bf2002-12-16 20:18:38 +00004310
4311static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004312time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004314 char buf[100];
Andy Lesterc3fa6342020-02-24 00:40:43 -06004315 const char *timespec = NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004316 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004317 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004318 int us = TIME_GET_MICROSECOND(self);
Andy Lesterc3fa6342020-02-24 00:40:43 -06004319 static const char *specs[][2] = {
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004320 {"hours", "%02d"},
4321 {"minutes", "%02d:%02d"},
4322 {"seconds", "%02d:%02d:%02d"},
4323 {"milliseconds", "%02d:%02d:%02d.%03d"},
4324 {"microseconds", "%02d:%02d:%02d.%06d"},
4325 };
4326 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004327
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004328 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4329 return NULL;
4330
4331 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4332 if (us == 0) {
4333 /* seconds */
4334 given_spec = 2;
4335 }
4336 else {
4337 /* microseconds */
4338 given_spec = 4;
4339 }
4340 }
4341 else {
4342 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4343 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4344 if (given_spec == 3) {
4345 /* milliseconds */
4346 us = us / 1000;
4347 }
4348 break;
4349 }
4350 }
4351 }
4352
4353 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4354 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4355 return NULL;
4356 }
4357 else {
4358 result = PyUnicode_FromFormat(specs[given_spec][1],
4359 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4360 TIME_GET_SECOND(self), us);
4361 }
Tim Peters37f39822003-01-10 03:49:02 +00004362
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004363 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004364 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004366 /* We need to append the UTC offset. */
4367 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4368 Py_None) < 0) {
4369 Py_DECREF(result);
4370 return NULL;
4371 }
4372 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4373 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004374}
4375
Tim Peters37f39822003-01-10 03:49:02 +00004376static PyObject *
4377time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004379 PyObject *result;
4380 PyObject *tuple;
4381 PyObject *format;
4382 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4385 &format))
4386 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004388 /* Python's strftime does insane things with the year part of the
4389 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004390 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004391 */
4392 tuple = Py_BuildValue("iiiiiiiii",
4393 1900, 1, 1, /* year, month, day */
4394 TIME_GET_HOUR(self),
4395 TIME_GET_MINUTE(self),
4396 TIME_GET_SECOND(self),
4397 0, 1, -1); /* weekday, daynum, dst */
4398 if (tuple == NULL)
4399 return NULL;
4400 assert(PyTuple_Size(tuple) == 9);
4401 result = wrap_strftime((PyObject *)self, format, tuple,
4402 Py_None);
4403 Py_DECREF(tuple);
4404 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004405}
Tim Peters2a799bf2002-12-16 20:18:38 +00004406
4407/*
4408 * Miscellaneous methods.
4409 */
4410
Tim Peters37f39822003-01-10 03:49:02 +00004411static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004412time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004413{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004414 PyObject *result = NULL;
4415 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004416 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004417
Brian Curtindfc80e32011-08-10 20:28:54 -05004418 if (! PyTime_Check(other))
4419 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004420
4421 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004422 diff = memcmp(((PyDateTime_Time *)self)->data,
4423 ((PyDateTime_Time *)other)->data,
4424 _PyDateTime_TIME_DATASIZE);
4425 return diff_to_bool(diff, op);
4426 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004427 offset1 = time_utcoffset(self, NULL);
4428 if (offset1 == NULL)
4429 return NULL;
4430 offset2 = time_utcoffset(other, NULL);
4431 if (offset2 == NULL)
4432 goto done;
4433 /* If they're both naive, or both aware and have the same offsets,
4434 * we get off cheap. Note that if they're both naive, offset1 ==
4435 * offset2 == Py_None at this point.
4436 */
4437 if ((offset1 == offset2) ||
4438 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4439 delta_cmp(offset1, offset2) == 0)) {
4440 diff = memcmp(((PyDateTime_Time *)self)->data,
4441 ((PyDateTime_Time *)other)->data,
4442 _PyDateTime_TIME_DATASIZE);
4443 result = diff_to_bool(diff, op);
4444 }
4445 /* The hard case: both aware with different UTC offsets */
4446 else if (offset1 != Py_None && offset2 != Py_None) {
4447 int offsecs1, offsecs2;
4448 assert(offset1 != offset2); /* else last "if" handled it */
4449 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4450 TIME_GET_MINUTE(self) * 60 +
4451 TIME_GET_SECOND(self) -
4452 GET_TD_DAYS(offset1) * 86400 -
4453 GET_TD_SECONDS(offset1);
4454 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4455 TIME_GET_MINUTE(other) * 60 +
4456 TIME_GET_SECOND(other) -
4457 GET_TD_DAYS(offset2) * 86400 -
4458 GET_TD_SECONDS(offset2);
4459 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004460 if (diff == 0)
4461 diff = TIME_GET_MICROSECOND(self) -
4462 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004463 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004464 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004465 else if (op == Py_EQ) {
4466 result = Py_False;
4467 Py_INCREF(result);
4468 }
4469 else if (op == Py_NE) {
4470 result = Py_True;
4471 Py_INCREF(result);
4472 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004473 else {
4474 PyErr_SetString(PyExc_TypeError,
4475 "can't compare offset-naive and "
4476 "offset-aware times");
4477 }
4478 done:
4479 Py_DECREF(offset1);
4480 Py_XDECREF(offset2);
4481 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004482}
4483
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004484static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004485time_hash(PyDateTime_Time *self)
4486{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004487 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004488 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004489 if (TIME_GET_FOLD(self)) {
4490 self0 = new_time_ex2(TIME_GET_HOUR(self),
4491 TIME_GET_MINUTE(self),
4492 TIME_GET_SECOND(self),
4493 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004494 HASTZINFO(self) ? self->tzinfo : Py_None,
4495 0, Py_TYPE(self));
4496 if (self0 == NULL)
4497 return -1;
4498 }
4499 else {
4500 self0 = (PyObject *)self;
4501 Py_INCREF(self0);
4502 }
4503 offset = time_utcoffset(self0, NULL);
4504 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004505
4506 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004507 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004509 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004510 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004511 self->hashcode = generic_hash(
4512 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004513 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004514 PyObject *temp1, *temp2;
4515 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004516 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004517 seconds = TIME_GET_HOUR(self) * 3600 +
4518 TIME_GET_MINUTE(self) * 60 +
4519 TIME_GET_SECOND(self);
4520 microseconds = TIME_GET_MICROSECOND(self);
4521 temp1 = new_delta(0, seconds, microseconds, 1);
4522 if (temp1 == NULL) {
4523 Py_DECREF(offset);
4524 return -1;
4525 }
4526 temp2 = delta_subtract(temp1, offset);
4527 Py_DECREF(temp1);
4528 if (temp2 == NULL) {
4529 Py_DECREF(offset);
4530 return -1;
4531 }
4532 self->hashcode = PyObject_Hash(temp2);
4533 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004534 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004535 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004536 }
4537 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004538}
Tim Peters2a799bf2002-12-16 20:18:38 +00004539
Tim Peters12bf3392002-12-24 05:41:27 +00004540static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004541time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004543 PyObject *clone;
4544 PyObject *tuple;
4545 int hh = TIME_GET_HOUR(self);
4546 int mm = TIME_GET_MINUTE(self);
4547 int ss = TIME_GET_SECOND(self);
4548 int us = TIME_GET_MICROSECOND(self);
4549 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004550 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004551
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004552 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004553 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004554 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004555 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004556 if (fold != 0 && fold != 1) {
4557 PyErr_SetString(PyExc_ValueError,
4558 "fold must be either 0 or 1");
4559 return NULL;
4560 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004561 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4562 if (tuple == NULL)
4563 return NULL;
4564 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004565 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004566 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004567 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004568 Py_DECREF(tuple);
4569 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004570}
4571
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004572static PyObject *
4573time_fromisoformat(PyObject *cls, PyObject *tstr) {
4574 assert(tstr != NULL);
4575
4576 if (!PyUnicode_Check(tstr)) {
4577 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4578 return NULL;
4579 }
4580
4581 Py_ssize_t len;
4582 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4583
Paul Ganssle096329f2018-08-23 11:06:20 -04004584 if (p == NULL) {
4585 goto invalid_string_error;
4586 }
4587
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004588 int hour = 0, minute = 0, second = 0, microsecond = 0;
4589 int tzoffset, tzimicrosecond = 0;
4590 int rv = parse_isoformat_time(p, len,
4591 &hour, &minute, &second, &microsecond,
4592 &tzoffset, &tzimicrosecond);
4593
4594 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04004595 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004596 }
4597
4598 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4599 tzimicrosecond);
4600
4601 if (tzinfo == NULL) {
4602 return NULL;
4603 }
4604
4605 PyObject *t;
4606 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4607 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4608 } else {
4609 t = PyObject_CallFunction(cls, "iiiiO",
4610 hour, minute, second, microsecond, tzinfo);
4611 }
4612
4613 Py_DECREF(tzinfo);
4614 return t;
Paul Ganssle096329f2018-08-23 11:06:20 -04004615
4616invalid_string_error:
4617 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4618 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004619}
4620
4621
Tim Peters371935f2003-02-01 01:52:50 +00004622/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004623
Tim Peters33e0f382003-01-10 02:05:14 +00004624/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004625 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4626 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004627 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004628 */
4629static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004630time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004632 PyObject *basestate;
4633 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004635 basestate = PyBytes_FromStringAndSize((char *)self->data,
4636 _PyDateTime_TIME_DATASIZE);
4637 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004638 if (proto > 3 && TIME_GET_FOLD(self))
4639 /* Set the first bit of the first byte */
4640 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004641 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4642 result = PyTuple_Pack(1, basestate);
4643 else
4644 result = PyTuple_Pack(2, basestate, self->tzinfo);
4645 Py_DECREF(basestate);
4646 }
4647 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004648}
4649
4650static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004651time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004652{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004653 int proto;
4654 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004655 return NULL;
4656
4657 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004658}
4659
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004660static PyObject *
4661time_reduce(PyDateTime_Time *self, PyObject *arg)
4662{
4663 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4664}
4665
Tim Peters37f39822003-01-10 03:49:02 +00004666static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004667
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004668 {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS,
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004669 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4670 "[+HH:MM].\n\n"
4671 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004672
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004673 {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004674 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004676 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4677 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004679 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4680 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004682 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4683 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004685 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4686 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004687
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004688 {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004689 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004690
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004691 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4692 PyDoc_STR("string -> time from time.isoformat() output")},
4693
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004694 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004695 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004696
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004697 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4698 PyDoc_STR("__reduce__() -> (cls, state)")},
4699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004700 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004701};
4702
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004703static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004704PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4705\n\
4706All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004707a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004708
Neal Norwitz227b5332006-03-22 09:28:35 +00004709static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004710 PyVarObject_HEAD_INIT(NULL, 0)
4711 "datetime.time", /* tp_name */
4712 sizeof(PyDateTime_Time), /* tp_basicsize */
4713 0, /* tp_itemsize */
4714 (destructor)time_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004715 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004716 0, /* tp_getattr */
4717 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004718 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004719 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004720 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004721 0, /* tp_as_sequence */
4722 0, /* tp_as_mapping */
4723 (hashfunc)time_hash, /* tp_hash */
4724 0, /* tp_call */
4725 (reprfunc)time_str, /* tp_str */
4726 PyObject_GenericGetAttr, /* tp_getattro */
4727 0, /* tp_setattro */
4728 0, /* tp_as_buffer */
4729 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4730 time_doc, /* tp_doc */
4731 0, /* tp_traverse */
4732 0, /* tp_clear */
4733 time_richcompare, /* tp_richcompare */
4734 0, /* tp_weaklistoffset */
4735 0, /* tp_iter */
4736 0, /* tp_iternext */
4737 time_methods, /* tp_methods */
4738 0, /* tp_members */
4739 time_getset, /* tp_getset */
4740 0, /* tp_base */
4741 0, /* tp_dict */
4742 0, /* tp_descr_get */
4743 0, /* tp_descr_set */
4744 0, /* tp_dictoffset */
4745 0, /* tp_init */
4746 time_alloc, /* tp_alloc */
4747 time_new, /* tp_new */
4748 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004749};
4750
4751/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004752 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004753 */
4754
Tim Petersa9bc1682003-01-11 03:39:11 +00004755/* Accessor properties. Properties for day, month, and year are inherited
4756 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004757 */
4758
4759static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004760datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004762 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004763}
4764
Tim Petersa9bc1682003-01-11 03:39:11 +00004765static PyObject *
4766datetime_minute(PyDateTime_DateTime *self, void *unused)
4767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004768 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004769}
4770
4771static PyObject *
4772datetime_second(PyDateTime_DateTime *self, void *unused)
4773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004774 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004775}
4776
4777static PyObject *
4778datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4779{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004780 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004781}
4782
4783static PyObject *
4784datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004786 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4787 Py_INCREF(result);
4788 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004789}
4790
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004791static PyObject *
4792datetime_fold(PyDateTime_DateTime *self, void *unused)
4793{
4794 return PyLong_FromLong(DATE_GET_FOLD(self));
4795}
4796
Tim Petersa9bc1682003-01-11 03:39:11 +00004797static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004798 {"hour", (getter)datetime_hour},
4799 {"minute", (getter)datetime_minute},
4800 {"second", (getter)datetime_second},
4801 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004802 {"tzinfo", (getter)datetime_tzinfo},
4803 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004804 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004805};
4806
4807/*
4808 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004809 */
4810
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004811static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004812 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004813 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004814};
4815
Tim Peters2a799bf2002-12-16 20:18:38 +00004816static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004817datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4818{
4819 PyDateTime_DateTime *me;
4820 char aware = (char)(tzinfo != Py_None);
4821
4822 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4823 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4824 return NULL;
4825 }
4826
4827 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4828 if (me != NULL) {
4829 const char *pdata = PyBytes_AS_STRING(state);
4830
4831 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4832 me->hashcode = -1;
4833 me->hastzinfo = aware;
4834 if (aware) {
4835 Py_INCREF(tzinfo);
4836 me->tzinfo = tzinfo;
4837 }
4838 if (pdata[2] & (1 << 7)) {
4839 me->data[2] -= 128;
4840 me->fold = 1;
4841 }
4842 else {
4843 me->fold = 0;
4844 }
4845 }
4846 return (PyObject *)me;
4847}
4848
4849static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004850datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004851{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004852 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004853 int year;
4854 int month;
4855 int day;
4856 int hour = 0;
4857 int minute = 0;
4858 int second = 0;
4859 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004860 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004861 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004863 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004864 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4865 PyObject *state = PyTuple_GET_ITEM(args, 0);
4866 if (PyTuple_GET_SIZE(args) == 2) {
4867 tzinfo = PyTuple_GET_ITEM(args, 1);
4868 }
4869 if (PyBytes_Check(state)) {
4870 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4871 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4872 {
4873 return datetime_from_pickle(type, state, tzinfo);
4874 }
4875 }
4876 else if (PyUnicode_Check(state)) {
4877 if (PyUnicode_READY(state)) {
4878 return NULL;
4879 }
4880 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4881 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4882 {
4883 state = PyUnicode_AsLatin1String(state);
4884 if (state == NULL) {
4885 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4886 /* More informative error message. */
4887 PyErr_SetString(PyExc_ValueError,
4888 "Failed to encode latin1 string when unpickling "
4889 "a datetime object. "
4890 "pickle.load(data, encoding='latin1') is assumed.");
4891 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004892 return NULL;
4893 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004894 self = datetime_from_pickle(type, state, tzinfo);
4895 Py_DECREF(state);
4896 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004897 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004898 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004899 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004900 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004901
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004902 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004903 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004904 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004905 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004906 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004907 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004908 }
4909 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004910}
4911
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004912/* TM_FUNC is the shared type of _PyTime_localtime() and
4913 * _PyTime_gmtime(). */
4914typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004915
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004916/* As of version 2015f max fold in IANA database is
4917 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004918static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004919/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004920static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004921
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004922static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004923utc_to_seconds(int year, int month, int day,
4924 int hour, int minute, int second)
4925{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004926 long long ordinal;
4927
4928 /* ymd_to_ord() doesn't support year <= 0 */
4929 if (year < MINYEAR || year > MAXYEAR) {
4930 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4931 return -1;
4932 }
4933
4934 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004935 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4936}
4937
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004938static long long
4939local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004940{
4941 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004942 time_t t;
4943 u -= epoch;
4944 t = u;
4945 if (t != u) {
4946 PyErr_SetString(PyExc_OverflowError,
4947 "timestamp out of range for platform time_t");
4948 return -1;
4949 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004950 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004951 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004952 return utc_to_seconds(local_time.tm_year + 1900,
4953 local_time.tm_mon + 1,
4954 local_time.tm_mday,
4955 local_time.tm_hour,
4956 local_time.tm_min,
4957 local_time.tm_sec);
4958}
4959
Tim Petersa9bc1682003-01-11 03:39:11 +00004960/* Internal helper.
4961 * Build datetime from a time_t and a distinct count of microseconds.
4962 * Pass localtime or gmtime for f, to control the interpretation of timet.
4963 */
4964static PyObject *
4965datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004966 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004967{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004968 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004969 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004970
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004971 if (f(timet, &tm) != 0)
4972 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004973
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004974 year = tm.tm_year + 1900;
4975 month = tm.tm_mon + 1;
4976 day = tm.tm_mday;
4977 hour = tm.tm_hour;
4978 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004979 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004980 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004981 * except to the extent that passing them on to the datetime
4982 * constructor would raise ValueError for a reason that
4983 * made no sense to the user.
4984 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004985 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004986
Victor Stinnerb67f0962017-02-10 10:34:02 +01004987 /* local timezone requires to compute fold */
Ammar Askar96d1e692018-07-25 09:54:58 -07004988 if (tzinfo == Py_None && f == _PyTime_localtime
4989 /* On Windows, passing a negative value to local results
4990 * in an OSError because localtime_s on Windows does
4991 * not support negative timestamps. Unfortunately this
4992 * means that fold detection for time values between
4993 * 0 and max_fold_seconds will result in an identical
4994 * error since we subtract max_fold_seconds to detect a
4995 * fold. However, since we know there haven't been any
4996 * folds in the interval [0, max_fold_seconds) in any
4997 * timezone, we can hackily just forego fold detection
4998 * for this time range.
4999 */
5000#ifdef MS_WINDOWS
5001 && (timet - max_fold_seconds > 0)
5002#endif
5003 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005004 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005005
5006 result_seconds = utc_to_seconds(year, month, day,
5007 hour, minute, second);
5008 /* Probe max_fold_seconds to detect a fold. */
5009 probe_seconds = local(epoch + timet - max_fold_seconds);
5010 if (probe_seconds == -1)
5011 return NULL;
5012 transition = result_seconds - probe_seconds - max_fold_seconds;
5013 if (transition < 0) {
5014 probe_seconds = local(epoch + timet + transition);
5015 if (probe_seconds == -1)
5016 return NULL;
5017 if (probe_seconds == result_seconds)
5018 fold = 1;
5019 }
5020 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005021 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
5022 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00005023}
5024
5025/* Internal helper.
5026 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
5027 * to control the interpretation of the timestamp. Since a double doesn't
5028 * have enough bits to cover a datetime's full range of precision, it's
5029 * better to call datetime_from_timet_and_us provided you have a way
5030 * to get that much precision (e.g., C time() isn't good enough).
5031 */
5032static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01005033datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005034 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00005035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005036 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01005037 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00005038
Victor Stinnere4a994d2015-03-30 01:10:14 +02005039 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02005040 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005041 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02005042
Victor Stinner21f58932012-03-14 00:15:40 +01005043 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00005044}
5045
5046/* Internal helper.
5047 * Build most accurate possible datetime for current time. Pass localtime or
5048 * gmtime for f as appropriate.
5049 */
5050static PyObject *
5051datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
5052{
Victor Stinner09e5cf22015-03-30 00:09:18 +02005053 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02005054 time_t secs;
5055 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02005056
Victor Stinner1e2b6882015-09-18 13:23:02 +02005057 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02005058 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02005059 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02005060
Victor Stinner1e2b6882015-09-18 13:23:02 +02005061 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00005062}
5063
Larry Hastings61272b72014-01-07 12:41:53 -08005064/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07005065
5066@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005067datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07005068
5069 tz: object = None
5070 Timezone object.
5071
5072Returns new datetime object representing current time local to tz.
5073
5074If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08005075[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07005076
Larry Hastings31826802013-10-19 00:09:25 -07005077static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08005078datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005079/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00005080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005081 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005082
Larry Hastings31826802013-10-19 00:09:25 -07005083 /* Return best possible local time -- this isn't constrained by the
5084 * precision of a timestamp.
5085 */
5086 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005087 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00005088
Larry Hastings5c661892014-01-24 06:17:25 -08005089 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005090 tz == Py_None ? _PyTime_localtime :
5091 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07005092 tz);
5093 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005094 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02005095 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005096 }
5097 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005098}
5099
Tim Petersa9bc1682003-01-11 03:39:11 +00005100/* Return best possible UTC time -- this isn't constrained by the
5101 * precision of a timestamp.
5102 */
5103static PyObject *
5104datetime_utcnow(PyObject *cls, PyObject *dummy)
5105{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005106 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00005107}
5108
Tim Peters2a799bf2002-12-16 20:18:38 +00005109/* Return new local datetime from timestamp (Python timestamp -- a double). */
5110static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005111datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005113 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01005114 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005115 PyObject *tzinfo = Py_None;
5116 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00005117
Victor Stinner5d272cc2012-03-13 13:35:55 +01005118 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005119 keywords, &timestamp, &tzinfo))
5120 return NULL;
5121 if (check_tzinfo_subclass(tzinfo) < 0)
5122 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00005123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005124 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005125 tzinfo == Py_None ? _PyTime_localtime :
5126 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005127 timestamp,
5128 tzinfo);
5129 if (self != NULL && tzinfo != Py_None) {
5130 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02005131 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005132 }
5133 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005134}
5135
Tim Petersa9bc1682003-01-11 03:39:11 +00005136/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
5137static PyObject *
5138datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
5139{
Victor Stinner5d272cc2012-03-13 13:35:55 +01005140 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005141 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005142
Victor Stinner5d272cc2012-03-13 13:35:55 +01005143 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005144 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005145 Py_None);
5146 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005147}
5148
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005149/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005150static PyObject *
5151datetime_strptime(PyObject *cls, PyObject *args)
5152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005153 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005154 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02005155 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005156
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005157 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005158 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005159
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005160 if (module == NULL) {
5161 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00005162 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005163 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005164 }
Victor Stinner20401de2016-12-09 15:24:31 +01005165 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
5166 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005167}
5168
Tim Petersa9bc1682003-01-11 03:39:11 +00005169/* Return new datetime from date/datetime and time arguments. */
5170static PyObject *
5171datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
5172{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005173 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005174 PyObject *date;
5175 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005176 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005177 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00005178
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005179 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005180 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005181 &PyDateTime_TimeType, &time, &tzinfo)) {
5182 if (tzinfo == NULL) {
5183 if (HASTZINFO(time))
5184 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
5185 else
5186 tzinfo = Py_None;
5187 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005188 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
5189 GET_MONTH(date),
5190 GET_DAY(date),
5191 TIME_GET_HOUR(time),
5192 TIME_GET_MINUTE(time),
5193 TIME_GET_SECOND(time),
5194 TIME_GET_MICROSECOND(time),
5195 tzinfo,
5196 TIME_GET_FOLD(time),
5197 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005198 }
5199 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005200}
Tim Peters2a799bf2002-12-16 20:18:38 +00005201
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005202static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005203_sanitize_isoformat_str(PyObject *dtstr)
5204{
Paul Ganssle096329f2018-08-23 11:06:20 -04005205 // `fromisoformat` allows surrogate characters in exactly one position,
5206 // the separator; to allow datetime_fromisoformat to make the simplifying
5207 // assumption that all valid strings can be encoded in UTF-8, this function
5208 // replaces any surrogate character separators with `T`.
Paul Ganssle3df85402018-10-22 12:32:52 -04005209 //
5210 // The result of this, if not NULL, returns a new reference
Paul Ganssle096329f2018-08-23 11:06:20 -04005211 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005212 if (len < 0) {
5213 return NULL;
5214 }
5215
5216 if (len <= 10 ||
5217 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
5218 Py_INCREF(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005219 return dtstr;
5220 }
5221
Paul Ganssle3df85402018-10-22 12:32:52 -04005222 PyObject *str_out = _PyUnicode_Copy(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005223 if (str_out == NULL) {
5224 return NULL;
5225 }
5226
Paul Ganssle3df85402018-10-22 12:32:52 -04005227 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005228 Py_DECREF(str_out);
5229 return NULL;
5230 }
5231
Paul Ganssle096329f2018-08-23 11:06:20 -04005232 return str_out;
5233}
5234
5235static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005236datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5237{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005238 assert(dtstr != NULL);
5239
5240 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005241 PyErr_SetString(PyExc_TypeError,
5242 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005243 return NULL;
5244 }
5245
Paul Ganssle3df85402018-10-22 12:32:52 -04005246 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5247 if (dtstr_clean == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005248 goto error;
5249 }
5250
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005251 Py_ssize_t len;
Paul Ganssle3df85402018-10-22 12:32:52 -04005252 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04005253
5254 if (dt_ptr == NULL) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005255 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5256 // Encoding errors are invalid string errors at this point
5257 goto invalid_string_error;
5258 }
5259 else {
5260 goto error;
5261 }
Paul Ganssle096329f2018-08-23 11:06:20 -04005262 }
5263
5264 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005265
5266 int year = 0, month = 0, day = 0;
5267 int hour = 0, minute = 0, second = 0, microsecond = 0;
5268 int tzoffset = 0, tzusec = 0;
5269
5270 // date has a fixed length of 10
5271 int rv = parse_isoformat_date(p, &year, &month, &day);
5272
5273 if (!rv && len > 10) {
5274 // In UTF-8, the length of multi-byte characters is encoded in the MSB
5275 if ((p[10] & 0x80) == 0) {
5276 p += 11;
Paul Ganssle3df85402018-10-22 12:32:52 -04005277 }
5278 else {
5279 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005280 case 0xe0:
5281 p += 13;
5282 break;
5283 case 0xf0:
5284 p += 14;
5285 break;
5286 default:
5287 p += 12;
5288 break;
5289 }
5290 }
5291
5292 len -= (p - dt_ptr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005293 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5294 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005295 }
5296 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005297 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005298 }
5299
Paul Ganssle3df85402018-10-22 12:32:52 -04005300 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005301 if (tzinfo == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005302 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005303 }
5304
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005305 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5306 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005307
5308 Py_DECREF(tzinfo);
Paul Ganssle3df85402018-10-22 12:32:52 -04005309 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005310 return dt;
Paul Ganssle096329f2018-08-23 11:06:20 -04005311
5312invalid_string_error:
5313 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5314
5315error:
Paul Ganssle3df85402018-10-22 12:32:52 -04005316 Py_XDECREF(dtstr_clean);
Paul Ganssle096329f2018-08-23 11:06:20 -04005317
5318 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005319}
5320
Tim Peters2a799bf2002-12-16 20:18:38 +00005321/*
5322 * Destructor.
5323 */
5324
5325static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005326datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005328 if (HASTZINFO(self)) {
5329 Py_XDECREF(self->tzinfo);
5330 }
5331 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005332}
5333
5334/*
5335 * Indirect access to tzinfo methods.
5336 */
5337
Tim Peters2a799bf2002-12-16 20:18:38 +00005338/* These are all METH_NOARGS, so don't need to check the arglist. */
5339static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005340datetime_utcoffset(PyObject *self, PyObject *unused) {
5341 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005342}
5343
5344static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005345datetime_dst(PyObject *self, PyObject *unused) {
5346 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005347}
5348
5349static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005350datetime_tzname(PyObject *self, PyObject *unused) {
5351 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005352}
5353
5354/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005355 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005356 */
5357
Tim Petersa9bc1682003-01-11 03:39:11 +00005358/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5359 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005360 */
5361static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005362add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005363 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005365 /* Note that the C-level additions can't overflow, because of
5366 * invariant bounds on the member values.
5367 */
5368 int year = GET_YEAR(date);
5369 int month = GET_MONTH(date);
5370 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5371 int hour = DATE_GET_HOUR(date);
5372 int minute = DATE_GET_MINUTE(date);
5373 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5374 int microsecond = DATE_GET_MICROSECOND(date) +
5375 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005377 assert(factor == 1 || factor == -1);
5378 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005379 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005380 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005381 }
5382
Paul Ganssle89427cd2019-02-04 14:42:04 -05005383 return new_datetime_subclass_ex(year, month, day,
5384 hour, minute, second, microsecond,
5385 HASTZINFO(date) ? date->tzinfo : Py_None,
5386 (PyObject *)Py_TYPE(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00005387}
5388
5389static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005390datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005392 if (PyDateTime_Check(left)) {
5393 /* datetime + ??? */
5394 if (PyDelta_Check(right))
5395 /* datetime + delta */
5396 return add_datetime_timedelta(
5397 (PyDateTime_DateTime *)left,
5398 (PyDateTime_Delta *)right,
5399 1);
5400 }
5401 else if (PyDelta_Check(left)) {
5402 /* delta + datetime */
5403 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5404 (PyDateTime_Delta *) left,
5405 1);
5406 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005407 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005408}
5409
5410static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005411datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005413 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005415 if (PyDateTime_Check(left)) {
5416 /* datetime - ??? */
5417 if (PyDateTime_Check(right)) {
5418 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005419 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005420 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005421
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005422 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5423 offset2 = offset1 = Py_None;
5424 Py_INCREF(offset1);
5425 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005426 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005427 else {
5428 offset1 = datetime_utcoffset(left, NULL);
5429 if (offset1 == NULL)
5430 return NULL;
5431 offset2 = datetime_utcoffset(right, NULL);
5432 if (offset2 == NULL) {
5433 Py_DECREF(offset1);
5434 return NULL;
5435 }
5436 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5437 PyErr_SetString(PyExc_TypeError,
5438 "can't subtract offset-naive and "
5439 "offset-aware datetimes");
5440 Py_DECREF(offset1);
5441 Py_DECREF(offset2);
5442 return NULL;
5443 }
5444 }
5445 if ((offset1 != offset2) &&
5446 delta_cmp(offset1, offset2) != 0) {
5447 offdiff = delta_subtract(offset1, offset2);
5448 if (offdiff == NULL) {
5449 Py_DECREF(offset1);
5450 Py_DECREF(offset2);
5451 return NULL;
5452 }
5453 }
5454 Py_DECREF(offset1);
5455 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005456 delta_d = ymd_to_ord(GET_YEAR(left),
5457 GET_MONTH(left),
5458 GET_DAY(left)) -
5459 ymd_to_ord(GET_YEAR(right),
5460 GET_MONTH(right),
5461 GET_DAY(right));
5462 /* These can't overflow, since the values are
5463 * normalized. At most this gives the number of
5464 * seconds in one day.
5465 */
5466 delta_s = (DATE_GET_HOUR(left) -
5467 DATE_GET_HOUR(right)) * 3600 +
5468 (DATE_GET_MINUTE(left) -
5469 DATE_GET_MINUTE(right)) * 60 +
5470 (DATE_GET_SECOND(left) -
5471 DATE_GET_SECOND(right));
5472 delta_us = DATE_GET_MICROSECOND(left) -
5473 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005474 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005475 if (result == NULL)
5476 return NULL;
5477
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005478 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005479 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005480 Py_DECREF(offdiff);
5481 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005482 }
5483 else if (PyDelta_Check(right)) {
5484 /* datetime - delta */
5485 result = add_datetime_timedelta(
5486 (PyDateTime_DateTime *)left,
5487 (PyDateTime_Delta *)right,
5488 -1);
5489 }
5490 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005492 if (result == Py_NotImplemented)
5493 Py_INCREF(result);
5494 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005495}
5496
5497/* Various ways to turn a datetime into a string. */
5498
5499static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005500datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005502 const char *type_name = Py_TYPE(self)->tp_name;
5503 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005505 if (DATE_GET_MICROSECOND(self)) {
5506 baserepr = PyUnicode_FromFormat(
5507 "%s(%d, %d, %d, %d, %d, %d, %d)",
5508 type_name,
5509 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5510 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5511 DATE_GET_SECOND(self),
5512 DATE_GET_MICROSECOND(self));
5513 }
5514 else if (DATE_GET_SECOND(self)) {
5515 baserepr = PyUnicode_FromFormat(
5516 "%s(%d, %d, %d, %d, %d, %d)",
5517 type_name,
5518 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5519 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5520 DATE_GET_SECOND(self));
5521 }
5522 else {
5523 baserepr = PyUnicode_FromFormat(
5524 "%s(%d, %d, %d, %d, %d)",
5525 type_name,
5526 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5527 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5528 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005529 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5530 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005531 if (baserepr == NULL || ! HASTZINFO(self))
5532 return baserepr;
5533 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005534}
5535
Tim Petersa9bc1682003-01-11 03:39:11 +00005536static PyObject *
5537datetime_str(PyDateTime_DateTime *self)
5538{
Victor Stinner4c381542016-12-09 00:33:39 +01005539 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005540}
Tim Peters2a799bf2002-12-16 20:18:38 +00005541
5542static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005543datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005545 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005546 char *timespec = NULL;
5547 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005548 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005549 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005550 int us = DATE_GET_MICROSECOND(self);
Andy Lesterc3fa6342020-02-24 00:40:43 -06005551 static const char *specs[][2] = {
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005552 {"hours", "%04d-%02d-%02d%c%02d"},
5553 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5554 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5555 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5556 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5557 };
5558 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005559
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005560 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005561 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005562
5563 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5564 if (us == 0) {
5565 /* seconds */
5566 given_spec = 2;
5567 }
5568 else {
5569 /* microseconds */
5570 given_spec = 4;
5571 }
5572 }
5573 else {
5574 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5575 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5576 if (given_spec == 3) {
5577 us = us / 1000;
5578 }
5579 break;
5580 }
5581 }
5582 }
5583
5584 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5585 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5586 return NULL;
5587 }
5588 else {
5589 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005590 GET_YEAR(self), GET_MONTH(self),
5591 GET_DAY(self), (int)sep,
5592 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5593 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005594 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005596 if (!result || !HASTZINFO(self))
5597 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005599 /* We need to append the UTC offset. */
5600 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5601 (PyObject *)self) < 0) {
5602 Py_DECREF(result);
5603 return NULL;
5604 }
5605 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5606 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005607}
5608
Tim Petersa9bc1682003-01-11 03:39:11 +00005609static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305610datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005612 return format_ctime((PyDateTime_Date *)self,
5613 DATE_GET_HOUR(self),
5614 DATE_GET_MINUTE(self),
5615 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005616}
5617
Tim Peters2a799bf2002-12-16 20:18:38 +00005618/* Miscellaneous methods. */
5619
Tim Petersa9bc1682003-01-11 03:39:11 +00005620static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005621flip_fold(PyObject *dt)
5622{
5623 return new_datetime_ex2(GET_YEAR(dt),
5624 GET_MONTH(dt),
5625 GET_DAY(dt),
5626 DATE_GET_HOUR(dt),
5627 DATE_GET_MINUTE(dt),
5628 DATE_GET_SECOND(dt),
5629 DATE_GET_MICROSECOND(dt),
5630 HASTZINFO(dt) ?
5631 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5632 !DATE_GET_FOLD(dt),
5633 Py_TYPE(dt));
5634}
5635
5636static PyObject *
5637get_flip_fold_offset(PyObject *dt)
5638{
5639 PyObject *result, *flip_dt;
5640
5641 flip_dt = flip_fold(dt);
5642 if (flip_dt == NULL)
5643 return NULL;
5644 result = datetime_utcoffset(flip_dt, NULL);
5645 Py_DECREF(flip_dt);
5646 return result;
5647}
5648
5649/* PEP 495 exception: Whenever one or both of the operands in
5650 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakabac2d5b2018-03-28 22:14:26 +03005651 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005652 *
5653 * Return 1 if exception applies, 0 if not, and -1 on error.
5654 */
5655static int
5656pep495_eq_exception(PyObject *self, PyObject *other,
5657 PyObject *offset_self, PyObject *offset_other)
5658{
5659 int result = 0;
5660 PyObject *flip_offset;
5661
5662 flip_offset = get_flip_fold_offset(self);
5663 if (flip_offset == NULL)
5664 return -1;
5665 if (flip_offset != offset_self &&
5666 delta_cmp(flip_offset, offset_self))
5667 {
5668 result = 1;
5669 goto done;
5670 }
5671 Py_DECREF(flip_offset);
5672
5673 flip_offset = get_flip_fold_offset(other);
5674 if (flip_offset == NULL)
5675 return -1;
5676 if (flip_offset != offset_other &&
5677 delta_cmp(flip_offset, offset_other))
5678 result = 1;
5679 done:
5680 Py_DECREF(flip_offset);
5681 return result;
5682}
5683
5684static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005685datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005686{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005687 PyObject *result = NULL;
5688 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005689 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005691 if (! PyDateTime_Check(other)) {
5692 if (PyDate_Check(other)) {
5693 /* Prevent invocation of date_richcompare. We want to
5694 return NotImplemented here to give the other object
5695 a chance. But since DateTime is a subclass of
5696 Date, if the other object is a Date, it would
5697 compute an ordering based on the date part alone,
5698 and we don't want that. So force unequal or
5699 uncomparable here in that case. */
5700 if (op == Py_EQ)
5701 Py_RETURN_FALSE;
5702 if (op == Py_NE)
5703 Py_RETURN_TRUE;
5704 return cmperror(self, other);
5705 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005706 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005707 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005708
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005709 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005710 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5711 ((PyDateTime_DateTime *)other)->data,
5712 _PyDateTime_DATETIME_DATASIZE);
5713 return diff_to_bool(diff, op);
5714 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005715 offset1 = datetime_utcoffset(self, NULL);
5716 if (offset1 == NULL)
5717 return NULL;
5718 offset2 = datetime_utcoffset(other, NULL);
5719 if (offset2 == NULL)
5720 goto done;
5721 /* If they're both naive, or both aware and have the same offsets,
5722 * we get off cheap. Note that if they're both naive, offset1 ==
5723 * offset2 == Py_None at this point.
5724 */
5725 if ((offset1 == offset2) ||
5726 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5727 delta_cmp(offset1, offset2) == 0)) {
5728 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5729 ((PyDateTime_DateTime *)other)->data,
5730 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005731 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5732 int ex = pep495_eq_exception(self, other, offset1, offset2);
5733 if (ex == -1)
5734 goto done;
5735 if (ex)
5736 diff = 1;
5737 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005738 result = diff_to_bool(diff, op);
5739 }
5740 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005741 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005742
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005743 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005744 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5745 other);
5746 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005747 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005748 diff = GET_TD_DAYS(delta);
5749 if (diff == 0)
5750 diff = GET_TD_SECONDS(delta) |
5751 GET_TD_MICROSECONDS(delta);
5752 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005753 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5754 int ex = pep495_eq_exception(self, other, offset1, offset2);
5755 if (ex == -1)
5756 goto done;
5757 if (ex)
5758 diff = 1;
5759 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005760 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005761 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005762 else if (op == Py_EQ) {
5763 result = Py_False;
5764 Py_INCREF(result);
5765 }
5766 else if (op == Py_NE) {
5767 result = Py_True;
5768 Py_INCREF(result);
5769 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005770 else {
5771 PyErr_SetString(PyExc_TypeError,
5772 "can't compare offset-naive and "
5773 "offset-aware datetimes");
5774 }
5775 done:
5776 Py_DECREF(offset1);
5777 Py_XDECREF(offset2);
5778 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005779}
5780
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005781static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005782datetime_hash(PyDateTime_DateTime *self)
5783{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005784 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005785 PyObject *offset, *self0;
5786 if (DATE_GET_FOLD(self)) {
5787 self0 = new_datetime_ex2(GET_YEAR(self),
5788 GET_MONTH(self),
5789 GET_DAY(self),
5790 DATE_GET_HOUR(self),
5791 DATE_GET_MINUTE(self),
5792 DATE_GET_SECOND(self),
5793 DATE_GET_MICROSECOND(self),
5794 HASTZINFO(self) ? self->tzinfo : Py_None,
5795 0, Py_TYPE(self));
5796 if (self0 == NULL)
5797 return -1;
5798 }
5799 else {
5800 self0 = (PyObject *)self;
5801 Py_INCREF(self0);
5802 }
5803 offset = datetime_utcoffset(self0, NULL);
5804 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005805
5806 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005807 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005809 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005810 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005811 self->hashcode = generic_hash(
5812 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005813 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005814 PyObject *temp1, *temp2;
5815 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005817 assert(HASTZINFO(self));
5818 days = ymd_to_ord(GET_YEAR(self),
5819 GET_MONTH(self),
5820 GET_DAY(self));
5821 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005822 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005823 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005824 temp1 = new_delta(days, seconds,
5825 DATE_GET_MICROSECOND(self),
5826 1);
5827 if (temp1 == NULL) {
5828 Py_DECREF(offset);
5829 return -1;
5830 }
5831 temp2 = delta_subtract(temp1, offset);
5832 Py_DECREF(temp1);
5833 if (temp2 == NULL) {
5834 Py_DECREF(offset);
5835 return -1;
5836 }
5837 self->hashcode = PyObject_Hash(temp2);
5838 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005839 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005840 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005841 }
5842 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005843}
Tim Peters2a799bf2002-12-16 20:18:38 +00005844
5845static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005846datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005848 PyObject *clone;
5849 PyObject *tuple;
5850 int y = GET_YEAR(self);
5851 int m = GET_MONTH(self);
5852 int d = GET_DAY(self);
5853 int hh = DATE_GET_HOUR(self);
5854 int mm = DATE_GET_MINUTE(self);
5855 int ss = DATE_GET_SECOND(self);
5856 int us = DATE_GET_MICROSECOND(self);
5857 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005858 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005859
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005860 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005861 datetime_kws,
5862 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005863 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005864 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005865 if (fold != 0 && fold != 1) {
5866 PyErr_SetString(PyExc_ValueError,
5867 "fold must be either 0 or 1");
5868 return NULL;
5869 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005870 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5871 if (tuple == NULL)
5872 return NULL;
5873 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005874 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005875 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005876 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005877 Py_DECREF(tuple);
5878 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005879}
5880
5881static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005882local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005883{
5884 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005885 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005886 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005887 PyObject *nameo = NULL;
5888 const char *zone = NULL;
5889
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005890 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005891 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005892#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005893 zone = local_time_tm.tm_zone;
5894 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005895#else /* HAVE_STRUCT_TM_TM_ZONE */
5896 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005897 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005898 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005899 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005900 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005901 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005902 local_time = new_datetime(local_time_tm.tm_year + 1900,
5903 local_time_tm.tm_mon + 1,
5904 local_time_tm.tm_mday,
5905 local_time_tm.tm_hour,
5906 local_time_tm.tm_min,
5907 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005908 if (local_time == NULL) {
5909 return NULL;
5910 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005911 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005912 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005913 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5914 utc_time_tm.tm_mon + 1,
5915 utc_time_tm.tm_mday,
5916 utc_time_tm.tm_hour,
5917 utc_time_tm.tm_min,
5918 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005919 if (utc_time == NULL) {
5920 Py_DECREF(local_time);
5921 return NULL;
5922 }
5923 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005924 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005925 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005926 }
5927#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005928 if (delta == NULL) {
5929 return NULL;
5930 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005931 if (zone != NULL) {
5932 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5933 if (nameo == NULL)
5934 goto error;
5935 }
5936 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005937 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005938 error:
5939 Py_DECREF(delta);
5940 return result;
5941}
5942
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005943static PyObject *
5944local_timezone(PyDateTime_DateTime *utc_time)
5945{
5946 time_t timestamp;
5947 PyObject *delta;
5948 PyObject *one_second;
5949 PyObject *seconds;
5950
5951 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5952 if (delta == NULL)
5953 return NULL;
5954 one_second = new_delta(0, 1, 0, 0);
5955 if (one_second == NULL) {
5956 Py_DECREF(delta);
5957 return NULL;
5958 }
5959 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5960 (PyDateTime_Delta *)one_second);
5961 Py_DECREF(one_second);
5962 Py_DECREF(delta);
5963 if (seconds == NULL)
5964 return NULL;
5965 timestamp = _PyLong_AsTime_t(seconds);
5966 Py_DECREF(seconds);
5967 if (timestamp == -1 && PyErr_Occurred())
5968 return NULL;
5969 return local_timezone_from_timestamp(timestamp);
5970}
5971
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005972static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005973local_to_seconds(int year, int month, int day,
5974 int hour, int minute, int second, int fold);
5975
5976static PyObject *
5977local_timezone_from_local(PyDateTime_DateTime *local_dt)
5978{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005979 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005980 time_t timestamp;
5981 seconds = local_to_seconds(GET_YEAR(local_dt),
5982 GET_MONTH(local_dt),
5983 GET_DAY(local_dt),
5984 DATE_GET_HOUR(local_dt),
5985 DATE_GET_MINUTE(local_dt),
5986 DATE_GET_SECOND(local_dt),
5987 DATE_GET_FOLD(local_dt));
5988 if (seconds == -1)
5989 return NULL;
5990 /* XXX: add bounds check */
5991 timestamp = seconds - epoch;
5992 return local_timezone_from_timestamp(timestamp);
5993}
5994
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005995static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005996datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005997{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005998 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005999 PyObject *offset;
6000 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006001 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006002 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006003 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00006004
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006005 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07006006 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006007 return NULL;
6008
6009 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006010 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00006011
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006012 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Alexander Belopolsky877b2322018-06-10 17:02:58 -04006013 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006014 self_tzinfo = local_timezone_from_local(self);
6015 if (self_tzinfo == NULL)
6016 return NULL;
6017 } else {
6018 self_tzinfo = self->tzinfo;
6019 Py_INCREF(self_tzinfo);
6020 }
Tim Peters521fc152002-12-31 17:36:56 +00006021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006022 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006023 if (self_tzinfo == tzinfo) {
6024 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006025 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006026 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006027 }
Tim Peters521fc152002-12-31 17:36:56 +00006028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006029 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006030 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
6031 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006032 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006033 return NULL;
Alexander Belopolsky877b2322018-06-10 17:02:58 -04006034 else if(offset == Py_None) {
6035 Py_DECREF(offset);
6036 goto naive;
6037 }
6038 else if (!PyDelta_Check(offset)) {
6039 Py_DECREF(offset);
6040 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
6041 " expected timedelta or None", Py_TYPE(offset)->tp_name);
6042 return NULL;
6043 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006044 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006045 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6046 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006047 Py_DECREF(offset);
6048 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006049 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00006050
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006051 /* Make sure result is aware and UTC. */
6052 if (!HASTZINFO(result)) {
6053 temp = (PyObject *)result;
6054 result = (PyDateTime_DateTime *)
6055 new_datetime_ex2(GET_YEAR(result),
6056 GET_MONTH(result),
6057 GET_DAY(result),
6058 DATE_GET_HOUR(result),
6059 DATE_GET_MINUTE(result),
6060 DATE_GET_SECOND(result),
6061 DATE_GET_MICROSECOND(result),
6062 PyDateTime_TimeZone_UTC,
6063 DATE_GET_FOLD(result),
6064 Py_TYPE(result));
6065 Py_DECREF(temp);
6066 if (result == NULL)
6067 return NULL;
6068 }
6069 else {
6070 /* Result is already aware - just replace tzinfo. */
6071 temp = result->tzinfo;
6072 result->tzinfo = PyDateTime_TimeZone_UTC;
6073 Py_INCREF(result->tzinfo);
6074 Py_DECREF(temp);
6075 }
6076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006077 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006078 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006079 if (tzinfo == Py_None) {
6080 tzinfo = local_timezone(result);
6081 if (tzinfo == NULL) {
6082 Py_DECREF(result);
6083 return NULL;
6084 }
6085 }
6086 else
6087 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006088 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006089 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00006090
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006091 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006092 result = (PyDateTime_DateTime *)
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02006093 _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006094 Py_DECREF(temp);
6095
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006096 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00006097}
6098
6099static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306100datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006102 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00006103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006104 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006105 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00006106
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006107 dst = call_dst(self->tzinfo, (PyObject *)self);
6108 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006109 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006110
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006111 if (dst != Py_None)
6112 dstflag = delta_bool((PyDateTime_Delta *)dst);
6113 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006114 }
6115 return build_struct_time(GET_YEAR(self),
6116 GET_MONTH(self),
6117 GET_DAY(self),
6118 DATE_GET_HOUR(self),
6119 DATE_GET_MINUTE(self),
6120 DATE_GET_SECOND(self),
6121 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00006122}
6123
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006124static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006125local_to_seconds(int year, int month, int day,
6126 int hour, int minute, int second, int fold)
6127{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006128 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006129 t = utc_to_seconds(year, month, day, hour, minute, second);
6130 /* Our goal is to solve t = local(u) for u. */
6131 lt = local(t);
6132 if (lt == -1)
6133 return -1;
6134 a = lt - t;
6135 u1 = t - a;
6136 t1 = local(u1);
6137 if (t1 == -1)
6138 return -1;
6139 if (t1 == t) {
6140 /* We found one solution, but it may not be the one we need.
6141 * Look for an earlier solution (if `fold` is 0), or a
6142 * later one (if `fold` is 1). */
6143 if (fold)
6144 u2 = u1 + max_fold_seconds;
6145 else
6146 u2 = u1 - max_fold_seconds;
6147 lt = local(u2);
6148 if (lt == -1)
6149 return -1;
6150 b = lt - u2;
6151 if (a == b)
6152 return u1;
6153 }
6154 else {
6155 b = t1 - u1;
6156 assert(a != b);
6157 }
6158 u2 = t - b;
6159 t2 = local(u2);
6160 if (t2 == -1)
6161 return -1;
6162 if (t2 == t)
6163 return u2;
6164 if (t1 == t)
6165 return u1;
6166 /* We have found both offsets a and b, but neither t - a nor t - b is
6167 * a solution. This means t is in the gap. */
6168 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
6169}
6170
6171/* date(1970,1,1).toordinal() == 719163 */
6172#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
6173
Tim Peters2a799bf2002-12-16 20:18:38 +00006174static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306175datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolskya4415142012-06-08 12:33:09 -04006176{
6177 PyObject *result;
6178
6179 if (HASTZINFO(self) && self->tzinfo != Py_None) {
6180 PyObject *delta;
6181 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
6182 if (delta == NULL)
6183 return NULL;
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306184 result = delta_total_seconds(delta, NULL);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006185 Py_DECREF(delta);
6186 }
6187 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006188 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006189 seconds = local_to_seconds(GET_YEAR(self),
6190 GET_MONTH(self),
6191 GET_DAY(self),
6192 DATE_GET_HOUR(self),
6193 DATE_GET_MINUTE(self),
6194 DATE_GET_SECOND(self),
6195 DATE_GET_FOLD(self));
6196 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04006197 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006198 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
6199 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006200 }
6201 return result;
6202}
6203
6204static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306205datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006207 return new_date(GET_YEAR(self),
6208 GET_MONTH(self),
6209 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006210}
6211
6212static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306213datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006215 return new_time(DATE_GET_HOUR(self),
6216 DATE_GET_MINUTE(self),
6217 DATE_GET_SECOND(self),
6218 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006219 Py_None,
6220 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006221}
6222
6223static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306224datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006226 return new_time(DATE_GET_HOUR(self),
6227 DATE_GET_MINUTE(self),
6228 DATE_GET_SECOND(self),
6229 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006230 GET_DT_TZINFO(self),
6231 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006232}
6233
6234static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306235datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006236{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006237 int y, m, d, hh, mm, ss;
6238 PyObject *tzinfo;
6239 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006240
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006241 tzinfo = GET_DT_TZINFO(self);
6242 if (tzinfo == Py_None) {
6243 utcself = self;
6244 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006245 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006246 else {
6247 PyObject *offset;
6248 offset = call_utcoffset(tzinfo, (PyObject *)self);
6249 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006250 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006251 if (offset == Py_None) {
6252 Py_DECREF(offset);
6253 utcself = self;
6254 Py_INCREF(utcself);
6255 }
6256 else {
6257 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6258 (PyDateTime_Delta *)offset, -1);
6259 Py_DECREF(offset);
6260 if (utcself == NULL)
6261 return NULL;
6262 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006263 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006264 y = GET_YEAR(utcself);
6265 m = GET_MONTH(utcself);
6266 d = GET_DAY(utcself);
6267 hh = DATE_GET_HOUR(utcself);
6268 mm = DATE_GET_MINUTE(utcself);
6269 ss = DATE_GET_SECOND(utcself);
6270
6271 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006272 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006273}
6274
Tim Peters371935f2003-02-01 01:52:50 +00006275/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006276
Tim Petersa9bc1682003-01-11 03:39:11 +00006277/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006278 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6279 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006280 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006281 */
6282static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006283datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006285 PyObject *basestate;
6286 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006288 basestate = PyBytes_FromStringAndSize((char *)self->data,
6289 _PyDateTime_DATETIME_DATASIZE);
6290 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006291 if (proto > 3 && DATE_GET_FOLD(self))
6292 /* Set the first bit of the third byte */
6293 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006294 if (! HASTZINFO(self) || self->tzinfo == Py_None)
6295 result = PyTuple_Pack(1, basestate);
6296 else
6297 result = PyTuple_Pack(2, basestate, self->tzinfo);
6298 Py_DECREF(basestate);
6299 }
6300 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00006301}
6302
6303static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006304datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006305{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006306 int proto;
6307 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006308 return NULL;
6309
6310 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006311}
6312
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006313static PyObject *
6314datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6315{
6316 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6317}
6318
Tim Petersa9bc1682003-01-11 03:39:11 +00006319static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006321 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006322
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006323 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006325 {"utcnow", (PyCFunction)datetime_utcnow,
6326 METH_NOARGS | METH_CLASS,
6327 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006328
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006329 {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006330 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6331 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006333 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6334 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006335 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006337 {"strptime", (PyCFunction)datetime_strptime,
6338 METH_VARARGS | METH_CLASS,
6339 PyDoc_STR("string, format -> new datetime parsed from a string "
6340 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006341
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006342 {"combine", (PyCFunction)(void(*)(void))datetime_combine,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006343 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6344 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006345
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006346 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6347 METH_O | METH_CLASS,
6348 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006350 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006352 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6353 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006355 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6356 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006358 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6359 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006361 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6362 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006364 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6365 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006366
Alexander Belopolskya4415142012-06-08 12:33:09 -04006367 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6368 PyDoc_STR("Return POSIX timestamp as float.")},
6369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006370 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6371 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006372
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006373 {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006374 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006375 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006376 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006377 "defaults to 'T'.\n"
6378 "timespec specifies what components of the time to include"
6379 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6380 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006382 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6383 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006385 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6386 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006388 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6389 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006390
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006391 {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006392 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006393
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006394 {"astimezone", (PyCFunction)(void(*)(void))datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006395 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006396
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006397 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006398 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006399
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006400 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6401 PyDoc_STR("__reduce__() -> (cls, state)")},
6402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006403 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006404};
6405
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006406static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006407PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6408\n\
6409The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006410instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006411
Tim Petersa9bc1682003-01-11 03:39:11 +00006412static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006413 datetime_add, /* nb_add */
6414 datetime_subtract, /* nb_subtract */
6415 0, /* nb_multiply */
6416 0, /* nb_remainder */
6417 0, /* nb_divmod */
6418 0, /* nb_power */
6419 0, /* nb_negative */
6420 0, /* nb_positive */
6421 0, /* nb_absolute */
6422 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006423};
6424
Neal Norwitz227b5332006-03-22 09:28:35 +00006425static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006426 PyVarObject_HEAD_INIT(NULL, 0)
6427 "datetime.datetime", /* tp_name */
6428 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6429 0, /* tp_itemsize */
6430 (destructor)datetime_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006431 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006432 0, /* tp_getattr */
6433 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02006434 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006435 (reprfunc)datetime_repr, /* tp_repr */
6436 &datetime_as_number, /* tp_as_number */
6437 0, /* tp_as_sequence */
6438 0, /* tp_as_mapping */
6439 (hashfunc)datetime_hash, /* tp_hash */
6440 0, /* tp_call */
6441 (reprfunc)datetime_str, /* tp_str */
6442 PyObject_GenericGetAttr, /* tp_getattro */
6443 0, /* tp_setattro */
6444 0, /* tp_as_buffer */
6445 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6446 datetime_doc, /* tp_doc */
6447 0, /* tp_traverse */
6448 0, /* tp_clear */
6449 datetime_richcompare, /* tp_richcompare */
6450 0, /* tp_weaklistoffset */
6451 0, /* tp_iter */
6452 0, /* tp_iternext */
6453 datetime_methods, /* tp_methods */
6454 0, /* tp_members */
6455 datetime_getset, /* tp_getset */
Petr Viktorin459acc52020-05-28 18:14:46 +02006456 0, /* tp_base; filled in
6457 PyInit__datetime */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006458 0, /* tp_dict */
6459 0, /* tp_descr_get */
6460 0, /* tp_descr_set */
6461 0, /* tp_dictoffset */
6462 0, /* tp_init */
6463 datetime_alloc, /* tp_alloc */
6464 datetime_new, /* tp_new */
6465 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006466};
6467
6468/* ---------------------------------------------------------------------------
6469 * Module methods and initialization.
6470 */
6471
6472static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006473 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006474};
6475
Tim Peters9ddf40b2004-06-20 22:41:32 +00006476/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6477 * datetime.h.
6478 */
6479static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006480 &PyDateTime_DateType,
6481 &PyDateTime_DateTimeType,
6482 &PyDateTime_TimeType,
6483 &PyDateTime_DeltaType,
6484 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006485 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006486 new_date_ex,
6487 new_datetime_ex,
6488 new_time_ex,
6489 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006490 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006491 datetime_fromtimestamp,
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04006492 datetime_date_fromtimestamp_capi,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006493 new_datetime_ex2,
6494 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006495};
6496
6497
Martin v. Löwis1a214512008-06-11 05:26:20 +00006498
6499static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006500 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006501 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006502 "Fast implementation of the datetime type.",
6503 -1,
6504 module_methods,
6505 NULL,
6506 NULL,
6507 NULL,
6508 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006509};
6510
Tim Peters2a799bf2002-12-16 20:18:38 +00006511PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006512PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006514 PyObject *m; /* a module object */
6515 PyObject *d; /* its dict */
6516 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006517 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006519 m = PyModule_Create(&datetimemodule);
6520 if (m == NULL)
6521 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006522
Petr Viktorin459acc52020-05-28 18:14:46 +02006523 // `&...` is not a constant expression according to a strict reading
6524 // of C standards. Fill tp_base at run-time rather than statically.
6525 // See https://bugs.python.org/issue40777
6526 PyDateTime_IsoCalendarDateType.tp_base = &PyTuple_Type;
6527 PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType;
6528 PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType;
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006529
Dong-hee Na37fcbb62020-03-25 07:08:51 +09006530 PyTypeObject *types[] = {
6531 &PyDateTime_DateType,
6532 &PyDateTime_DateTimeType,
6533 &PyDateTime_TimeType,
6534 &PyDateTime_DeltaType,
6535 &PyDateTime_TZInfoType,
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006536 &PyDateTime_TimeZoneType,
Dong-hee Na37fcbb62020-03-25 07:08:51 +09006537 };
6538
6539 for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
6540 if (PyModule_AddType(m, types[i]) < 0) {
6541 return NULL;
6542 }
6543 }
Tim Peters2a799bf2002-12-16 20:18:38 +00006544
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006545 if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) {
6546 return NULL;
6547 }
6548 Py_INCREF(&PyDateTime_IsoCalendarDateType);
6549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006550 /* timedelta values */
6551 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006553 x = new_delta(0, 0, 1, 0);
6554 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6555 return NULL;
6556 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006558 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6559 if (x == NULL || PyDict_SetItemString(d, "min", 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, 24*3600-1, 1000000-1, 0);
6564 if (x == NULL || PyDict_SetItemString(d, "max", 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 /* date values */
6569 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006571 x = new_date(1, 1, 1);
6572 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6573 return NULL;
6574 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006576 x = new_date(MAXYEAR, 12, 31);
6577 if (x == NULL || PyDict_SetItemString(d, "max", 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_delta(1, 0, 0, 0);
6582 if (x == NULL || PyDict_SetItemString(d, "resolution", 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 /* time values */
6587 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006588
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006589 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006590 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6591 return NULL;
6592 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006593
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006594 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006595 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6596 return NULL;
6597 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006599 x = new_delta(0, 0, 1, 0);
6600 if (x == NULL || PyDict_SetItemString(d, "resolution", 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 /* datetime values */
6605 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006606
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006607 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006608 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6609 return NULL;
6610 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006611
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006612 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006613 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6614 return NULL;
6615 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006617 x = new_delta(0, 0, 1, 0);
6618 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6619 return NULL;
6620 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006621
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006622 /* timezone values */
6623 d = PyDateTime_TimeZoneType.tp_dict;
6624
6625 delta = new_delta(0, 0, 0, 0);
6626 if (delta == NULL)
6627 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006628 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006629 Py_DECREF(delta);
6630 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6631 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006632 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006633 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006634
Ngalim Siregar92c7e302019-08-09 21:22:16 +07006635 /* bpo-37642: These attributes are rounded to the nearest minute for backwards
6636 * compatibility, even though the constructor will accept a wider range of
6637 * values. This may change in the future.*/
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006638 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6639 if (delta == NULL)
6640 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006641 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006642 Py_DECREF(delta);
6643 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6644 return NULL;
6645 Py_DECREF(x);
6646
6647 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6648 if (delta == NULL)
6649 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006650 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006651 Py_DECREF(delta);
6652 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6653 return NULL;
6654 Py_DECREF(x);
6655
Alexander Belopolskya4415142012-06-08 12:33:09 -04006656 /* Epoch */
6657 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006658 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006659 if (PyDateTime_Epoch == NULL)
6660 return NULL;
6661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006662 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006663 PyModule_AddIntMacro(m, MINYEAR);
6664 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006666 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6667 if (x == NULL)
6668 return NULL;
6669 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006671 /* A 4-year cycle has an extra leap day over what we'd get from
6672 * pasting together 4 single years.
6673 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006674 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006675 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006677 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6678 * get from pasting together 4 100-year cycles.
6679 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006680 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006681 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006683 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6684 * pasting together 25 4-year cycles.
6685 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006686 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006687 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006689 us_per_ms = PyLong_FromLong(1000);
6690 us_per_second = PyLong_FromLong(1000000);
6691 us_per_minute = PyLong_FromLong(60000000);
6692 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006693 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006694 us_per_minute == NULL || seconds_per_day == NULL)
6695 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006697 /* The rest are too big for 32-bit ints, but even
6698 * us_per_week fits in 40 bits, so doubles should be exact.
6699 */
6700 us_per_hour = PyLong_FromDouble(3600000000.0);
6701 us_per_day = PyLong_FromDouble(86400000000.0);
6702 us_per_week = PyLong_FromDouble(604800000000.0);
6703 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6704 return NULL;
6705 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006706}
Tim Petersf3615152003-01-01 21:51:37 +00006707
6708/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006709Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006710 x.n = x stripped of its timezone -- its naive time.
6711 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006712 return None
Tim Petersf3615152003-01-01 21:51:37 +00006713 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006714 return None
Tim Petersf3615152003-01-01 21:51:37 +00006715 x.s = x's standard offset, x.o - x.d
6716
6717Now some derived rules, where k is a duration (timedelta).
6718
67191. x.o = x.s + x.d
6720 This follows from the definition of x.s.
6721
Tim Petersc5dc4da2003-01-02 17:55:03 +000067222. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006723 This is actually a requirement, an assumption we need to make about
6724 sane tzinfo classes.
6725
67263. The naive UTC time corresponding to x is x.n - x.o.
6727 This is again a requirement for a sane tzinfo class.
6728
67294. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006730 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006731
Tim Petersc5dc4da2003-01-02 17:55:03 +000067325. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006733 Again follows from how arithmetic is defined.
6734
Tim Peters8bb5ad22003-01-24 02:44:45 +00006735Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006736(meaning that the various tzinfo methods exist, and don't blow up or return
6737None when called).
6738
Tim Petersa9bc1682003-01-11 03:39:11 +00006739The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006740x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006741
6742By #3, we want
6743
Tim Peters8bb5ad22003-01-24 02:44:45 +00006744 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006745
6746The algorithm starts by attaching tz to x.n, and calling that y. So
6747x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6748becomes true; in effect, we want to solve [2] for k:
6749
Tim Peters8bb5ad22003-01-24 02:44:45 +00006750 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006751
6752By #1, this is the same as
6753
Tim Peters8bb5ad22003-01-24 02:44:45 +00006754 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006755
6756By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6757Substituting that into [3],
6758
Tim Peters8bb5ad22003-01-24 02:44:45 +00006759 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6760 k - (y+k).s - (y+k).d = 0; rearranging,
6761 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6762 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006763
Tim Peters8bb5ad22003-01-24 02:44:45 +00006764On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6765approximate k by ignoring the (y+k).d term at first. Note that k can't be
6766very large, since all offset-returning methods return a duration of magnitude
6767less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6768be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006769
6770In any case, the new value is
6771
Tim Peters8bb5ad22003-01-24 02:44:45 +00006772 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006773
Tim Peters8bb5ad22003-01-24 02:44:45 +00006774It's helpful to step back at look at [4] from a higher level: it's simply
6775mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006776
6777At this point, if
6778
Tim Peters8bb5ad22003-01-24 02:44:45 +00006779 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006780
6781we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006782at the start of daylight time. Picture US Eastern for concreteness. The wall
6783time 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 +00006784sense then. The docs ask that an Eastern tzinfo class consider such a time to
6785be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6786on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006787the only spelling that makes sense on the local wall clock.
6788
Tim Petersc5dc4da2003-01-02 17:55:03 +00006789In fact, if [5] holds at this point, we do have the standard-time spelling,
6790but that takes a bit of proof. We first prove a stronger result. What's the
6791difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006792
Tim Peters8bb5ad22003-01-24 02:44:45 +00006793 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006794
Tim Petersc5dc4da2003-01-02 17:55:03 +00006795Now
6796 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006797 (y + y.s).n = by #5
6798 y.n + y.s = since y.n = x.n
6799 x.n + y.s = since z and y are have the same tzinfo member,
6800 y.s = z.s by #2
6801 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006802
Tim Petersc5dc4da2003-01-02 17:55:03 +00006803Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006804
Tim Petersc5dc4da2003-01-02 17:55:03 +00006805 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006806 x.n - ((x.n + z.s) - z.o) = expanding
6807 x.n - x.n - z.s + z.o = cancelling
6808 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006809 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006810
Tim Petersc5dc4da2003-01-02 17:55:03 +00006811So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006812
Tim Petersc5dc4da2003-01-02 17:55:03 +00006813If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006814spelling we wanted in the endcase described above. We're done. Contrarily,
6815if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006816
Tim Petersc5dc4da2003-01-02 17:55:03 +00006817If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6818add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006819local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006820
Tim Petersc5dc4da2003-01-02 17:55:03 +00006821Let
Tim Petersf3615152003-01-01 21:51:37 +00006822
Tim Peters4fede1a2003-01-04 00:26:59 +00006823 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006824
Tim Peters4fede1a2003-01-04 00:26:59 +00006825and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006826
Tim Peters8bb5ad22003-01-24 02:44:45 +00006827 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006828
Tim Peters8bb5ad22003-01-24 02:44:45 +00006829If so, we're done. If not, the tzinfo class is insane, according to the
6830assumptions we've made. This also requires a bit of proof. As before, let's
6831compute the difference between the LHS and RHS of [8] (and skipping some of
6832the justifications for the kinds of substitutions we've done several times
6833already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006834
Tim Peters8bb5ad22003-01-24 02:44:45 +00006835 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006836 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6837 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6838 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6839 - z.n + z.n - z.o + z'.o = cancel z.n
6840 - z.o + z'.o = #1 twice
6841 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6842 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006843
6844So 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 +00006845we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6846return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006847
Tim Peters8bb5ad22003-01-24 02:44:45 +00006848How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6849a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6850would have to change the result dst() returns: we start in DST, and moving
6851a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006852
Tim Peters8bb5ad22003-01-24 02:44:45 +00006853There isn't a sane case where this can happen. The closest it gets is at
6854the end of DST, where there's an hour in UTC with no spelling in a hybrid
6855tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6856that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6857UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6858time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6859clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6860standard time. Since that's what the local clock *does*, we want to map both
6861UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006862in local time, but so it goes -- it's the way the local clock works.
6863
Tim Peters8bb5ad22003-01-24 02:44:45 +00006864When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6865so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6866z' = 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 +00006867(correctly) concludes that z' is not UTC-equivalent to x.
6868
6869Because we know z.d said z was in daylight time (else [5] would have held and
6870we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006871and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006872return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6873but the reasoning doesn't depend on the example -- it depends on there being
6874two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006875z' must be in standard time, and is the spelling we want in this case.
6876
6877Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6878concerned (because it takes z' as being in standard time rather than the
6879daylight time we intend here), but returning it gives the real-life "local
6880clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6881tz.
6882
6883When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6884the 1:MM standard time spelling we want.
6885
6886So how can this break? One of the assumptions must be violated. Two
6887possibilities:
6888
68891) [2] effectively says that y.s is invariant across all y belong to a given
6890 time zone. This isn't true if, for political reasons or continental drift,
6891 a region decides to change its base offset from UTC.
6892
68932) There may be versions of "double daylight" time where the tail end of
6894 the analysis gives up a step too early. I haven't thought about that
6895 enough to say.
6896
6897In any case, it's clear that the default fromutc() is strong enough to handle
6898"almost all" time zones: so long as the standard offset is invariant, it
6899doesn't matter if daylight time transition points change from year to year, or
6900if daylight time is skipped in some years; it doesn't matter how large or
6901small dst() may get within its bounds; and it doesn't even matter if some
6902perverse time zone returns a negative dst()). So a breaking case must be
6903pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006904--------------------------------------------------------------------------- */