blob: c3e0b52baa6facd892a1ed2540860d2f68068da4 [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 Stinner37834132020-10-27 17:12:53 +010011#include "pycore_long.h" // _PyLong_GetOne()
Victor Stinner04fc4f22020-06-16 01:28:07 +020012#include "pycore_object.h" // _PyObject_Init()
Paul Ganssle0d126722018-11-13 03:02:25 -050013#include "datetime.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020014#include "structmember.h" // PyMemberDef
Tim Peters2a799bf2002-12-16 20:18:38 +000015
16#include <time.h>
17
Victor Stinner09e5cf22015-03-30 00:09:18 +020018#ifdef MS_WINDOWS
19# include <winsock2.h> /* struct timeval */
20#endif
21
Paul Ganssle0d126722018-11-13 03:02:25 -050022#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090023#define PyDate_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateType)
Paul Ganssle0d126722018-11-13 03:02:25 -050024
25#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090026#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateTimeType)
Paul Ganssle0d126722018-11-13 03:02:25 -050027
28#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090029#define PyTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TimeType)
Paul Ganssle0d126722018-11-13 03:02:25 -050030
31#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090032#define PyDelta_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DeltaType)
Paul Ganssle0d126722018-11-13 03:02:25 -050033
34#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090035#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_TZInfoType)
Paul Ganssle0d126722018-11-13 03:02:25 -050036
Pablo Galindo4be11c02019-08-22 20:24:25 +010037#define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType)
Tim Peters2a799bf2002-12-16 20:18:38 +000038
Larry Hastings61272b72014-01-07 12:41:53 -080039/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080040module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080041class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +020042class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType"
Paul Ganssle1b97b9b2020-05-16 10:02:59 -040043class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCalendarDateType"
Larry Hastings61272b72014-01-07 12:41:53 -080044[clinic start generated code]*/
Paul Ganssle1b97b9b2020-05-16 10:02:59 -040045/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81bec0fa19837f63]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080046
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030047#include "clinic/_datetimemodule.c.h"
48
Tim Peters2a799bf2002-12-16 20:18:38 +000049/* We require that C int be at least 32 bits, and use int virtually
50 * everywhere. In just a few cases we use a temp long, where a Python
51 * API returns a C long. In such cases, we have to ensure that the
52 * final result fits in a C int (this can be an issue on 64-bit boxes).
53 */
54#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000055# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000056#endif
57
58#define MINYEAR 1
59#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000060#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000061
62/* Nine decimal digits is easy to communicate, and leaves enough room
63 * so that two delta days can be added w/o fear of overflowing a signed
64 * 32-bit int, and with plenty of room left over to absorb any possible
65 * carries from adding seconds.
66 */
67#define MAX_DELTA_DAYS 999999999
68
69/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070#define GET_YEAR PyDateTime_GET_YEAR
71#define GET_MONTH PyDateTime_GET_MONTH
72#define GET_DAY PyDateTime_GET_DAY
73#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
74#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
75#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
76#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040077#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000078
79/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
81 ((o)->data[1] = ((v) & 0x00ff)))
82#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
83#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000084
85/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000086#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
87#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
88#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
89#define DATE_SET_MICROSECOND(o, v) \
90 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
91 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
92 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040093#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000094
95/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
97#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
98#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
99#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400100#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
102#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
103#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
104#define TIME_SET_MICROSECOND(o, v) \
105 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
106 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
107 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400108#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000109
110/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
112#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
113#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115#define SET_TD_DAYS(o, v) ((o)->days = (v))
116#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000117#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
118
Zackery Spytz2e4dd332020-09-23 12:43:45 -0600119#define HASTZINFO _PyDateTime_HAS_TZINFO
120#define GET_TIME_TZINFO PyDateTime_TIME_GET_TZINFO
121#define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO
Tim Peters3f606292004-03-21 23:38:41 +0000122/* M is a char or int claiming to be a valid month. The macro is equivalent
123 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000125 */
126#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
127
Tim Peters2a799bf2002-12-16 20:18:38 +0000128/* Forward declarations. */
129static PyTypeObject PyDateTime_DateType;
130static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000131static PyTypeObject PyDateTime_DeltaType;
Paul Ganssle1b97b9b2020-05-16 10:02:59 -0400132static PyTypeObject PyDateTime_IsoCalendarDateType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000133static PyTypeObject PyDateTime_TimeType;
134static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000135static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000136
Victor Stinnerb67f0962017-02-10 10:34:02 +0100137static int check_tzinfo_subclass(PyObject *p);
138
Martin v. Löwise75fc142013-11-07 18:46:53 +0100139_Py_IDENTIFIER(as_integer_ratio);
140_Py_IDENTIFIER(fromutc);
141_Py_IDENTIFIER(isoformat);
142_Py_IDENTIFIER(strftime);
143
Tim Peters2a799bf2002-12-16 20:18:38 +0000144/* ---------------------------------------------------------------------------
145 * Math utilities.
146 */
147
148/* k = i+j overflows iff k differs in sign from both inputs,
149 * iff k^i has sign bit set and k^j has sign bit set,
150 * iff (k^i)&(k^j) has sign bit set.
151 */
152#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000154
155/* Compute Python divmod(x, y), returning the quotient and storing the
156 * remainder into *r. The quotient is the floor of x/y, and that's
157 * the real point of this. C will probably truncate instead (C99
158 * requires truncation; C89 left it implementation-defined).
159 * Simplification: we *require* that y > 0 here. That's appropriate
160 * for all the uses made of it. This simplifies the code and makes
161 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
162 * overflow case).
163 */
164static int
165divmod(int x, int y, int *r)
166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 assert(y > 0);
170 quo = x / y;
171 *r = x - quo * y;
172 if (*r < 0) {
173 --quo;
174 *r += y;
175 }
176 assert(0 <= *r && *r < y);
177 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000178}
179
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000180/* Nearest integer to m / n for integers m and n. Half-integer results
181 * are rounded to even.
182 */
183static PyObject *
184divide_nearest(PyObject *m, PyObject *n)
185{
186 PyObject *result;
187 PyObject *temp;
188
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000189 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000190 if (temp == NULL)
191 return NULL;
192 result = PyTuple_GET_ITEM(temp, 0);
193 Py_INCREF(result);
194 Py_DECREF(temp);
195
196 return result;
197}
198
Tim Peters2a799bf2002-12-16 20:18:38 +0000199/* ---------------------------------------------------------------------------
200 * General calendrical helper functions
201 */
202
203/* For each month ordinal in 1..12, the number of days in that month,
204 * and the number of days before that month in the same year. These
205 * are correct for non-leap years only.
206 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200207static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 0, /* unused; this vector uses 1-based indexing */
209 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000210};
211
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200212static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 0, /* unused; this vector uses 1-based indexing */
214 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000215};
216
217/* year -> 1 if leap year, else 0. */
218static int
219is_leap(int year)
220{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 /* Cast year to unsigned. The result is the same either way, but
222 * C can generate faster code for unsigned mod than for signed
223 * mod (especially for % 4 -- a good compiler should just grab
224 * the last 2 bits when the LHS is unsigned).
225 */
226 const unsigned int ayear = (unsigned int)year;
227 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000228}
229
230/* year, month -> number of days in that month in that year */
231static int
232days_in_month(int year, int month)
233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 assert(month >= 1);
235 assert(month <= 12);
236 if (month == 2 && is_leap(year))
237 return 29;
238 else
239 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000240}
241
Martin Panter46f50722016-05-26 05:35:26 +0000242/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000243static int
244days_before_month(int year, int month)
245{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 assert(month >= 1);
249 assert(month <= 12);
250 days = _days_before_month[month];
251 if (month > 2 && is_leap(year))
252 ++days;
253 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000254}
255
256/* year -> number of days before January 1st of year. Remember that we
257 * start with year 1, so days_before_year(1) == 0.
258 */
259static int
260days_before_year(int year)
261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 int y = year - 1;
263 /* This is incorrect if year <= 0; we really want the floor
264 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000265 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000267 assert (year >= 1);
268 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000269}
270
271/* Number of days in 4, 100, and 400 year cycles. That these have
272 * the correct values is asserted in the module init function.
273 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274#define DI4Y 1461 /* days_before_year(5); days in 4 years */
275#define DI100Y 36524 /* days_before_year(101); days in 100 years */
276#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000277
278/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
279static void
280ord_to_ymd(int ordinal, int *year, int *month, int *day)
281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
285 * leap years repeats exactly every 400 years. The basic strategy is
286 * to find the closest 400-year boundary at or before ordinal, then
287 * work with the offset from that boundary to ordinal. Life is much
288 * clearer if we subtract 1 from ordinal first -- then the values
289 * of ordinal at 400-year boundaries are exactly those divisible
290 * by DI400Y:
291 *
292 * D M Y n n-1
293 * -- --- ---- ---------- ----------------
294 * 31 Dec -400 -DI400Y -DI400Y -1
295 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
296 * ...
297 * 30 Dec 000 -1 -2
298 * 31 Dec 000 0 -1
299 * 1 Jan 001 1 0 400-year boundary
300 * 2 Jan 001 2 1
301 * 3 Jan 001 3 2
302 * ...
303 * 31 Dec 400 DI400Y DI400Y -1
304 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
305 */
306 assert(ordinal >= 1);
307 --ordinal;
308 n400 = ordinal / DI400Y;
309 n = ordinal % DI400Y;
310 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 /* Now n is the (non-negative) offset, in days, from January 1 of
313 * year, to the desired date. Now compute how many 100-year cycles
314 * precede n.
315 * Note that it's possible for n100 to equal 4! In that case 4 full
316 * 100-year cycles precede the desired day, which implies the
317 * desired day is December 31 at the end of a 400-year cycle.
318 */
319 n100 = n / DI100Y;
320 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 /* Now compute how many 4-year cycles precede it. */
323 n4 = n / DI4Y;
324 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 /* And now how many single years. Again n1 can be 4, and again
327 * meaning that the desired day is December 31 at the end of the
328 * 4-year cycle.
329 */
330 n1 = n / 365;
331 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 *year += n100 * 100 + n4 * 4 + n1;
334 if (n1 == 4 || n100 == 4) {
335 assert(n == 0);
336 *year -= 1;
337 *month = 12;
338 *day = 31;
339 return;
340 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 /* Now the year is correct, and n is the offset from January 1. We
343 * find the month via an estimate that's either exact or one too
344 * large.
345 */
346 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
347 assert(leapyear == is_leap(*year));
348 *month = (n + 50) >> 5;
349 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
350 if (preceding > n) {
351 /* estimate is too large */
352 *month -= 1;
353 preceding -= days_in_month(*year, *month);
354 }
355 n -= preceding;
356 assert(0 <= n);
357 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000360}
361
362/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
363static int
364ymd_to_ord(int year, int month, int day)
365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000367}
368
369/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
370static int
371weekday(int year, int month, int day)
372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000374}
375
376/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
377 * first calendar week containing a Thursday.
378 */
379static int
380iso_week1_monday(int year)
381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
383 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
384 int first_weekday = (first_day + 6) % 7;
385 /* ordinal of closest Monday at or before 1/1 */
386 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
389 week1_monday += 7;
390 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000391}
392
393/* ---------------------------------------------------------------------------
394 * Range checkers.
395 */
396
397/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
398 * If not, raise OverflowError and return -1.
399 */
400static int
401check_delta_day_range(int days)
402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
404 return 0;
405 PyErr_Format(PyExc_OverflowError,
406 "days=%d; must have magnitude <= %d",
407 days, MAX_DELTA_DAYS);
408 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000409}
410
411/* Check that date arguments are in range. Return 0 if they are. If they
412 * aren't, raise ValueError and return -1.
413 */
414static int
415check_date_args(int year, int month, int day)
416{
417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 if (year < MINYEAR || year > MAXYEAR) {
Victor Stinnerb67f0962017-02-10 10:34:02 +0100419 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 return -1;
421 }
422 if (month < 1 || month > 12) {
423 PyErr_SetString(PyExc_ValueError,
424 "month must be in 1..12");
425 return -1;
426 }
427 if (day < 1 || day > days_in_month(year, month)) {
428 PyErr_SetString(PyExc_ValueError,
429 "day is out of range for month");
430 return -1;
431 }
432 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000433}
434
435/* Check that time arguments are in range. Return 0 if they are. If they
436 * aren't, raise ValueError and return -1.
437 */
438static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400439check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000440{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 if (h < 0 || h > 23) {
442 PyErr_SetString(PyExc_ValueError,
443 "hour must be in 0..23");
444 return -1;
445 }
446 if (m < 0 || m > 59) {
447 PyErr_SetString(PyExc_ValueError,
448 "minute must be in 0..59");
449 return -1;
450 }
451 if (s < 0 || s > 59) {
452 PyErr_SetString(PyExc_ValueError,
453 "second must be in 0..59");
454 return -1;
455 }
456 if (us < 0 || us > 999999) {
457 PyErr_SetString(PyExc_ValueError,
458 "microsecond must be in 0..999999");
459 return -1;
460 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400461 if (fold != 0 && fold != 1) {
462 PyErr_SetString(PyExc_ValueError,
463 "fold must be either 0 or 1");
464 return -1;
465 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000467}
468
469/* ---------------------------------------------------------------------------
470 * Normalization utilities.
471 */
472
473/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
474 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
475 * at least factor, enough of *lo is converted into "hi" units so that
476 * 0 <= *lo < factor. The input values must be such that int overflow
477 * is impossible.
478 */
479static void
480normalize_pair(int *hi, int *lo, int factor)
481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 assert(factor > 0);
483 assert(lo != hi);
484 if (*lo < 0 || *lo >= factor) {
485 const int num_hi = divmod(*lo, factor, lo);
486 const int new_hi = *hi + num_hi;
487 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
488 *hi = new_hi;
489 }
490 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000491}
492
493/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 * 0 <= *s < 24*3600
495 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000496 * The input values must be such that the internals don't overflow.
497 * The way this routine is used, we don't get close.
498 */
499static void
500normalize_d_s_us(int *d, int *s, int *us)
501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 if (*us < 0 || *us >= 1000000) {
503 normalize_pair(s, us, 1000000);
504 /* |s| can't be bigger than about
505 * |original s| + |original us|/1000000 now.
506 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
509 if (*s < 0 || *s >= 24*3600) {
510 normalize_pair(d, s, 24*3600);
511 /* |d| can't be bigger than about
512 * |original d| +
513 * (|original s| + |original us|/1000000) / (24*3600) now.
514 */
515 }
516 assert(0 <= *s && *s < 24*3600);
517 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000518}
519
520/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 * 1 <= *m <= 12
522 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000523 * The input values must be such that the internals don't overflow.
524 * The way this routine is used, we don't get close.
525 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000526static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000527normalize_y_m_d(int *y, int *m, int *d)
528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000530
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000531 /* In actual use, m is always the month component extracted from a
532 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 /* Now only day can be out of bounds (year may also be out of bounds
538 * for a datetime object, but we don't care about that here).
539 * If day is out of bounds, what to do is arguable, but at least the
540 * method here is principled and explainable.
541 */
542 dim = days_in_month(*y, *m);
543 if (*d < 1 || *d > dim) {
544 /* Move day-1 days from the first of the month. First try to
545 * get off cheap if we're only one day out of range
546 * (adjustments for timezone alone can't be worse than that).
547 */
548 if (*d == 0) {
549 --*m;
550 if (*m > 0)
551 *d = days_in_month(*y, *m);
552 else {
553 --*y;
554 *m = 12;
555 *d = 31;
556 }
557 }
558 else if (*d == dim + 1) {
559 /* move forward a day */
560 ++*m;
561 *d = 1;
562 if (*m > 12) {
563 *m = 1;
564 ++*y;
565 }
566 }
567 else {
568 int ordinal = ymd_to_ord(*y, *m, 1) +
569 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000570 if (ordinal < 1 || ordinal > MAXORDINAL) {
571 goto error;
572 } else {
573 ord_to_ymd(ordinal, y, m, d);
574 return 0;
575 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 }
577 }
578 assert(*m > 0);
579 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000580 if (MINYEAR <= *y && *y <= MAXYEAR)
581 return 0;
582 error:
583 PyErr_SetString(PyExc_OverflowError,
584 "date value out of range");
585 return -1;
586
Tim Peters2a799bf2002-12-16 20:18:38 +0000587}
588
589/* Fiddle out-of-bounds months and days so that the result makes some kind
590 * of sense. The parameters are both inputs and outputs. Returns < 0 on
591 * failure, where failure means the adjusted year is out of bounds.
592 */
593static int
594normalize_date(int *year, int *month, int *day)
595{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000596 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000597}
598
599/* Force all the datetime fields into range. The parameters are both
600 * inputs and outputs. Returns < 0 on error.
601 */
602static int
603normalize_datetime(int *year, int *month, int *day,
604 int *hour, int *minute, int *second,
605 int *microsecond)
606{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 normalize_pair(second, microsecond, 1000000);
608 normalize_pair(minute, second, 60);
609 normalize_pair(hour, minute, 60);
610 normalize_pair(day, hour, 24);
611 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000612}
613
614/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000615 * Basic object allocation: tp_alloc implementations. These allocate
616 * Python objects of the right size and type, and do the Python object-
617 * initialization bit. If there's not enough memory, they return NULL after
618 * setting MemoryError. All data members remain uninitialized trash.
619 *
620 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000621 * member is needed. This is ugly, imprecise, and possibly insecure.
622 * tp_basicsize for the time and datetime types is set to the size of the
623 * struct that has room for the tzinfo member, so subclasses in Python will
624 * allocate enough space for a tzinfo member whether or not one is actually
625 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
626 * part is that PyType_GenericAlloc() (which subclasses in Python end up
627 * using) just happens today to effectively ignore the nitems argument
628 * when tp_itemsize is 0, which it is for these type objects. If that
629 * changes, perhaps the callers of tp_alloc slots in this file should
630 * be changed to force a 0 nitems argument unless the type being allocated
631 * is a base type implemented in this file (so that tp_alloc is time_alloc
632 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000633 */
634
635static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000636time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000637{
Victor Stinner04fc4f22020-06-16 01:28:07 +0200638 size_t size = aware ? sizeof(PyDateTime_Time) : sizeof(_PyDateTime_BaseTime);
639 PyObject *self = (PyObject *)PyObject_Malloc(size);
640 if (self == NULL) {
641 return PyErr_NoMemory();
642 }
643 _PyObject_Init(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000645}
646
647static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000648datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000649{
Victor Stinner04fc4f22020-06-16 01:28:07 +0200650 size_t size = aware ? sizeof(PyDateTime_DateTime) : sizeof(_PyDateTime_BaseDateTime);
651 PyObject *self = (PyObject *)PyObject_Malloc(size);
652 if (self == NULL) {
653 return PyErr_NoMemory();
654 }
655 _PyObject_Init(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000657}
658
659/* ---------------------------------------------------------------------------
660 * Helpers for setting object fields. These work on pointers to the
661 * appropriate base class.
662 */
663
664/* For date and datetime. */
665static void
666set_date_fields(PyDateTime_Date *self, int y, int m, int d)
667{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 self->hashcode = -1;
669 SET_YEAR(self, y);
670 SET_MONTH(self, m);
671 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000672}
673
674/* ---------------------------------------------------------------------------
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500675 * String parsing utilities and helper functions
676 */
677
Paul Ganssle3df85402018-10-22 12:32:52 -0400678static const char *
679parse_digits(const char *ptr, int *var, size_t num_digits)
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500680{
681 for (size_t i = 0; i < num_digits; ++i) {
682 unsigned int tmp = (unsigned int)(*(ptr++) - '0');
683 if (tmp > 9) {
684 return NULL;
685 }
686 *var *= 10;
687 *var += (signed int)tmp;
688 }
689
690 return ptr;
691}
692
Paul Ganssle3df85402018-10-22 12:32:52 -0400693static int
694parse_isoformat_date(const char *dtstr, int *year, int *month, int *day)
695{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500696 /* Parse the date components of the result of date.isoformat()
Paul Ganssle3df85402018-10-22 12:32:52 -0400697 *
698 * Return codes:
699 * 0: Success
700 * -1: Failed to parse date component
701 * -2: Failed to parse dateseparator
702 */
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500703 const char *p = dtstr;
704 p = parse_digits(p, year, 4);
705 if (NULL == p) {
706 return -1;
707 }
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100708
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500709 if (*(p++) != '-') {
710 return -2;
711 }
712
713 p = parse_digits(p, month, 2);
714 if (NULL == p) {
715 return -1;
716 }
717
718 if (*(p++) != '-') {
719 return -2;
720 }
721
722 p = parse_digits(p, day, 2);
723 if (p == NULL) {
724 return -1;
725 }
726
727 return 0;
728}
729
730static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400731parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
732 int *minute, int *second, int *microsecond)
733{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500734 const char *p = tstr;
735 const char *p_end = tstr_end;
736 int *vals[3] = {hour, minute, second};
737
738 // Parse [HH[:MM[:SS]]]
739 for (size_t i = 0; i < 3; ++i) {
740 p = parse_digits(p, vals[i], 2);
741 if (NULL == p) {
742 return -3;
743 }
744
745 char c = *(p++);
746 if (p >= p_end) {
747 return c != '\0';
Paul Ganssle3df85402018-10-22 12:32:52 -0400748 }
749 else if (c == ':') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500750 continue;
Paul Ganssle3df85402018-10-22 12:32:52 -0400751 }
752 else if (c == '.') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500753 break;
Paul Ganssle3df85402018-10-22 12:32:52 -0400754 }
755 else {
756 return -4; // Malformed time separator
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500757 }
758 }
759
760 // Parse .fff[fff]
761 size_t len_remains = p_end - p;
762 if (!(len_remains == 6 || len_remains == 3)) {
763 return -3;
764 }
765
766 p = parse_digits(p, microsecond, len_remains);
767 if (NULL == p) {
768 return -3;
769 }
770
771 if (len_remains == 3) {
772 *microsecond *= 1000;
773 }
774
775 // Return 1 if it's not the end of the string
776 return *p != '\0';
777}
778
779static int
Paul Ganssle3df85402018-10-22 12:32:52 -0400780parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
781 int *second, int *microsecond, int *tzoffset,
782 int *tzmicrosecond)
783{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500784 // Parse the time portion of a datetime.isoformat() string
785 //
786 // Return codes:
787 // 0: Success (no tzoffset)
788 // 1: Success (with tzoffset)
789 // -3: Failed to parse time component
790 // -4: Failed to parse time separator
791 // -5: Malformed timezone string
792
793 const char *p = dtstr;
794 const char *p_end = dtstr + dtlen;
795
796 const char *tzinfo_pos = p;
797 do {
798 if (*tzinfo_pos == '+' || *tzinfo_pos == '-') {
799 break;
800 }
Paul Ganssle3df85402018-10-22 12:32:52 -0400801 } while (++tzinfo_pos < p_end);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500802
Paul Ganssle3df85402018-10-22 12:32:52 -0400803 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second,
804 microsecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500805
806 if (rv < 0) {
807 return rv;
Paul Ganssle3df85402018-10-22 12:32:52 -0400808 }
809 else if (tzinfo_pos == p_end) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500810 // We know that there's no time zone, so if there's stuff at the
811 // end of the string it's an error.
812 if (rv == 1) {
813 return -5;
Paul Ganssle3df85402018-10-22 12:32:52 -0400814 }
815 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500816 return 0;
817 }
818 }
819
820 // Parse time zone component
821 // Valid formats are:
822 // - +HH:MM (len 6)
823 // - +HH:MM:SS (len 9)
824 // - +HH:MM:SS.ffffff (len 16)
825 size_t tzlen = p_end - tzinfo_pos;
826 if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) {
827 return -5;
828 }
829
Paul Ganssle3df85402018-10-22 12:32:52 -0400830 int tzsign = (*tzinfo_pos == '-') ? -1 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500831 tzinfo_pos++;
832 int tzhour = 0, tzminute = 0, tzsecond = 0;
Paul Ganssle3df85402018-10-22 12:32:52 -0400833 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond,
834 tzmicrosecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500835
836 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
837 *tzmicrosecond *= tzsign;
838
Paul Ganssle3df85402018-10-22 12:32:52 -0400839 return rv ? -5 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500840}
841
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500842/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000843 * Create various objects, mostly without range checking.
844 */
845
846/* Create a date instance with no range checking. */
847static PyObject *
848new_date_ex(int year, int month, int day, PyTypeObject *type)
849{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000851
Victor Stinnerb67f0962017-02-10 10:34:02 +0100852 if (check_date_args(year, month, day) < 0) {
853 return NULL;
854 }
855
Paul Ganssle3df85402018-10-22 12:32:52 -0400856 self = (PyDateTime_Date *)(type->tp_alloc(type, 0));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 if (self != NULL)
858 set_date_fields(self, year, month, day);
Paul Ganssle3df85402018-10-22 12:32:52 -0400859 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000860}
861
862#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000864
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500865// Forward declaration
Paul Ganssle3df85402018-10-22 12:32:52 -0400866static PyObject *
867new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500868
869/* Create date instance with no range checking, or call subclass constructor */
870static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -0400871new_date_subclass_ex(int year, int month, int day, PyObject *cls)
872{
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500873 PyObject *result;
874 // We have "fast path" constructors for two subclasses: date and datetime
875 if ((PyTypeObject *)cls == &PyDateTime_DateType) {
876 result = new_date_ex(year, month, day, (PyTypeObject *)cls);
Paul Ganssle3df85402018-10-22 12:32:52 -0400877 }
878 else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500879 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
880 (PyTypeObject *)cls);
Paul Ganssle3df85402018-10-22 12:32:52 -0400881 }
882 else {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500883 result = PyObject_CallFunction(cls, "iii", year, month, day);
884 }
885
886 return result;
887}
888
Tim Petersb0c854d2003-05-17 15:57:00 +0000889/* Create a datetime instance with no range checking. */
890static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400891new_datetime_ex2(int year, int month, int day, int hour, int minute,
892 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000893{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 PyDateTime_DateTime *self;
895 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000896
Victor Stinnerb67f0962017-02-10 10:34:02 +0100897 if (check_date_args(year, month, day) < 0) {
898 return NULL;
899 }
900 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
901 return NULL;
902 }
903 if (check_tzinfo_subclass(tzinfo) < 0) {
904 return NULL;
905 }
906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
908 if (self != NULL) {
909 self->hastzinfo = aware;
910 set_date_fields((PyDateTime_Date *)self, year, month, day);
911 DATE_SET_HOUR(self, hour);
912 DATE_SET_MINUTE(self, minute);
913 DATE_SET_SECOND(self, second);
914 DATE_SET_MICROSECOND(self, usecond);
915 if (aware) {
916 Py_INCREF(tzinfo);
917 self->tzinfo = tzinfo;
918 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400919 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 }
921 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000922}
923
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400924static PyObject *
925new_datetime_ex(int year, int month, int day, int hour, int minute,
926 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
927{
928 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
929 tzinfo, 0, type);
930}
931
932#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
933 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000935
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500936static PyObject *
937new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
938 int second, int usecond, PyObject *tzinfo,
939 int fold, PyObject *cls) {
940 PyObject* dt;
941 if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) {
942 // Use the fast path constructor
943 dt = new_datetime(year, month, day, hour, minute, second, usecond,
944 tzinfo, fold);
945 } else {
946 // Subclass
947 dt = PyObject_CallFunction(cls, "iiiiiiiO",
948 year,
949 month,
950 day,
951 hour,
952 minute,
953 second,
954 usecond,
955 tzinfo);
956 }
957
958 return dt;
959}
960
961static PyObject *
962new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
963 int second, int usecond, PyObject *tzinfo,
964 PyObject *cls) {
965 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
966 second, usecond, tzinfo, 0,
967 cls);
968}
969
Tim Petersb0c854d2003-05-17 15:57:00 +0000970/* Create a time instance with no range checking. */
971static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400972new_time_ex2(int hour, int minute, int second, int usecond,
973 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000974{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 PyDateTime_Time *self;
976 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000977
Victor Stinnerb67f0962017-02-10 10:34:02 +0100978 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
979 return NULL;
980 }
981 if (check_tzinfo_subclass(tzinfo) < 0) {
982 return NULL;
983 }
984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
986 if (self != NULL) {
987 self->hastzinfo = aware;
988 self->hashcode = -1;
989 TIME_SET_HOUR(self, hour);
990 TIME_SET_MINUTE(self, minute);
991 TIME_SET_SECOND(self, second);
992 TIME_SET_MICROSECOND(self, usecond);
993 if (aware) {
994 Py_INCREF(tzinfo);
995 self->tzinfo = tzinfo;
996 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400997 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 }
999 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001000}
1001
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001002static PyObject *
1003new_time_ex(int hour, int minute, int second, int usecond,
1004 PyObject *tzinfo, PyTypeObject *type)
1005{
1006 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
1007}
1008
1009#define new_time(hh, mm, ss, us, tzinfo, fold) \
1010 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001011
1012/* Create a timedelta instance. Normalize the members iff normalize is
1013 * true. Passing false is a speed optimization, if you know for sure
1014 * that seconds and microseconds are already in their proper ranges. In any
1015 * case, raises OverflowError and returns NULL if the normalized days is out
1016 * of range).
1017 */
1018static PyObject *
1019new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +00001021{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 if (normalize)
1025 normalize_d_s_us(&days, &seconds, &microseconds);
1026 assert(0 <= seconds && seconds < 24*3600);
1027 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +00001028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 if (check_delta_day_range(days) < 0)
1030 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +00001031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1033 if (self != NULL) {
1034 self->hashcode = -1;
1035 SET_TD_DAYS(self, days);
1036 SET_TD_SECONDS(self, seconds);
1037 SET_TD_MICROSECONDS(self, microseconds);
1038 }
1039 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001040}
1041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042#define new_delta(d, s, us, normalize) \
1043 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001044
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001045
1046typedef struct
1047{
1048 PyObject_HEAD
1049 PyObject *offset;
1050 PyObject *name;
1051} PyDateTime_TimeZone;
1052
Victor Stinner6ced7c42011-03-21 18:15:42 +01001053/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001054static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -04001055/* The interned Epoch datetime instance */
1056static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00001057
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001058/* Create new timezone instance checking offset range. This
1059 function does not check the name argument. Caller must assure
1060 that offset is a timedelta instance and name is either NULL
1061 or a unicode object. */
1062static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001063create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001064{
1065 PyDateTime_TimeZone *self;
1066 PyTypeObject *type = &PyDateTime_TimeZoneType;
1067
1068 assert(offset != NULL);
1069 assert(PyDelta_Check(offset));
1070 assert(name == NULL || PyUnicode_Check(name));
1071
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001072 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1073 if (self == NULL) {
1074 return NULL;
1075 }
1076 Py_INCREF(offset);
1077 self->offset = offset;
1078 Py_XINCREF(name);
1079 self->name = name;
1080 return (PyObject *)self;
1081}
1082
1083static int delta_bool(PyDateTime_Delta *self);
1084
1085static PyObject *
1086new_timezone(PyObject *offset, PyObject *name)
1087{
1088 assert(offset != NULL);
1089 assert(PyDelta_Check(offset));
1090 assert(name == NULL || PyUnicode_Check(name));
1091
1092 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
1093 Py_INCREF(PyDateTime_TimeZone_UTC);
1094 return PyDateTime_TimeZone_UTC;
1095 }
Ngalim Siregar92c7e302019-08-09 21:22:16 +07001096 if ((GET_TD_DAYS(offset) == -1 &&
1097 GET_TD_SECONDS(offset) == 0 &&
1098 GET_TD_MICROSECONDS(offset) < 1) ||
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001099 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1100 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1101 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04001102 " timedelta(hours=24),"
1103 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001104 return NULL;
1105 }
1106
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001107 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001108}
1109
Tim Petersb0c854d2003-05-17 15:57:00 +00001110/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001111 * tzinfo helpers.
1112 */
1113
Tim Peters855fe882002-12-22 03:43:39 +00001114/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
1115 * raise TypeError and return -1.
1116 */
1117static int
1118check_tzinfo_subclass(PyObject *p)
1119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 if (p == Py_None || PyTZInfo_Check(p))
1121 return 0;
1122 PyErr_Format(PyExc_TypeError,
1123 "tzinfo argument must be None or of a tzinfo subclass, "
1124 "not type '%s'",
1125 Py_TYPE(p)->tp_name);
1126 return -1;
Tim Peters855fe882002-12-22 03:43:39 +00001127}
1128
Tim Peters2a799bf2002-12-16 20:18:38 +00001129/* If self has a tzinfo member, return a BORROWED reference to it. Else
1130 * return NULL, which is NOT AN ERROR. There are no error returns here,
1131 * and the caller must not decref the result.
1132 */
1133static PyObject *
1134get_tzinfo_member(PyObject *self)
1135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 if (PyDateTime_Check(self) && HASTZINFO(self))
1139 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1140 else if (PyTime_Check(self) && HASTZINFO(self))
1141 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001144}
1145
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001146/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
1147 * be an instance of the tzinfo class. If the method returns None, this
1148 * returns None. If the method doesn't return None or timedelta, TypeError is
1149 * raised and this returns NULL. If it returns a timedelta and the value is
1150 * out of range or isn't a whole number of minutes, ValueError is raised and
1151 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +00001152 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001153static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001154call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001155{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001156 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001159 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001161
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001162 if (tzinfo == Py_None)
1163 Py_RETURN_NONE;
1164 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1165 if (offset == Py_None || offset == NULL)
1166 return offset;
1167 if (PyDelta_Check(offset)) {
Ngalim Siregar92c7e302019-08-09 21:22:16 +07001168 if ((GET_TD_DAYS(offset) == -1 &&
1169 GET_TD_SECONDS(offset) == 0 &&
1170 GET_TD_MICROSECONDS(offset) < 1) ||
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001171 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1172 Py_DECREF(offset);
1173 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1174 " strictly between -timedelta(hours=24) and"
1175 " timedelta(hours=24).");
1176 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 }
1178 }
1179 else {
1180 PyErr_Format(PyExc_TypeError,
1181 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001182 "timedelta, not '%.200s'",
1183 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07001184 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001185 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001187
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001188 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001189}
1190
1191/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1192 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
1193 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +00001194 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001195 * If utcoffset() returns an out of range timedelta,
1196 * ValueError is raised and this returns -1. Else *none is
1197 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001198 */
Tim Peters855fe882002-12-22 03:43:39 +00001199static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001200call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1201{
1202 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001203}
1204
Tim Peters2a799bf2002-12-16 20:18:38 +00001205/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1206 * result. tzinfo must be an instance of the tzinfo class. If dst()
1207 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001208 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00001209 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +00001210 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001211 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001212 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001213static PyObject *
1214call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001215{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001216 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001217}
1218
Tim Petersbad8ff02002-12-30 20:52:32 +00001219/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +00001220 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001221 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001222 * returns NULL. If the result is a string, we ensure it is a Unicode
1223 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001224 */
1225static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001226call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001227{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001229 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 assert(tzinfo != NULL);
1232 assert(check_tzinfo_subclass(tzinfo) >= 0);
1233 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001236 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001237
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001238 result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001239
1240 if (result == NULL || result == Py_None)
1241 return result;
1242
1243 if (!PyUnicode_Check(result)) {
1244 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1245 "return None or a string, not '%s'",
1246 Py_TYPE(result)->tp_name);
1247 Py_DECREF(result);
1248 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001250
1251 return result;
Tim Peters00237032002-12-27 02:21:51 +00001252}
1253
Tim Peters2a799bf2002-12-16 20:18:38 +00001254/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1255 * stuff
1256 * ", tzinfo=" + repr(tzinfo)
1257 * before the closing ")".
1258 */
1259static PyObject *
1260append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 assert(PyUnicode_Check(repr));
1265 assert(tzinfo);
1266 if (tzinfo == Py_None)
1267 return repr;
1268 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001269 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1270 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 Py_DECREF(repr);
1272 if (temp == NULL)
1273 return NULL;
1274 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1275 Py_DECREF(temp);
1276 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001277}
1278
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001279/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1280 * stuff
1281 * ", fold=" + repr(tzinfo)
1282 * before the closing ")".
1283 */
1284static PyObject *
1285append_keyword_fold(PyObject *repr, int fold)
1286{
1287 PyObject *temp;
1288
1289 assert(PyUnicode_Check(repr));
1290 if (fold == 0)
1291 return repr;
1292 /* Get rid of the trailing ')'. */
1293 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1294 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1295 Py_DECREF(repr);
1296 if (temp == NULL)
1297 return NULL;
1298 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1299 Py_DECREF(temp);
1300 return repr;
1301}
1302
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001303static inline PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04001304tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
1305{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001306 PyObject *tzinfo;
1307 if (rv == 1) {
1308 // Create a timezone from offset in seconds (0 returns UTC)
1309 if (tzoffset == 0) {
1310 Py_INCREF(PyDateTime_TimeZone_UTC);
1311 return PyDateTime_TimeZone_UTC;
1312 }
1313
1314 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001315 if (delta == NULL) {
1316 return NULL;
1317 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001318 tzinfo = new_timezone(delta, NULL);
Alexey Izbyshev49884532018-08-24 18:53:16 +03001319 Py_DECREF(delta);
Paul Ganssle3df85402018-10-22 12:32:52 -04001320 }
1321 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001322 tzinfo = Py_None;
1323 Py_INCREF(Py_None);
1324 }
1325
1326 return tzinfo;
1327}
1328
Tim Peters2a799bf2002-12-16 20:18:38 +00001329/* ---------------------------------------------------------------------------
1330 * String format helpers.
1331 */
1332
1333static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001334format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001335{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001336 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1338 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001339 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1341 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1342 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1347 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1348 GET_DAY(date), hours, minutes, seconds,
1349 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001350}
1351
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001352static PyObject *delta_negative(PyDateTime_Delta *self);
1353
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001354/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001355 * buflen bytes remaining. The UTC offset is gotten by calling
1356 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1357 * *buf, and that's all. Else the returned value is checked for sanity (an
1358 * integer in range), and if that's OK it's converted to an hours & minutes
1359 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001360 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001361 * Returns 0 if everything is OK. If the return value from utcoffset() is
1362 * bogus, an appropriate exception is set and -1 is returned.
1363 */
1364static int
Tim Peters328fff72002-12-20 01:31:27 +00001365format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001367{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001368 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001369 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001373
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001374 offset = call_utcoffset(tzinfo, tzinfoarg);
1375 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001377 if (offset == Py_None) {
1378 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 *buf = '\0';
1380 return 0;
1381 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001382 /* Offset is normalized, so it is negative if days < 0 */
1383 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001385 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001386 if (offset == NULL)
1387 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001389 else {
1390 sign = '+';
1391 }
1392 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001393 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001394 seconds = GET_TD_SECONDS(offset);
1395 Py_DECREF(offset);
1396 minutes = divmod(seconds, 60, &seconds);
1397 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001398 if (microseconds) {
1399 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1400 hours, sep, minutes, sep, seconds, microseconds);
1401 return 0;
1402 }
1403 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001404 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1405 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001406 return 0;
1407 }
1408 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001410}
1411
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001412static PyObject *
1413make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 PyObject *temp;
1416 PyObject *tzinfo = get_tzinfo_member(object);
1417 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001418 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 if (Zreplacement == NULL)
1421 return NULL;
1422 if (tzinfo == Py_None || tzinfo == NULL)
1423 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 assert(tzinfoarg != NULL);
1426 temp = call_tzname(tzinfo, tzinfoarg);
1427 if (temp == NULL)
1428 goto Error;
1429 if (temp == Py_None) {
1430 Py_DECREF(temp);
1431 return Zreplacement;
1432 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 assert(PyUnicode_Check(temp));
1435 /* Since the tzname is getting stuffed into the
1436 * format, we have to double any % signs so that
1437 * strftime doesn't treat them as format codes.
1438 */
1439 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001440 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 Py_DECREF(temp);
1442 if (Zreplacement == NULL)
1443 return NULL;
1444 if (!PyUnicode_Check(Zreplacement)) {
1445 PyErr_SetString(PyExc_TypeError,
1446 "tzname.replace() did not return a string");
1447 goto Error;
1448 }
1449 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001450
1451 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 Py_DECREF(Zreplacement);
1453 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001454}
1455
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001456static PyObject *
1457make_freplacement(PyObject *object)
1458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 char freplacement[64];
1460 if (PyTime_Check(object))
1461 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1462 else if (PyDateTime_Check(object))
1463 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1464 else
1465 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001468}
1469
Tim Peters2a799bf2002-12-16 20:18:38 +00001470/* I sure don't want to reproduce the strftime code from the time module,
1471 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001472 * giving special meanings to the %z, %Z and %f format codes via a
1473 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001474 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1475 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001476 */
1477static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001478wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001480{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1484 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1485 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 const char *pin; /* pointer to next char in input format */
1488 Py_ssize_t flen; /* length of input format */
1489 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 PyObject *newfmt = NULL; /* py string, the output format */
1492 char *pnew; /* pointer to available byte in output format */
1493 size_t totalnew; /* number bytes total in output format buffer,
1494 exclusive of trailing \0 */
1495 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 const char *ptoappend; /* ptr to string to append to output buffer */
1498 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 assert(object && format && timetuple);
1501 assert(PyUnicode_Check(format));
1502 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001503 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 if (!pin)
1505 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 /* Scan the input format, looking for %z/%Z/%f escapes, building
1508 * a new format. Since computing the replacements for those codes
1509 * is expensive, don't unless they're actually used.
1510 */
1511 if (flen > INT_MAX - 1) {
1512 PyErr_NoMemory();
1513 goto Done;
1514 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 totalnew = flen + 1; /* realistic if no %z/%Z */
1517 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1518 if (newfmt == NULL) goto Done;
1519 pnew = PyBytes_AsString(newfmt);
1520 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 while ((ch = *pin++) != '\0') {
1523 if (ch != '%') {
1524 ptoappend = pin - 1;
1525 ntoappend = 1;
1526 }
1527 else if ((ch = *pin++) == '\0') {
Victor Stinner2ff58a22019-06-17 14:27:23 +02001528 /* Null byte follows %, copy only '%'.
1529 *
MichaelSaah454b3d42019-01-14 05:23:39 -05001530 * Back the pin up one char so that we catch the null check
1531 * the next time through the loop.*/
1532 pin--;
1533 ptoappend = pin - 1;
1534 ntoappend = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 }
1536 /* A % has been seen and ch is the character after it. */
1537 else if (ch == 'z') {
1538 if (zreplacement == NULL) {
1539 /* format utcoffset */
1540 char buf[100];
1541 PyObject *tzinfo = get_tzinfo_member(object);
1542 zreplacement = PyBytes_FromStringAndSize("", 0);
1543 if (zreplacement == NULL) goto Done;
1544 if (tzinfo != Py_None && tzinfo != NULL) {
1545 assert(tzinfoarg != NULL);
1546 if (format_utcoffset(buf,
1547 sizeof(buf),
1548 "",
1549 tzinfo,
1550 tzinfoarg) < 0)
1551 goto Done;
1552 Py_DECREF(zreplacement);
1553 zreplacement =
1554 PyBytes_FromStringAndSize(buf,
1555 strlen(buf));
1556 if (zreplacement == NULL)
1557 goto Done;
1558 }
1559 }
1560 assert(zreplacement != NULL);
1561 ptoappend = PyBytes_AS_STRING(zreplacement);
1562 ntoappend = PyBytes_GET_SIZE(zreplacement);
1563 }
1564 else if (ch == 'Z') {
1565 /* format tzname */
1566 if (Zreplacement == NULL) {
1567 Zreplacement = make_Zreplacement(object,
1568 tzinfoarg);
1569 if (Zreplacement == NULL)
1570 goto Done;
1571 }
1572 assert(Zreplacement != NULL);
1573 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001574 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001576 if (ptoappend == NULL)
1577 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 }
1579 else if (ch == 'f') {
1580 /* format microseconds */
1581 if (freplacement == NULL) {
1582 freplacement = make_freplacement(object);
1583 if (freplacement == NULL)
1584 goto Done;
1585 }
1586 assert(freplacement != NULL);
1587 assert(PyBytes_Check(freplacement));
1588 ptoappend = PyBytes_AS_STRING(freplacement);
1589 ntoappend = PyBytes_GET_SIZE(freplacement);
1590 }
1591 else {
1592 /* percent followed by neither z nor Z */
1593 ptoappend = pin - 2;
1594 ntoappend = 2;
1595 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 /* Append the ntoappend chars starting at ptoappend to
1598 * the new format.
1599 */
1600 if (ntoappend == 0)
1601 continue;
1602 assert(ptoappend != NULL);
1603 assert(ntoappend > 0);
1604 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001605 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 PyErr_NoMemory();
1607 goto Done;
1608 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001609 totalnew <<= 1;
1610 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 pnew = PyBytes_AsString(newfmt) + usednew;
1613 }
1614 memcpy(pnew, ptoappend, ntoappend);
1615 pnew += ntoappend;
1616 usednew += ntoappend;
1617 assert(usednew <= totalnew);
1618 } /* end while() */
Victor Stinner2ff58a22019-06-17 14:27:23 +02001619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1621 goto Done;
1622 {
1623 PyObject *format;
1624 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 if (time == NULL)
1627 goto Done;
1628 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1629 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001630 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1631 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 Py_DECREF(format);
1633 }
1634 Py_DECREF(time);
1635 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001636 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 Py_XDECREF(freplacement);
1638 Py_XDECREF(zreplacement);
1639 Py_XDECREF(Zreplacement);
1640 Py_XDECREF(newfmt);
1641 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001642}
1643
Tim Peters2a799bf2002-12-16 20:18:38 +00001644/* ---------------------------------------------------------------------------
1645 * Wrap functions from the time module. These aren't directly available
1646 * from C. Perhaps they should be.
1647 */
1648
1649/* Call time.time() and return its result (a Python float). */
1650static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001651time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001652{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 PyObject *result = NULL;
1654 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001657 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001658
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001659 result = _PyObject_CallMethodIdNoArgs(time, &PyId_time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 Py_DECREF(time);
1661 }
1662 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001663}
1664
1665/* Build a time.struct_time. The weekday and day number are automatically
1666 * computed from the y,m,d args.
1667 */
1668static PyObject *
1669build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001672 PyObject *result;
1673 _Py_IDENTIFIER(struct_time);
1674 PyObject *args;
1675
Tim Peters2a799bf2002-12-16 20:18:38 +00001676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001678 if (time == NULL) {
1679 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 }
Victor Stinner2b635972016-12-09 00:38:16 +01001681
1682 args = Py_BuildValue("iiiiiiiii",
1683 y, m, d,
1684 hh, mm, ss,
1685 weekday(y, m, d),
1686 days_before_month(y, m) + d,
1687 dstflag);
1688 if (args == NULL) {
1689 Py_DECREF(time);
1690 return NULL;
1691 }
1692
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001693 result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args);
Victor Stinner2b635972016-12-09 00:38:16 +01001694 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001695 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001696 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001697}
1698
1699/* ---------------------------------------------------------------------------
1700 * Miscellaneous helpers.
1701 */
1702
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001703/* The comparisons here all most naturally compute a cmp()-like result.
Tim Peters2a799bf2002-12-16 20:18:38 +00001704 * This little helper turns that into a bool result for rich comparisons.
1705 */
1706static PyObject *
1707diff_to_bool(int diff, int op)
1708{
stratakise8b19652017-11-02 11:32:54 +01001709 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001710}
1711
Tim Peters07534a62003-02-07 22:50:28 +00001712/* Raises a "can't compare" TypeError and returns NULL. */
1713static PyObject *
1714cmperror(PyObject *a, PyObject *b)
1715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 PyErr_Format(PyExc_TypeError,
1717 "can't compare %s to %s",
1718 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1719 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001720}
1721
Tim Peters2a799bf2002-12-16 20:18:38 +00001722/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001723 * Cached Python objects; these are set by the module init function.
1724 */
1725
1726/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727static PyObject *us_per_ms = NULL; /* 1000 */
1728static PyObject *us_per_second = NULL; /* 1000000 */
1729static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001730static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1731static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1732static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001733static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1734
Tim Peters2a799bf2002-12-16 20:18:38 +00001735/* ---------------------------------------------------------------------------
1736 * Class implementations.
1737 */
1738
1739/*
1740 * PyDateTime_Delta implementation.
1741 */
1742
1743/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001745 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001746 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1747 * due to ubiquitous overflow possibilities.
1748 */
1749static PyObject *
1750delta_to_microseconds(PyDateTime_Delta *self)
1751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 PyObject *x1 = NULL;
1753 PyObject *x2 = NULL;
1754 PyObject *x3 = NULL;
1755 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1758 if (x1 == NULL)
1759 goto Done;
1760 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1761 if (x2 == NULL)
1762 goto Done;
1763 Py_DECREF(x1);
1764 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 /* x2 has days in seconds */
1767 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1768 if (x1 == NULL)
1769 goto Done;
1770 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1771 if (x3 == NULL)
1772 goto Done;
1773 Py_DECREF(x1);
1774 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001775 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 /* x3 has days+seconds in seconds */
1778 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1779 if (x1 == NULL)
1780 goto Done;
1781 Py_DECREF(x3);
1782 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 /* x1 has days+seconds in us */
1785 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1786 if (x2 == NULL)
1787 goto Done;
1788 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001789 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001790
1791Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 Py_XDECREF(x1);
1793 Py_XDECREF(x2);
1794 Py_XDECREF(x3);
1795 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001796}
1797
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001798static PyObject *
1799checked_divmod(PyObject *a, PyObject *b)
1800{
1801 PyObject *result = PyNumber_Divmod(a, b);
1802 if (result != NULL) {
1803 if (!PyTuple_Check(result)) {
1804 PyErr_Format(PyExc_TypeError,
1805 "divmod() returned non-tuple (type %.200s)",
Victor Stinnerdaa97562020-02-07 03:37:06 +01001806 Py_TYPE(result)->tp_name);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001807 Py_DECREF(result);
1808 return NULL;
1809 }
1810 if (PyTuple_GET_SIZE(result) != 2) {
1811 PyErr_Format(PyExc_TypeError,
1812 "divmod() returned a tuple of size %zd",
1813 PyTuple_GET_SIZE(result));
1814 Py_DECREF(result);
1815 return NULL;
1816 }
1817 }
1818 return result;
1819}
1820
Serhiy Storchaka95949422013-08-27 19:40:23 +03001821/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001822 */
1823static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001824microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 int us;
1827 int s;
1828 int d;
Tim Peters2a799bf2002-12-16 20:18:38 +00001829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 PyObject *tuple = NULL;
1831 PyObject *num = NULL;
1832 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001833
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001834 tuple = checked_divmod(pyus, us_per_second);
1835 if (tuple == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 goto Done;
1837 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001838
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001839 num = PyTuple_GET_ITEM(tuple, 1); /* us */
1840 us = _PyLong_AsInt(num);
1841 num = NULL;
1842 if (us == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 goto Done;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001844 }
1845 if (!(0 <= us && us < 1000000)) {
1846 goto BadDivmod;
1847 }
1848
1849 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 Py_INCREF(num);
1851 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001852
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001853 tuple = checked_divmod(num, seconds_per_day);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 if (tuple == NULL)
1855 goto Done;
1856 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001857
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001858 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */
1859 s = _PyLong_AsInt(num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 num = NULL;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001861 if (s == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 goto Done;
1863 }
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001864 if (!(0 <= s && s < 24*3600)) {
1865 goto BadDivmod;
1866 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001867
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001868 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 Py_INCREF(num);
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001870 d = _PyLong_AsInt(num);
1871 if (d == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 goto Done;
1873 }
1874 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001875
1876Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 Py_XDECREF(tuple);
1878 Py_XDECREF(num);
1879 return result;
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001880
1881BadDivmod:
1882 PyErr_SetString(PyExc_TypeError,
1883 "divmod() returned a value out of range");
1884 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001885}
1886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887#define microseconds_to_delta(pymicros) \
1888 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001889
Tim Peters2a799bf2002-12-16 20:18:38 +00001890static PyObject *
1891multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1892{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 PyObject *pyus_in;
1894 PyObject *pyus_out;
1895 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 pyus_in = delta_to_microseconds(delta);
1898 if (pyus_in == NULL)
1899 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001900
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02001901 pyus_out = PyNumber_Multiply(intobj, pyus_in);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 Py_DECREF(pyus_in);
1903 if (pyus_out == NULL)
1904 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 result = microseconds_to_delta(pyus_out);
1907 Py_DECREF(pyus_out);
1908 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001909}
1910
1911static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001912get_float_as_integer_ratio(PyObject *floatobj)
1913{
1914 PyObject *ratio;
1915
1916 assert(floatobj && PyFloat_Check(floatobj));
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001917 ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio);
Oren Milman865e4b42017-09-19 15:58:11 +03001918 if (ratio == NULL) {
1919 return NULL;
1920 }
1921 if (!PyTuple_Check(ratio)) {
1922 PyErr_Format(PyExc_TypeError,
1923 "unexpected return type from as_integer_ratio(): "
1924 "expected tuple, got '%.200s'",
1925 Py_TYPE(ratio)->tp_name);
1926 Py_DECREF(ratio);
1927 return NULL;
1928 }
1929 if (PyTuple_Size(ratio) != 2) {
1930 PyErr_SetString(PyExc_ValueError,
1931 "as_integer_ratio() must return a 2-tuple");
1932 Py_DECREF(ratio);
1933 return NULL;
1934 }
1935 return ratio;
1936}
1937
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001938/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001939static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001940multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001941{
1942 PyObject *result = NULL;
1943 PyObject *pyus_in = NULL, *temp, *pyus_out;
1944 PyObject *ratio = NULL;
1945
1946 pyus_in = delta_to_microseconds(delta);
1947 if (pyus_in == NULL)
1948 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001949 ratio = get_float_as_integer_ratio(floatobj);
1950 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001951 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001952 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001953 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001954 Py_DECREF(pyus_in);
1955 pyus_in = NULL;
1956 if (temp == NULL)
1957 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001958 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001959 Py_DECREF(temp);
1960 if (pyus_out == NULL)
1961 goto error;
1962 result = microseconds_to_delta(pyus_out);
1963 Py_DECREF(pyus_out);
1964 error:
1965 Py_XDECREF(pyus_in);
1966 Py_XDECREF(ratio);
1967
1968 return result;
1969}
1970
1971static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001972divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 PyObject *pyus_in;
1975 PyObject *pyus_out;
1976 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 pyus_in = delta_to_microseconds(delta);
1979 if (pyus_in == NULL)
1980 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1983 Py_DECREF(pyus_in);
1984 if (pyus_out == NULL)
1985 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 result = microseconds_to_delta(pyus_out);
1988 Py_DECREF(pyus_out);
1989 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001990}
1991
1992static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001993divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 PyObject *pyus_left;
1996 PyObject *pyus_right;
1997 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 pyus_left = delta_to_microseconds(left);
2000 if (pyus_left == NULL)
2001 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 pyus_right = delta_to_microseconds(right);
2004 if (pyus_right == NULL) {
2005 Py_DECREF(pyus_left);
2006 return NULL;
2007 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 result = PyNumber_FloorDivide(pyus_left, pyus_right);
2010 Py_DECREF(pyus_left);
2011 Py_DECREF(pyus_right);
2012 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002013}
2014
2015static PyObject *
2016truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2017{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 PyObject *pyus_left;
2019 PyObject *pyus_right;
2020 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 pyus_left = delta_to_microseconds(left);
2023 if (pyus_left == NULL)
2024 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 pyus_right = delta_to_microseconds(right);
2027 if (pyus_right == NULL) {
2028 Py_DECREF(pyus_left);
2029 return NULL;
2030 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2033 Py_DECREF(pyus_left);
2034 Py_DECREF(pyus_right);
2035 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002036}
2037
2038static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002039truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2040{
2041 PyObject *result;
2042 PyObject *pyus_in, *pyus_out;
2043 pyus_in = delta_to_microseconds(delta);
2044 if (pyus_in == NULL)
2045 return NULL;
2046 pyus_out = divide_nearest(pyus_in, i);
2047 Py_DECREF(pyus_in);
2048 if (pyus_out == NULL)
2049 return NULL;
2050 result = microseconds_to_delta(pyus_out);
2051 Py_DECREF(pyus_out);
2052
2053 return result;
2054}
2055
2056static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002057delta_add(PyObject *left, PyObject *right)
2058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2062 /* delta + delta */
2063 /* The C-level additions can't overflow because of the
2064 * invariant bounds.
2065 */
2066 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2067 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2068 int microseconds = GET_TD_MICROSECONDS(left) +
2069 GET_TD_MICROSECONDS(right);
2070 result = new_delta(days, seconds, microseconds, 1);
2071 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 if (result == Py_NotImplemented)
2074 Py_INCREF(result);
2075 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002076}
2077
2078static PyObject *
2079delta_negative(PyDateTime_Delta *self)
2080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 return new_delta(-GET_TD_DAYS(self),
2082 -GET_TD_SECONDS(self),
2083 -GET_TD_MICROSECONDS(self),
2084 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002085}
2086
2087static PyObject *
2088delta_positive(PyDateTime_Delta *self)
2089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 /* Could optimize this (by returning self) if this isn't a
2091 * subclass -- but who uses unary + ? Approximately nobody.
2092 */
2093 return new_delta(GET_TD_DAYS(self),
2094 GET_TD_SECONDS(self),
2095 GET_TD_MICROSECONDS(self),
2096 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002097}
2098
2099static PyObject *
2100delta_abs(PyDateTime_Delta *self)
2101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 assert(GET_TD_MICROSECONDS(self) >= 0);
2105 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 if (GET_TD_DAYS(self) < 0)
2108 result = delta_negative(self);
2109 else
2110 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002113}
2114
2115static PyObject *
2116delta_subtract(PyObject *left, PyObject *right)
2117{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2121 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002122 /* The C-level additions can't overflow because of the
2123 * invariant bounds.
2124 */
2125 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2126 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2127 int microseconds = GET_TD_MICROSECONDS(left) -
2128 GET_TD_MICROSECONDS(right);
2129 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002132 if (result == Py_NotImplemented)
2133 Py_INCREF(result);
2134 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002135}
2136
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002137static int
2138delta_cmp(PyObject *self, PyObject *other)
2139{
2140 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2141 if (diff == 0) {
2142 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2143 if (diff == 0)
2144 diff = GET_TD_MICROSECONDS(self) -
2145 GET_TD_MICROSECONDS(other);
2146 }
2147 return diff;
2148}
2149
Tim Peters2a799bf2002-12-16 20:18:38 +00002150static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002151delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002153 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002154 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 return diff_to_bool(diff, op);
2156 }
2157 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002158 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002160}
2161
2162static PyObject *delta_getstate(PyDateTime_Delta *self);
2163
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002164static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002165delta_hash(PyDateTime_Delta *self)
2166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 if (self->hashcode == -1) {
2168 PyObject *temp = delta_getstate(self);
2169 if (temp != NULL) {
2170 self->hashcode = PyObject_Hash(temp);
2171 Py_DECREF(temp);
2172 }
2173 }
2174 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002175}
2176
2177static PyObject *
2178delta_multiply(PyObject *left, PyObject *right)
2179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 if (PyDelta_Check(left)) {
2183 /* delta * ??? */
2184 if (PyLong_Check(right))
2185 result = multiply_int_timedelta(right,
2186 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002187 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002188 result = multiply_truedivide_timedelta_float(
2189 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 }
2191 else if (PyLong_Check(left))
2192 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002193 (PyDateTime_Delta *) right);
2194 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002195 result = multiply_truedivide_timedelta_float(
2196 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 if (result == Py_NotImplemented)
2199 Py_INCREF(result);
2200 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002201}
2202
2203static PyObject *
2204delta_divide(PyObject *left, PyObject *right)
2205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002208 if (PyDelta_Check(left)) {
2209 /* delta * ??? */
2210 if (PyLong_Check(right))
2211 result = divide_timedelta_int(
2212 (PyDateTime_Delta *)left,
2213 right);
2214 else if (PyDelta_Check(right))
2215 result = divide_timedelta_timedelta(
2216 (PyDateTime_Delta *)left,
2217 (PyDateTime_Delta *)right);
2218 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 if (result == Py_NotImplemented)
2221 Py_INCREF(result);
2222 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002223}
2224
Mark Dickinson7c186e22010-04-20 22:32:49 +00002225static PyObject *
2226delta_truedivide(PyObject *left, PyObject *right)
2227{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002230 if (PyDelta_Check(left)) {
2231 if (PyDelta_Check(right))
2232 result = truedivide_timedelta_timedelta(
2233 (PyDateTime_Delta *)left,
2234 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002235 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002236 result = multiply_truedivide_timedelta_float(
2237 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002238 else if (PyLong_Check(right))
2239 result = truedivide_timedelta_int(
2240 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 if (result == Py_NotImplemented)
2244 Py_INCREF(result);
2245 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002246}
2247
2248static PyObject *
2249delta_remainder(PyObject *left, PyObject *right)
2250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 PyObject *pyus_left;
2252 PyObject *pyus_right;
2253 PyObject *pyus_remainder;
2254 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002255
Brian Curtindfc80e32011-08-10 20:28:54 -05002256 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2257 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002259 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2260 if (pyus_left == NULL)
2261 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2264 if (pyus_right == NULL) {
2265 Py_DECREF(pyus_left);
2266 return NULL;
2267 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2270 Py_DECREF(pyus_left);
2271 Py_DECREF(pyus_right);
2272 if (pyus_remainder == NULL)
2273 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002275 remainder = microseconds_to_delta(pyus_remainder);
2276 Py_DECREF(pyus_remainder);
2277 if (remainder == NULL)
2278 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002281}
2282
2283static PyObject *
2284delta_divmod(PyObject *left, PyObject *right)
2285{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 PyObject *pyus_left;
2287 PyObject *pyus_right;
2288 PyObject *divmod;
2289 PyObject *delta;
2290 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002291
Brian Curtindfc80e32011-08-10 20:28:54 -05002292 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2293 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2296 if (pyus_left == NULL)
2297 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2300 if (pyus_right == NULL) {
2301 Py_DECREF(pyus_left);
2302 return NULL;
2303 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002304
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002305 divmod = checked_divmod(pyus_left, pyus_right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 Py_DECREF(pyus_left);
2307 Py_DECREF(pyus_right);
2308 if (divmod == NULL)
2309 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002311 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2312 if (delta == NULL) {
2313 Py_DECREF(divmod);
2314 return NULL;
2315 }
2316 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2317 Py_DECREF(delta);
2318 Py_DECREF(divmod);
2319 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002320}
2321
Tim Peters2a799bf2002-12-16 20:18:38 +00002322/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2323 * timedelta constructor. sofar is the # of microseconds accounted for
2324 * so far, and there are factor microseconds per current unit, the number
2325 * of which is given by num. num * factor is added to sofar in a
2326 * numerically careful way, and that's the result. Any fractional
2327 * microseconds left over (this can happen if num is a float type) are
2328 * added into *leftover.
2329 * Note that there are many ways this can give an error (NULL) return.
2330 */
2331static PyObject *
2332accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2333 double *leftover)
2334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 PyObject *prod;
2336 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002338 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002340 if (PyLong_Check(num)) {
Serhiy Storchaka3ec0f492018-11-20 20:41:09 +02002341 prod = PyNumber_Multiply(num, factor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002342 if (prod == NULL)
2343 return NULL;
2344 sum = PyNumber_Add(sofar, prod);
2345 Py_DECREF(prod);
2346 return sum;
2347 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 if (PyFloat_Check(num)) {
2350 double dnum;
2351 double fracpart;
2352 double intpart;
2353 PyObject *x;
2354 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356 /* The Plan: decompose num into an integer part and a
2357 * fractional part, num = intpart + fracpart.
2358 * Then num * factor ==
2359 * intpart * factor + fracpart * factor
2360 * and the LHS can be computed exactly in long arithmetic.
2361 * The RHS is again broken into an int part and frac part.
2362 * and the frac part is added into *leftover.
2363 */
2364 dnum = PyFloat_AsDouble(num);
2365 if (dnum == -1.0 && PyErr_Occurred())
2366 return NULL;
2367 fracpart = modf(dnum, &intpart);
2368 x = PyLong_FromDouble(intpart);
2369 if (x == NULL)
2370 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372 prod = PyNumber_Multiply(x, factor);
2373 Py_DECREF(x);
2374 if (prod == NULL)
2375 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 sum = PyNumber_Add(sofar, prod);
2378 Py_DECREF(prod);
2379 if (sum == NULL)
2380 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 if (fracpart == 0.0)
2383 return sum;
2384 /* So far we've lost no information. Dealing with the
2385 * fractional part requires float arithmetic, and may
2386 * lose a little info.
2387 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002388 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 dnum *= fracpart;
2392 fracpart = modf(dnum, &intpart);
2393 x = PyLong_FromDouble(intpart);
2394 if (x == NULL) {
2395 Py_DECREF(sum);
2396 return NULL;
2397 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 y = PyNumber_Add(sum, x);
2400 Py_DECREF(sum);
2401 Py_DECREF(x);
2402 *leftover += fracpart;
2403 return y;
2404 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 PyErr_Format(PyExc_TypeError,
2407 "unsupported type for timedelta %s component: %s",
2408 tag, Py_TYPE(num)->tp_name);
2409 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002410}
2411
2412static PyObject *
2413delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 /* Argument objects. */
2418 PyObject *day = NULL;
2419 PyObject *second = NULL;
2420 PyObject *us = NULL;
2421 PyObject *ms = NULL;
2422 PyObject *minute = NULL;
2423 PyObject *hour = NULL;
2424 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 PyObject *x = NULL; /* running sum of microseconds */
2427 PyObject *y = NULL; /* temp sum of microseconds */
2428 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 static char *keywords[] = {
2431 "days", "seconds", "microseconds", "milliseconds",
2432 "minutes", "hours", "weeks", NULL
2433 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2436 keywords,
2437 &day, &second, &us,
2438 &ms, &minute, &hour, &week) == 0)
2439 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002441 x = PyLong_FromLong(0);
2442 if (x == NULL)
2443 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445#define CLEANUP \
2446 Py_DECREF(x); \
2447 x = y; \
2448 if (x == NULL) \
2449 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002451 if (us) {
Victor Stinner37834132020-10-27 17:12:53 +01002452 y = accum("microseconds", x, us, _PyLong_GetOne(), &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 CLEANUP;
2454 }
2455 if (ms) {
2456 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2457 CLEANUP;
2458 }
2459 if (second) {
2460 y = accum("seconds", x, second, us_per_second, &leftover_us);
2461 CLEANUP;
2462 }
2463 if (minute) {
2464 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2465 CLEANUP;
2466 }
2467 if (hour) {
2468 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2469 CLEANUP;
2470 }
2471 if (day) {
2472 y = accum("days", x, day, us_per_day, &leftover_us);
2473 CLEANUP;
2474 }
2475 if (week) {
2476 y = accum("weeks", x, week, us_per_week, &leftover_us);
2477 CLEANUP;
2478 }
2479 if (leftover_us) {
2480 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002481 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002482 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002483 PyObject *temp;
2484
Victor Stinner69cc4872015-09-08 23:58:54 +02002485 if (fabs(whole_us - leftover_us) == 0.5) {
2486 /* We're exactly halfway between two integers. In order
2487 * to do round-half-to-even, we must determine whether x
2488 * is odd. Note that x is odd when it's last bit is 1. The
2489 * code below uses bitwise and operation to check the last
2490 * bit. */
Victor Stinner37834132020-10-27 17:12:53 +01002491 temp = PyNumber_And(x, _PyLong_GetOne()); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002492 if (temp == NULL) {
2493 Py_DECREF(x);
2494 goto Done;
2495 }
2496 x_is_odd = PyObject_IsTrue(temp);
2497 Py_DECREF(temp);
2498 if (x_is_odd == -1) {
2499 Py_DECREF(x);
2500 goto Done;
2501 }
2502 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2503 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002504
Victor Stinner36a5a062013-08-28 01:53:39 +02002505 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002507 if (temp == NULL) {
2508 Py_DECREF(x);
2509 goto Done;
2510 }
2511 y = PyNumber_Add(x, temp);
2512 Py_DECREF(temp);
2513 CLEANUP;
2514 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 self = microseconds_to_delta_ex(x, type);
2517 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002518Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002520
2521#undef CLEANUP
2522}
2523
2524static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002525delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002526{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002527 return (GET_TD_DAYS(self) != 0
2528 || GET_TD_SECONDS(self) != 0
2529 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002530}
2531
2532static PyObject *
2533delta_repr(PyDateTime_Delta *self)
2534{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002535 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002536
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002537 if (args == NULL) {
2538 return NULL;
2539 }
2540
2541 const char *sep = "";
2542
2543 if (GET_TD_DAYS(self) != 0) {
2544 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2545 if (args == NULL) {
2546 return NULL;
2547 }
2548 sep = ", ";
2549 }
2550
2551 if (GET_TD_SECONDS(self) != 0) {
2552 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2553 GET_TD_SECONDS(self)));
2554 if (args == NULL) {
2555 return NULL;
2556 }
2557 sep = ", ";
2558 }
2559
2560 if (GET_TD_MICROSECONDS(self) != 0) {
2561 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2562 GET_TD_MICROSECONDS(self)));
2563 if (args == NULL) {
2564 return NULL;
2565 }
2566 }
2567
2568 if (PyUnicode_GET_LENGTH(args) == 0) {
2569 Py_SETREF(args, PyUnicode_FromString("0"));
2570 if (args == NULL) {
2571 return NULL;
2572 }
2573 }
2574
2575 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2576 args);
2577 Py_DECREF(args);
2578 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002579}
2580
2581static PyObject *
2582delta_str(PyDateTime_Delta *self)
2583{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002584 int us = GET_TD_MICROSECONDS(self);
2585 int seconds = GET_TD_SECONDS(self);
2586 int minutes = divmod(seconds, 60, &seconds);
2587 int hours = divmod(minutes, 60, &minutes);
2588 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002590 if (days) {
2591 if (us)
2592 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2593 days, (days == 1 || days == -1) ? "" : "s",
2594 hours, minutes, seconds, us);
2595 else
2596 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2597 days, (days == 1 || days == -1) ? "" : "s",
2598 hours, minutes, seconds);
2599 } else {
2600 if (us)
2601 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2602 hours, minutes, seconds, us);
2603 else
2604 return PyUnicode_FromFormat("%d:%02d:%02d",
2605 hours, minutes, seconds);
2606 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002607
Tim Peters2a799bf2002-12-16 20:18:38 +00002608}
2609
Tim Peters371935f2003-02-01 01:52:50 +00002610/* Pickle support, a simple use of __reduce__. */
2611
Tim Petersb57f8f02003-02-01 02:54:15 +00002612/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002613static PyObject *
2614delta_getstate(PyDateTime_Delta *self)
2615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 return Py_BuildValue("iii", GET_TD_DAYS(self),
2617 GET_TD_SECONDS(self),
2618 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002619}
2620
Tim Peters2a799bf2002-12-16 20:18:38 +00002621static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302622delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitroube6859d2009-11-25 23:02:32 +00002623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 PyObject *total_seconds;
2625 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002627 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2628 if (total_microseconds == NULL)
2629 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002630
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002631 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002634 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002635}
2636
2637static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302638delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00002639{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002640 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002641}
2642
2643#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2644
2645static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002647 {"days", T_INT, OFFSET(days), READONLY,
2648 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 {"seconds", T_INT, OFFSET(seconds), READONLY,
2651 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2654 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2655 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002656};
2657
2658static PyMethodDef delta_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302659 {"total_seconds", delta_total_seconds, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002660 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2663 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002665 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002666};
2667
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002668static const char delta_doc[] =
Chris Barkerd6a61f22018-10-19 15:43:24 -07002669PyDoc_STR("Difference between two datetime values.\n\n"
2670 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2671 "minutes=0, hours=0, weeks=0)\n\n"
2672 "All arguments are optional and default to 0.\n"
2673 "Arguments may be integers or floats, and may be positive or negative.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002674
2675static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002676 delta_add, /* nb_add */
2677 delta_subtract, /* nb_subtract */
2678 delta_multiply, /* nb_multiply */
2679 delta_remainder, /* nb_remainder */
2680 delta_divmod, /* nb_divmod */
2681 0, /* nb_power */
2682 (unaryfunc)delta_negative, /* nb_negative */
2683 (unaryfunc)delta_positive, /* nb_positive */
2684 (unaryfunc)delta_abs, /* nb_absolute */
2685 (inquiry)delta_bool, /* nb_bool */
2686 0, /*nb_invert*/
2687 0, /*nb_lshift*/
2688 0, /*nb_rshift*/
2689 0, /*nb_and*/
2690 0, /*nb_xor*/
2691 0, /*nb_or*/
2692 0, /*nb_int*/
2693 0, /*nb_reserved*/
2694 0, /*nb_float*/
2695 0, /*nb_inplace_add*/
2696 0, /*nb_inplace_subtract*/
2697 0, /*nb_inplace_multiply*/
2698 0, /*nb_inplace_remainder*/
2699 0, /*nb_inplace_power*/
2700 0, /*nb_inplace_lshift*/
2701 0, /*nb_inplace_rshift*/
2702 0, /*nb_inplace_and*/
2703 0, /*nb_inplace_xor*/
2704 0, /*nb_inplace_or*/
2705 delta_divide, /* nb_floor_divide */
2706 delta_truedivide, /* nb_true_divide */
2707 0, /* nb_inplace_floor_divide */
2708 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002709};
2710
2711static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002712 PyVarObject_HEAD_INIT(NULL, 0)
2713 "datetime.timedelta", /* tp_name */
2714 sizeof(PyDateTime_Delta), /* tp_basicsize */
2715 0, /* tp_itemsize */
2716 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002717 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 0, /* tp_getattr */
2719 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002720 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002721 (reprfunc)delta_repr, /* tp_repr */
2722 &delta_as_number, /* tp_as_number */
2723 0, /* tp_as_sequence */
2724 0, /* tp_as_mapping */
2725 (hashfunc)delta_hash, /* tp_hash */
2726 0, /* tp_call */
2727 (reprfunc)delta_str, /* tp_str */
2728 PyObject_GenericGetAttr, /* tp_getattro */
2729 0, /* tp_setattro */
2730 0, /* tp_as_buffer */
2731 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2732 delta_doc, /* tp_doc */
2733 0, /* tp_traverse */
2734 0, /* tp_clear */
2735 delta_richcompare, /* tp_richcompare */
2736 0, /* tp_weaklistoffset */
2737 0, /* tp_iter */
2738 0, /* tp_iternext */
2739 delta_methods, /* tp_methods */
2740 delta_members, /* tp_members */
2741 0, /* tp_getset */
2742 0, /* tp_base */
2743 0, /* tp_dict */
2744 0, /* tp_descr_get */
2745 0, /* tp_descr_set */
2746 0, /* tp_dictoffset */
2747 0, /* tp_init */
2748 0, /* tp_alloc */
2749 delta_new, /* tp_new */
2750 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002751};
2752
2753/*
2754 * PyDateTime_Date implementation.
2755 */
2756
2757/* Accessor properties. */
2758
2759static PyObject *
2760date_year(PyDateTime_Date *self, void *unused)
2761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002762 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002763}
2764
2765static PyObject *
2766date_month(PyDateTime_Date *self, void *unused)
2767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002768 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002769}
2770
2771static PyObject *
2772date_day(PyDateTime_Date *self, void *unused)
2773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002774 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002775}
2776
2777static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002778 {"year", (getter)date_year},
2779 {"month", (getter)date_month},
2780 {"day", (getter)date_day},
2781 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002782};
2783
2784/* Constructors. */
2785
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002786static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002787
Tim Peters2a799bf2002-12-16 20:18:38 +00002788static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002789date_from_pickle(PyTypeObject *type, PyObject *state)
2790{
2791 PyDateTime_Date *me;
2792
2793 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2794 if (me != NULL) {
2795 const char *pdata = PyBytes_AS_STRING(state);
2796 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2797 me->hashcode = -1;
2798 }
2799 return (PyObject *)me;
2800}
2801
2802static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002803date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002806 int year;
2807 int month;
2808 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka1133a8c2018-12-07 16:48:21 +02002811 if (PyTuple_GET_SIZE(args) == 1) {
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002812 PyObject *state = PyTuple_GET_ITEM(args, 0);
2813 if (PyBytes_Check(state)) {
2814 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2815 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2816 {
2817 return date_from_pickle(type, state);
Victor Stinnerb37672d2018-11-22 03:37:50 +01002818 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02002819 }
2820 else if (PyUnicode_Check(state)) {
2821 if (PyUnicode_READY(state)) {
2822 return NULL;
2823 }
2824 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
2825 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
2826 {
2827 state = PyUnicode_AsLatin1String(state);
2828 if (state == NULL) {
2829 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
2830 /* More informative error message. */
2831 PyErr_SetString(PyExc_ValueError,
2832 "Failed to encode latin1 string when unpickling "
2833 "a date object. "
2834 "pickle.load(data, encoding='latin1') is assumed.");
2835 }
2836 return NULL;
2837 }
2838 self = date_from_pickle(type, state);
2839 Py_DECREF(state);
2840 return self;
2841 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002842 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002843 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2846 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 self = new_date_ex(year, month, day, type);
2848 }
2849 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002850}
2851
Tim Peters2a799bf2002-12-16 20:18:38 +00002852static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002853date_fromtimestamp(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002854{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002855 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002857
Victor Stinnere4a994d2015-03-30 01:10:14 +02002858 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002859 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002860
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002861 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002862 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002863
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002864 return new_date_subclass_ex(tm.tm_year + 1900,
2865 tm.tm_mon + 1,
2866 tm.tm_mday,
2867 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002868}
2869
2870/* Return new date from current time.
2871 * We say this is equivalent to fromtimestamp(time.time()), and the
2872 * only way to be sure of that is to *call* time.time(). That's not
2873 * generally the same as calling C's time.
2874 */
2875static PyObject *
2876date_today(PyObject *cls, PyObject *dummy)
2877{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 PyObject *time;
2879 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002880 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002882 time = time_time();
2883 if (time == NULL)
2884 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002886 /* Note well: today() is a class method, so this may not call
2887 * date.fromtimestamp. For example, it may call
2888 * datetime.fromtimestamp. That's why we need all the accuracy
2889 * time.time() delivers; if someone were gonzo about optimization,
2890 * date.today() could get away with plain C time().
2891 */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02002892 result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 Py_DECREF(time);
2894 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002895}
2896
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002897/*[clinic input]
2898@classmethod
2899datetime.date.fromtimestamp
2900
2901 timestamp: object
2902 /
2903
2904Create a date from a POSIX timestamp.
2905
2906The timestamp is a number, e.g. created via time.time(), that is interpreted
2907as local time.
2908[clinic start generated code]*/
2909
Tim Peters2a799bf2002-12-16 20:18:38 +00002910static PyObject *
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002911datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp)
2912/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00002913{
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02002914 return date_fromtimestamp((PyObject *) type, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002915}
2916
Paul Ganssle4d8c8c02019-04-27 15:39:40 -04002917/* bpo-36025: This is a wrapper for API compatibility with the public C API,
2918 * which expects a function that takes an *args tuple, whereas the argument
2919 * clinic generates code that takes METH_O.
2920 */
2921static PyObject *
2922datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args)
2923{
2924 PyObject *timestamp;
2925 PyObject *result = NULL;
2926
2927 if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, &timestamp)) {
2928 result = date_fromtimestamp(cls, timestamp);
2929 }
2930
2931 return result;
2932}
2933
Tim Peters2a799bf2002-12-16 20:18:38 +00002934/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2935 * the ordinal is out of range.
2936 */
2937static PyObject *
2938date_fromordinal(PyObject *cls, PyObject *args)
2939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002940 PyObject *result = NULL;
2941 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002943 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2944 int year;
2945 int month;
2946 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002948 if (ordinal < 1)
2949 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2950 ">= 1");
2951 else {
2952 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002953 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002954 }
2955 }
2956 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002957}
2958
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002959/* Return the new date from a string as generated by date.isoformat() */
2960static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04002961date_fromisoformat(PyObject *cls, PyObject *dtstr)
2962{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002963 assert(dtstr != NULL);
2964
2965 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04002966 PyErr_SetString(PyExc_TypeError,
2967 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002968 return NULL;
2969 }
2970
2971 Py_ssize_t len;
2972
Paul Ganssle3df85402018-10-22 12:32:52 -04002973 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04002974 if (dt_ptr == NULL) {
2975 goto invalid_string_error;
2976 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002977
2978 int year = 0, month = 0, day = 0;
2979
2980 int rv;
2981 if (len == 10) {
2982 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
Paul Ganssle3df85402018-10-22 12:32:52 -04002983 }
2984 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002985 rv = -1;
2986 }
2987
2988 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04002989 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002990 }
2991
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002992 return new_date_subclass_ex(year, month, day, cls);
Paul Ganssle096329f2018-08-23 11:06:20 -04002993
2994invalid_string_error:
Paul Ganssle3df85402018-10-22 12:32:52 -04002995 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04002996 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002997}
2998
Paul Ganssle88c09372019-04-29 09:22:03 -04002999
3000static PyObject *
3001date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw)
3002{
3003 static char *keywords[] = {
3004 "year", "week", "day", NULL
3005 };
3006
3007 int year, week, day;
3008 if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar",
3009 keywords,
3010 &year, &week, &day) == 0) {
3011 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
3012 PyErr_Format(PyExc_ValueError,
3013 "ISO calendar component out of range");
3014
3015 }
3016 return NULL;
3017 }
3018
3019 // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
3020 if (year < MINYEAR || year > MAXYEAR) {
3021 PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
3022 return NULL;
3023 }
3024
3025 if (week <= 0 || week >= 53) {
3026 int out_of_range = 1;
3027 if (week == 53) {
3028 // ISO years have 53 weeks in it on years starting with a Thursday
3029 // and on leap years starting on Wednesday
3030 int first_weekday = weekday(year, 1, 1);
3031 if (first_weekday == 3 || (first_weekday == 2 && is_leap(year))) {
3032 out_of_range = 0;
3033 }
3034 }
3035
3036 if (out_of_range) {
3037 PyErr_Format(PyExc_ValueError, "Invalid week: %d", week);
3038 return NULL;
3039 }
3040 }
3041
3042 if (day <= 0 || day >= 8) {
3043 PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])",
3044 day);
3045 return NULL;
3046 }
3047
3048 // Convert (Y, W, D) to (Y, M, D) in-place
3049 int day_1 = iso_week1_monday(year);
3050
3051 int month = week;
3052 int day_offset = (month - 1)*7 + day - 1;
3053
3054 ord_to_ymd(day_1 + day_offset, &year, &month, &day);
3055
3056 return new_date_subclass_ex(year, month, day, cls);
3057}
3058
3059
Tim Peters2a799bf2002-12-16 20:18:38 +00003060/*
3061 * Date arithmetic.
3062 */
3063
3064/* date + timedelta -> date. If arg negate is true, subtract the timedelta
3065 * instead.
3066 */
3067static PyObject *
3068add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
3069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003070 PyObject *result = NULL;
3071 int year = GET_YEAR(date);
3072 int month = GET_MONTH(date);
3073 int deltadays = GET_TD_DAYS(delta);
3074 /* C-level overflow is impossible because |deltadays| < 1e9. */
3075 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00003076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003077 if (normalize_date(&year, &month, &day) >= 0)
Paul Ganssle89427cd2019-02-04 14:42:04 -05003078 result = new_date_subclass_ex(year, month, day,
3079 (PyObject* )Py_TYPE(date));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003080 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003081}
3082
3083static PyObject *
3084date_add(PyObject *left, PyObject *right)
3085{
Brian Curtindfc80e32011-08-10 20:28:54 -05003086 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3087 Py_RETURN_NOTIMPLEMENTED;
3088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003089 if (PyDate_Check(left)) {
3090 /* date + ??? */
3091 if (PyDelta_Check(right))
3092 /* date + delta */
3093 return add_date_timedelta((PyDateTime_Date *) left,
3094 (PyDateTime_Delta *) right,
3095 0);
3096 }
3097 else {
3098 /* ??? + date
3099 * 'right' must be one of us, or we wouldn't have been called
3100 */
3101 if (PyDelta_Check(left))
3102 /* delta + date */
3103 return add_date_timedelta((PyDateTime_Date *) right,
3104 (PyDateTime_Delta *) left,
3105 0);
3106 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003107 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003108}
3109
3110static PyObject *
3111date_subtract(PyObject *left, PyObject *right)
3112{
Brian Curtindfc80e32011-08-10 20:28:54 -05003113 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3114 Py_RETURN_NOTIMPLEMENTED;
3115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003116 if (PyDate_Check(left)) {
3117 if (PyDate_Check(right)) {
3118 /* date - date */
3119 int left_ord = ymd_to_ord(GET_YEAR(left),
3120 GET_MONTH(left),
3121 GET_DAY(left));
3122 int right_ord = ymd_to_ord(GET_YEAR(right),
3123 GET_MONTH(right),
3124 GET_DAY(right));
3125 return new_delta(left_ord - right_ord, 0, 0, 0);
3126 }
3127 if (PyDelta_Check(right)) {
3128 /* date - delta */
3129 return add_date_timedelta((PyDateTime_Date *) left,
3130 (PyDateTime_Delta *) right,
3131 1);
3132 }
3133 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003134 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003135}
3136
3137
3138/* Various ways to turn a date into a string. */
3139
3140static PyObject *
3141date_repr(PyDateTime_Date *self)
3142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3144 Py_TYPE(self)->tp_name,
3145 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003146}
3147
3148static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303149date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003151 return PyUnicode_FromFormat("%04d-%02d-%02d",
3152 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003153}
3154
Tim Peterse2df5ff2003-05-02 18:39:55 +00003155/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003156static PyObject *
3157date_str(PyDateTime_Date *self)
3158{
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02003159 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
Tim Peters2a799bf2002-12-16 20:18:38 +00003160}
3161
3162
3163static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303164date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003166 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003167}
3168
3169static PyObject *
3170date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 /* This method can be inherited, and needs to call the
3173 * timetuple() method appropriate to self's class.
3174 */
3175 PyObject *result;
3176 PyObject *tuple;
3177 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003178 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003179 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003181 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3182 &format))
3183 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003184
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02003185 tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003186 if (tuple == NULL)
3187 return NULL;
3188 result = wrap_strftime((PyObject *)self, format, tuple,
3189 (PyObject *)self);
3190 Py_DECREF(tuple);
3191 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003192}
3193
Eric Smith1ba31142007-09-11 18:06:02 +00003194static PyObject *
3195date_format(PyDateTime_Date *self, PyObject *args)
3196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003197 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003199 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3200 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003202 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003203 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003204 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003205
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02003206 return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime,
3207 format);
Eric Smith1ba31142007-09-11 18:06:02 +00003208}
3209
Tim Peters2a799bf2002-12-16 20:18:38 +00003210/* ISO methods. */
3211
3212static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303213date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003218}
3219
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003220PyDoc_STRVAR(iso_calendar_date__doc__,
3221"The result of date.isocalendar() or datetime.isocalendar()\n\n\
3222This object may be accessed either as a tuple of\n\
3223 ((year, week, weekday)\n\
3224or via the object attributes as named in the above tuple.");
3225
3226typedef struct {
3227 PyTupleObject tuple;
3228} PyDateTime_IsoCalendarDate;
3229
3230static PyObject *
3231iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self)
3232{
3233 PyObject* year = PyTuple_GetItem((PyObject *)self, 0);
3234 if (year == NULL) {
3235 return NULL;
3236 }
3237 PyObject* week = PyTuple_GetItem((PyObject *)self, 1);
3238 if (week == NULL) {
3239 return NULL;
3240 }
3241 PyObject* weekday = PyTuple_GetItem((PyObject *)self, 2);
3242 if (weekday == NULL) {
3243 return NULL;
3244 }
3245
3246 return PyUnicode_FromFormat("%.200s(year=%S, week=%S, weekday=%S)",
3247 Py_TYPE(self)->tp_name, year, week, weekday);
3248}
3249
3250static PyObject *
3251iso_calendar_date_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
3252{
3253 // Construct the tuple that this reduces to
3254 PyObject * reduce_tuple = Py_BuildValue(
3255 "O((OOO))", &PyTuple_Type,
3256 PyTuple_GET_ITEM(self, 0),
3257 PyTuple_GET_ITEM(self, 1),
3258 PyTuple_GET_ITEM(self, 2)
3259 );
3260
3261 return reduce_tuple;
3262}
3263
3264static PyObject *
3265iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused)
3266{
3267 PyObject *year = PyTuple_GetItem((PyObject *)self, 0);
3268 if (year == NULL) {
3269 return NULL;
3270 }
3271 Py_INCREF(year);
3272 return year;
3273}
3274
3275static PyObject *
3276iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused)
3277{
3278 PyObject *week = PyTuple_GetItem((PyObject *)self, 1);
3279 if (week == NULL) {
3280 return NULL;
3281 }
3282 Py_INCREF(week);
3283 return week;
3284}
3285
3286static PyObject *
3287iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused)
3288{
3289 PyObject *weekday = PyTuple_GetItem((PyObject *)self, 2);
3290 if (weekday == NULL) {
3291 return NULL;
3292 }
3293 Py_INCREF(weekday);
3294 return weekday;
3295}
3296
3297static PyGetSetDef iso_calendar_date_getset[] = {
3298 {"year", (getter)iso_calendar_date_year},
3299 {"week", (getter)iso_calendar_date_week},
3300 {"weekday", (getter)iso_calendar_date_weekday},
3301 {NULL}
3302};
3303
3304static PyMethodDef iso_calendar_date_methods[] = {
3305 {"__reduce__", (PyCFunction)iso_calendar_date_reduce, METH_NOARGS,
3306 PyDoc_STR("__reduce__() -> (cls, state)")},
3307 {NULL, NULL},
3308};
3309
3310static PyTypeObject PyDateTime_IsoCalendarDateType = {
3311 PyVarObject_HEAD_INIT(NULL, 0)
3312 .tp_name = "datetime.IsoCalendarDate",
3313 .tp_basicsize = sizeof(PyDateTime_IsoCalendarDate),
3314 .tp_repr = (reprfunc) iso_calendar_date_repr,
3315 .tp_flags = Py_TPFLAGS_DEFAULT,
3316 .tp_doc = iso_calendar_date__doc__,
3317 .tp_methods = iso_calendar_date_methods,
3318 .tp_getset = iso_calendar_date_getset,
Petr Viktorin459acc52020-05-28 18:14:46 +02003319 // .tp_base = &PyTuple_Type, // filled in PyInit__datetime
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003320 .tp_new = iso_calendar_date_new,
3321};
3322
3323/*[clinic input]
3324@classmethod
3325datetime.IsoCalendarDate.__new__ as iso_calendar_date_new
3326 year: int
3327 week: int
3328 weekday: int
3329[clinic start generated code]*/
3330
3331static PyObject *
3332iso_calendar_date_new_impl(PyTypeObject *type, int year, int week,
3333 int weekday)
3334/*[clinic end generated code: output=383d33d8dc7183a2 input=4f2c663c9d19c4ee]*/
3335
3336{
3337 PyDateTime_IsoCalendarDate *self;
3338 self = (PyDateTime_IsoCalendarDate *) type->tp_alloc(type, 3);
3339 if (self == NULL) {
3340 return NULL;
3341 }
3342
3343 PyTuple_SET_ITEM(self, 0, PyLong_FromLong(year));
3344 PyTuple_SET_ITEM(self, 1, PyLong_FromLong(week));
3345 PyTuple_SET_ITEM(self, 2, PyLong_FromLong(weekday));
3346
3347 return (PyObject *)self;
3348}
3349
Tim Peters2a799bf2002-12-16 20:18:38 +00003350static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303351date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003353 int year = GET_YEAR(self);
3354 int week1_monday = iso_week1_monday(year);
3355 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3356 int week;
3357 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003359 week = divmod(today - week1_monday, 7, &day);
3360 if (week < 0) {
3361 --year;
3362 week1_monday = iso_week1_monday(year);
3363 week = divmod(today - week1_monday, 7, &day);
3364 }
3365 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3366 ++year;
3367 week = 0;
3368 }
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003369
3370 PyObject* v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType,
3371 year, week + 1, day + 1);
3372 if (v == NULL) {
3373 return NULL;
3374 }
3375 return v;
Tim Peters2a799bf2002-12-16 20:18:38 +00003376}
3377
3378/* Miscellaneous methods. */
3379
Tim Peters2a799bf2002-12-16 20:18:38 +00003380static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003381date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003383 if (PyDate_Check(other)) {
3384 int diff = memcmp(((PyDateTime_Date *)self)->data,
3385 ((PyDateTime_Date *)other)->data,
3386 _PyDateTime_DATE_DATASIZE);
3387 return diff_to_bool(diff, op);
3388 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003389 else
3390 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003391}
3392
3393static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303394date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003396 return build_struct_time(GET_YEAR(self),
3397 GET_MONTH(self),
3398 GET_DAY(self),
3399 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003400}
3401
Tim Peters12bf3392002-12-24 05:41:27 +00003402static PyObject *
3403date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003405 PyObject *clone;
3406 PyObject *tuple;
3407 int year = GET_YEAR(self);
3408 int month = GET_MONTH(self);
3409 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003411 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3412 &year, &month, &day))
3413 return NULL;
3414 tuple = Py_BuildValue("iii", year, month, day);
3415 if (tuple == NULL)
3416 return NULL;
3417 clone = date_new(Py_TYPE(self), tuple, NULL);
3418 Py_DECREF(tuple);
3419 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003420}
3421
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003422static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003423generic_hash(unsigned char *data, int len)
3424{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003425 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003426}
3427
3428
3429static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003430
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003431static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003432date_hash(PyDateTime_Date *self)
3433{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003434 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003435 self->hashcode = generic_hash(
3436 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003437 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003439 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003440}
3441
3442static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303443date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003445 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3446 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003447}
3448
3449static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303450date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003452 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003454 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003455}
3456
Tim Peters371935f2003-02-01 01:52:50 +00003457/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003458
Tim Petersb57f8f02003-02-01 02:54:15 +00003459/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003460static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003461date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003463 PyObject* field;
3464 field = PyBytes_FromStringAndSize((char*)self->data,
3465 _PyDateTime_DATE_DATASIZE);
3466 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003467}
3468
3469static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003470date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003472 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003473}
3474
3475static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003477 /* Class methods: */
Tim Hoffmanna0fd7f12018-09-24 10:39:02 +02003478 DATETIME_DATE_FROMTIMESTAMP_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00003479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003480 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3481 METH_CLASS,
3482 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3483 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003484
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003485 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3486 METH_CLASS,
3487 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3488
Paul Ganssle88c09372019-04-29 09:22:03 -04003489 {"fromisocalendar", (PyCFunction)(void(*)(void))date_fromisocalendar,
3490 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
3491 PyDoc_STR("int, int, int -> Construct a date from the ISO year, week "
3492 "number and weekday.\n\n"
3493 "This is the inverse of the date.isocalendar() function")},
3494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003495 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3496 PyDoc_STR("Current date or datetime: same as "
3497 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003499 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003501 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3502 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003503
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003504 {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003505 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003507 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3508 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003510 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3511 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003513 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04003514 PyDoc_STR("Return a named tuple containing ISO year, week number, and "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003515 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003517 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3518 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003520 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3521 PyDoc_STR("Return the day of the week represented by the date.\n"
3522 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003524 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3525 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3526 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003528 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3529 PyDoc_STR("Return the day of the week represented by the date.\n"
3530 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003531
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003532 {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003533 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003535 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3536 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003538 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003539};
3540
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003541static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003542PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003543
3544static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003545 date_add, /* nb_add */
3546 date_subtract, /* nb_subtract */
3547 0, /* nb_multiply */
3548 0, /* nb_remainder */
3549 0, /* nb_divmod */
3550 0, /* nb_power */
3551 0, /* nb_negative */
3552 0, /* nb_positive */
3553 0, /* nb_absolute */
3554 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003555};
3556
3557static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003558 PyVarObject_HEAD_INIT(NULL, 0)
3559 "datetime.date", /* tp_name */
3560 sizeof(PyDateTime_Date), /* tp_basicsize */
3561 0, /* tp_itemsize */
3562 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003563 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003564 0, /* tp_getattr */
3565 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003566 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003567 (reprfunc)date_repr, /* tp_repr */
3568 &date_as_number, /* tp_as_number */
3569 0, /* tp_as_sequence */
3570 0, /* tp_as_mapping */
3571 (hashfunc)date_hash, /* tp_hash */
3572 0, /* tp_call */
3573 (reprfunc)date_str, /* tp_str */
3574 PyObject_GenericGetAttr, /* tp_getattro */
3575 0, /* tp_setattro */
3576 0, /* tp_as_buffer */
3577 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3578 date_doc, /* tp_doc */
3579 0, /* tp_traverse */
3580 0, /* tp_clear */
3581 date_richcompare, /* tp_richcompare */
3582 0, /* tp_weaklistoffset */
3583 0, /* tp_iter */
3584 0, /* tp_iternext */
3585 date_methods, /* tp_methods */
3586 0, /* tp_members */
3587 date_getset, /* tp_getset */
3588 0, /* tp_base */
3589 0, /* tp_dict */
3590 0, /* tp_descr_get */
3591 0, /* tp_descr_set */
3592 0, /* tp_dictoffset */
3593 0, /* tp_init */
3594 0, /* tp_alloc */
3595 date_new, /* tp_new */
3596 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003597};
3598
3599/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003600 * PyDateTime_TZInfo implementation.
3601 */
3602
3603/* This is a pure abstract base class, so doesn't do anything beyond
3604 * raising NotImplemented exceptions. Real tzinfo classes need
3605 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003606 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003607 * be subclasses of this tzinfo class, which is easy and quick to check).
3608 *
3609 * Note: For reasons having to do with pickling of subclasses, we have
3610 * to allow tzinfo objects to be instantiated. This wasn't an issue
3611 * in the Python implementation (__init__() could raise NotImplementedError
3612 * there without ill effect), but doing so in the C implementation hit a
3613 * brick wall.
3614 */
3615
3616static PyObject *
3617tzinfo_nogo(const char* methodname)
3618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003619 PyErr_Format(PyExc_NotImplementedError,
3620 "a tzinfo subclass must implement %s()",
3621 methodname);
3622 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003623}
3624
3625/* Methods. A subclass must implement these. */
3626
Tim Peters52dcce22003-01-23 16:36:11 +00003627static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003628tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003630 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003631}
3632
Tim Peters52dcce22003-01-23 16:36:11 +00003633static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003634tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3635{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003636 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003637}
3638
Tim Peters52dcce22003-01-23 16:36:11 +00003639static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003640tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003642 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003643}
3644
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003645
3646static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3647 PyDateTime_Delta *delta,
3648 int factor);
3649static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3650static PyObject *datetime_dst(PyObject *self, PyObject *);
3651
Tim Peters52dcce22003-01-23 16:36:11 +00003652static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003653tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003654{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003655 PyObject *result = NULL;
3656 PyObject *off = NULL, *dst = NULL;
3657 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003658
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003659 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003660 PyErr_SetString(PyExc_TypeError,
3661 "fromutc: argument must be a datetime");
3662 return NULL;
3663 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003664 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003665 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3666 "is not self");
3667 return NULL;
3668 }
Tim Peters52dcce22003-01-23 16:36:11 +00003669
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003670 off = datetime_utcoffset(dt, NULL);
3671 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003672 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003673 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003674 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3675 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003676 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003677 }
Tim Peters52dcce22003-01-23 16:36:11 +00003678
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003679 dst = datetime_dst(dt, NULL);
3680 if (dst == NULL)
3681 goto Fail;
3682 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003683 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3684 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003685 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003686 }
Tim Peters52dcce22003-01-23 16:36:11 +00003687
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003688 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3689 if (delta == NULL)
3690 goto Fail;
3691 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003692 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003693 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003694
3695 Py_DECREF(dst);
3696 dst = call_dst(GET_DT_TZINFO(dt), result);
3697 if (dst == NULL)
3698 goto Fail;
3699 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003700 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003701 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003702 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003703 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003704 if (result == NULL)
3705 goto Fail;
3706 }
3707 Py_DECREF(delta);
3708 Py_DECREF(dst);
3709 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003710 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003711
3712Inconsistent:
Serhiy Storchaka34fd4c22018-11-05 16:20:25 +02003713 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003714 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003715
Leo Ariasc3d95082018-02-03 18:36:10 -06003716 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003717Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003718 Py_XDECREF(off);
3719 Py_XDECREF(dst);
3720 Py_XDECREF(delta);
3721 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003722 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003723}
3724
Tim Peters2a799bf2002-12-16 20:18:38 +00003725/*
3726 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003727 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003728 */
3729
Guido van Rossum177e41a2003-01-30 22:06:23 +00003730static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303731tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003732{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003733 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003734 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003735 _Py_IDENTIFIER(__getinitargs__);
3736 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003737
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003738 if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) {
3739 return NULL;
3740 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003741 if (getinitargs != NULL) {
Victor Stinner2ff58a22019-06-17 14:27:23 +02003742 args = PyObject_CallNoArgs(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003743 Py_DECREF(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003744 }
3745 else {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003746 args = PyTuple_New(0);
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003747 }
3748 if (args == NULL) {
3749 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003750 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003751
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03003752 if (_PyObject_LookupAttrId(self, &PyId___getstate__, &getstate) < 0) {
3753 Py_DECREF(args);
3754 return NULL;
3755 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003756 if (getstate != NULL) {
Victor Stinner2ff58a22019-06-17 14:27:23 +02003757 state = PyObject_CallNoArgs(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003758 Py_DECREF(getstate);
3759 if (state == NULL) {
3760 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003761 return NULL;
3762 }
3763 }
3764 else {
3765 PyObject **dictptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003766 state = Py_None;
3767 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003768 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003769 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003770 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003771 Py_INCREF(state);
3772 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003774 if (state == Py_None) {
3775 Py_DECREF(state);
3776 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3777 }
3778 else
3779 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003780}
Tim Peters2a799bf2002-12-16 20:18:38 +00003781
3782static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003784 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3785 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003787 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003788 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3789 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003791 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003792 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003794 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003795 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003796
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303797 {"__reduce__", tzinfo_reduce, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003798 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003800 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003801};
3802
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003803static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003804PyDoc_STR("Abstract base class for time zone info objects.");
3805
Neal Norwitz227b5332006-03-22 09:28:35 +00003806static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003807 PyVarObject_HEAD_INIT(NULL, 0)
3808 "datetime.tzinfo", /* tp_name */
3809 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3810 0, /* tp_itemsize */
3811 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003812 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003813 0, /* tp_getattr */
3814 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003815 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003816 0, /* tp_repr */
3817 0, /* tp_as_number */
3818 0, /* tp_as_sequence */
3819 0, /* tp_as_mapping */
3820 0, /* tp_hash */
3821 0, /* tp_call */
3822 0, /* tp_str */
3823 PyObject_GenericGetAttr, /* tp_getattro */
3824 0, /* tp_setattro */
3825 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003826 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003827 tzinfo_doc, /* tp_doc */
3828 0, /* tp_traverse */
3829 0, /* tp_clear */
3830 0, /* tp_richcompare */
3831 0, /* tp_weaklistoffset */
3832 0, /* tp_iter */
3833 0, /* tp_iternext */
3834 tzinfo_methods, /* tp_methods */
3835 0, /* tp_members */
3836 0, /* tp_getset */
3837 0, /* tp_base */
3838 0, /* tp_dict */
3839 0, /* tp_descr_get */
3840 0, /* tp_descr_set */
3841 0, /* tp_dictoffset */
3842 0, /* tp_init */
3843 0, /* tp_alloc */
3844 PyType_GenericNew, /* tp_new */
3845 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003846};
3847
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003848static char *timezone_kws[] = {"offset", "name", NULL};
3849
3850static PyObject *
3851timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3852{
3853 PyObject *offset;
3854 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003855 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3856 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003857 return new_timezone(offset, name);
3858
3859 return NULL;
3860}
3861
3862static void
3863timezone_dealloc(PyDateTime_TimeZone *self)
3864{
3865 Py_CLEAR(self->offset);
3866 Py_CLEAR(self->name);
3867 Py_TYPE(self)->tp_free((PyObject *)self);
3868}
3869
3870static PyObject *
3871timezone_richcompare(PyDateTime_TimeZone *self,
3872 PyDateTime_TimeZone *other, int op)
3873{
Brian Curtindfc80e32011-08-10 20:28:54 -05003874 if (op != Py_EQ && op != Py_NE)
3875 Py_RETURN_NOTIMPLEMENTED;
Pablo Galindo4be11c02019-08-22 20:24:25 +01003876 if (!PyTimezone_Check(other)) {
Serhiy Storchaka17e52642019-08-04 12:38:46 +03003877 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003878 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003879 return delta_richcompare(self->offset, other->offset, op);
3880}
3881
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003882static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003883timezone_hash(PyDateTime_TimeZone *self)
3884{
3885 return delta_hash((PyDateTime_Delta *)self->offset);
3886}
3887
3888/* Check argument type passed to tzname, utcoffset, or dst methods.
3889 Returns 0 for good argument. Returns -1 and sets exception info
3890 otherwise.
3891 */
3892static int
3893_timezone_check_argument(PyObject *dt, const char *meth)
3894{
3895 if (dt == Py_None || PyDateTime_Check(dt))
3896 return 0;
3897 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3898 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3899 return -1;
3900}
3901
3902static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003903timezone_repr(PyDateTime_TimeZone *self)
3904{
3905 /* Note that although timezone is not subclassable, it is convenient
3906 to use Py_TYPE(self)->tp_name here. */
3907 const char *type_name = Py_TYPE(self)->tp_name;
3908
3909 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3910 return PyUnicode_FromFormat("%s.utc", type_name);
3911
3912 if (self->name == NULL)
3913 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3914
3915 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3916 self->name);
3917}
3918
3919
3920static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003921timezone_str(PyDateTime_TimeZone *self)
3922{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003923 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003924 PyObject *offset;
3925 char sign;
3926
3927 if (self->name != NULL) {
3928 Py_INCREF(self->name);
3929 return self->name;
3930 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003931 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003932 (GET_TD_DAYS(self->offset) == 0 &&
3933 GET_TD_SECONDS(self->offset) == 0 &&
3934 GET_TD_MICROSECONDS(self->offset) == 0))
3935 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003936 /* Offset is normalized, so it is negative if days < 0 */
3937 if (GET_TD_DAYS(self->offset) < 0) {
3938 sign = '-';
3939 offset = delta_negative((PyDateTime_Delta *)self->offset);
3940 if (offset == NULL)
3941 return NULL;
3942 }
3943 else {
3944 sign = '+';
3945 offset = self->offset;
3946 Py_INCREF(offset);
3947 }
3948 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003949 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003950 seconds = GET_TD_SECONDS(offset);
3951 Py_DECREF(offset);
3952 minutes = divmod(seconds, 60, &seconds);
3953 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003954 if (microseconds != 0) {
3955 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3956 sign, hours, minutes,
3957 seconds, microseconds);
3958 }
3959 if (seconds != 0) {
3960 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3961 sign, hours, minutes, seconds);
3962 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003963 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003964}
3965
3966static PyObject *
3967timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3968{
3969 if (_timezone_check_argument(dt, "tzname") == -1)
3970 return NULL;
3971
3972 return timezone_str(self);
3973}
3974
3975static PyObject *
3976timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3977{
3978 if (_timezone_check_argument(dt, "utcoffset") == -1)
3979 return NULL;
3980
3981 Py_INCREF(self->offset);
3982 return self->offset;
3983}
3984
3985static PyObject *
3986timezone_dst(PyObject *self, PyObject *dt)
3987{
3988 if (_timezone_check_argument(dt, "dst") == -1)
3989 return NULL;
3990
3991 Py_RETURN_NONE;
3992}
3993
3994static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003995timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3996{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003997 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003998 PyErr_SetString(PyExc_TypeError,
3999 "fromutc: argument must be a datetime");
4000 return NULL;
4001 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004002 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004003 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
4004 "is not self");
4005 return NULL;
4006 }
4007
4008 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
4009}
4010
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00004011static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304012timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00004013{
4014 if (self->name == NULL)
4015 return Py_BuildValue("(O)", self->offset);
4016 return Py_BuildValue("(OO)", self->offset, self->name);
4017}
4018
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004019static PyMethodDef timezone_methods[] = {
4020 {"tzname", (PyCFunction)timezone_tzname, METH_O,
4021 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00004022 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004023
4024 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00004025 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004026
4027 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00004028 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004029
4030 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
4031 PyDoc_STR("datetime in UTC -> datetime in local time.")},
4032
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00004033 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
4034 PyDoc_STR("pickle support")},
4035
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004036 {NULL, NULL}
4037};
4038
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004039static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004040PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
4041
4042static PyTypeObject PyDateTime_TimeZoneType = {
4043 PyVarObject_HEAD_INIT(NULL, 0)
4044 "datetime.timezone", /* tp_name */
4045 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
4046 0, /* tp_itemsize */
4047 (destructor)timezone_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004048 0, /* tp_vectorcall_offset */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004049 0, /* tp_getattr */
4050 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004051 0, /* tp_as_async */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00004052 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004053 0, /* tp_as_number */
4054 0, /* tp_as_sequence */
4055 0, /* tp_as_mapping */
4056 (hashfunc)timezone_hash, /* tp_hash */
4057 0, /* tp_call */
4058 (reprfunc)timezone_str, /* tp_str */
4059 0, /* tp_getattro */
4060 0, /* tp_setattro */
4061 0, /* tp_as_buffer */
4062 Py_TPFLAGS_DEFAULT, /* tp_flags */
4063 timezone_doc, /* tp_doc */
4064 0, /* tp_traverse */
4065 0, /* tp_clear */
4066 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
4067 0, /* tp_weaklistoffset */
4068 0, /* tp_iter */
4069 0, /* tp_iternext */
4070 timezone_methods, /* tp_methods */
4071 0, /* tp_members */
4072 0, /* tp_getset */
Petr Viktorin459acc52020-05-28 18:14:46 +02004073 0, /* tp_base; filled in PyInit__datetime */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00004074 0, /* tp_dict */
4075 0, /* tp_descr_get */
4076 0, /* tp_descr_set */
4077 0, /* tp_dictoffset */
4078 0, /* tp_init */
4079 0, /* tp_alloc */
4080 timezone_new, /* tp_new */
4081};
4082
Tim Peters2a799bf2002-12-16 20:18:38 +00004083/*
Tim Peters37f39822003-01-10 03:49:02 +00004084 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004085 */
4086
Tim Peters37f39822003-01-10 03:49:02 +00004087/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00004088 */
4089
4090static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004091time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004093 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004094}
4095
Tim Peters37f39822003-01-10 03:49:02 +00004096static PyObject *
4097time_minute(PyDateTime_Time *self, void *unused)
4098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00004100}
4101
4102/* The name time_second conflicted with some platform header file. */
4103static PyObject *
4104py_time_second(PyDateTime_Time *self, void *unused)
4105{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004106 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00004107}
4108
4109static PyObject *
4110time_microsecond(PyDateTime_Time *self, void *unused)
4111{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004112 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00004113}
4114
4115static PyObject *
4116time_tzinfo(PyDateTime_Time *self, void *unused)
4117{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004118 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4119 Py_INCREF(result);
4120 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004121}
4122
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004123static PyObject *
4124time_fold(PyDateTime_Time *self, void *unused)
4125{
4126 return PyLong_FromLong(TIME_GET_FOLD(self));
4127}
4128
Tim Peters37f39822003-01-10 03:49:02 +00004129static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 {"hour", (getter)time_hour},
4131 {"minute", (getter)time_minute},
4132 {"second", (getter)py_time_second},
4133 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004134 {"tzinfo", (getter)time_tzinfo},
4135 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004136 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004137};
4138
4139/*
4140 * Constructors.
4141 */
4142
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004143static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004144 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00004145
Tim Peters2a799bf2002-12-16 20:18:38 +00004146static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004147time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4148{
4149 PyDateTime_Time *me;
4150 char aware = (char)(tzinfo != Py_None);
4151
4152 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4153 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4154 return NULL;
4155 }
4156
4157 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
4158 if (me != NULL) {
4159 const char *pdata = PyBytes_AS_STRING(state);
4160
4161 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
4162 me->hashcode = -1;
4163 me->hastzinfo = aware;
4164 if (aware) {
4165 Py_INCREF(tzinfo);
4166 me->tzinfo = tzinfo;
4167 }
4168 if (pdata[0] & (1 << 7)) {
4169 me->data[0] -= 128;
4170 me->fold = 1;
4171 }
4172 else {
4173 me->fold = 0;
4174 }
4175 }
4176 return (PyObject *)me;
4177}
4178
4179static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004180time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004182 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 int hour = 0;
4184 int minute = 0;
4185 int second = 0;
4186 int usecond = 0;
4187 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004188 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004190 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004191 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4192 PyObject *state = PyTuple_GET_ITEM(args, 0);
4193 if (PyTuple_GET_SIZE(args) == 2) {
4194 tzinfo = PyTuple_GET_ITEM(args, 1);
4195 }
4196 if (PyBytes_Check(state)) {
4197 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
4198 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
4199 {
4200 return time_from_pickle(type, state, tzinfo);
4201 }
4202 }
4203 else if (PyUnicode_Check(state)) {
4204 if (PyUnicode_READY(state)) {
4205 return NULL;
4206 }
4207 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
Justin Blanchard122376d2019-08-29 03:36:15 -04004208 (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24)
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004209 {
4210 state = PyUnicode_AsLatin1String(state);
4211 if (state == NULL) {
4212 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4213 /* More informative error message. */
4214 PyErr_SetString(PyExc_ValueError,
4215 "Failed to encode latin1 string when unpickling "
4216 "a time object. "
4217 "pickle.load(data, encoding='latin1') is assumed.");
4218 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004219 return NULL;
4220 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004221 self = time_from_pickle(type, state, tzinfo);
4222 Py_DECREF(state);
4223 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004224 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004225 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004226 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004227 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004228
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004229 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004230 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004231 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004232 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4233 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 }
4235 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004236}
4237
4238/*
4239 * Destructor.
4240 */
4241
4242static void
Tim Peters37f39822003-01-10 03:49:02 +00004243time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004245 if (HASTZINFO(self)) {
4246 Py_XDECREF(self->tzinfo);
4247 }
4248 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004249}
4250
4251/*
Tim Peters855fe882002-12-22 03:43:39 +00004252 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004253 */
4254
Tim Peters2a799bf2002-12-16 20:18:38 +00004255/* These are all METH_NOARGS, so don't need to check the arglist. */
4256static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004257time_utcoffset(PyObject *self, PyObject *unused) {
4258 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004259}
4260
4261static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004262time_dst(PyObject *self, PyObject *unused) {
4263 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004264}
4265
4266static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004267time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004268 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004269}
4270
4271/*
Tim Peters37f39822003-01-10 03:49:02 +00004272 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004273 */
4274
4275static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004276time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004277{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004278 const char *type_name = Py_TYPE(self)->tp_name;
4279 int h = TIME_GET_HOUR(self);
4280 int m = TIME_GET_MINUTE(self);
4281 int s = TIME_GET_SECOND(self);
4282 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004283 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004284 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004286 if (us)
4287 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4288 type_name, h, m, s, us);
4289 else if (s)
4290 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4291 type_name, h, m, s);
4292 else
4293 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4294 if (result != NULL && HASTZINFO(self))
4295 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004296 if (result != NULL && fold)
4297 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004298 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004299}
4300
Tim Peters37f39822003-01-10 03:49:02 +00004301static PyObject *
4302time_str(PyDateTime_Time *self)
4303{
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02004304 return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
Tim Peters37f39822003-01-10 03:49:02 +00004305}
Tim Peters2a799bf2002-12-16 20:18:38 +00004306
4307static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004308time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004310 char buf[100];
Andy Lesterc3fa6342020-02-24 00:40:43 -06004311 const char *timespec = NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004312 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004313 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004314 int us = TIME_GET_MICROSECOND(self);
Andy Lesterc3fa6342020-02-24 00:40:43 -06004315 static const char *specs[][2] = {
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004316 {"hours", "%02d"},
4317 {"minutes", "%02d:%02d"},
4318 {"seconds", "%02d:%02d:%02d"},
4319 {"milliseconds", "%02d:%02d:%02d.%03d"},
4320 {"microseconds", "%02d:%02d:%02d.%06d"},
4321 };
4322 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004323
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004324 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4325 return NULL;
4326
4327 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4328 if (us == 0) {
4329 /* seconds */
4330 given_spec = 2;
4331 }
4332 else {
4333 /* microseconds */
4334 given_spec = 4;
4335 }
4336 }
4337 else {
4338 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4339 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4340 if (given_spec == 3) {
4341 /* milliseconds */
4342 us = us / 1000;
4343 }
4344 break;
4345 }
4346 }
4347 }
4348
4349 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4350 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4351 return NULL;
4352 }
4353 else {
4354 result = PyUnicode_FromFormat(specs[given_spec][1],
4355 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4356 TIME_GET_SECOND(self), us);
4357 }
Tim Peters37f39822003-01-10 03:49:02 +00004358
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004359 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004360 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004362 /* We need to append the UTC offset. */
4363 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4364 Py_None) < 0) {
4365 Py_DECREF(result);
4366 return NULL;
4367 }
4368 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4369 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004370}
4371
Tim Peters37f39822003-01-10 03:49:02 +00004372static PyObject *
4373time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004375 PyObject *result;
4376 PyObject *tuple;
4377 PyObject *format;
4378 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004380 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4381 &format))
4382 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 /* Python's strftime does insane things with the year part of the
4385 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004386 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004387 */
4388 tuple = Py_BuildValue("iiiiiiiii",
4389 1900, 1, 1, /* year, month, day */
4390 TIME_GET_HOUR(self),
4391 TIME_GET_MINUTE(self),
4392 TIME_GET_SECOND(self),
4393 0, 1, -1); /* weekday, daynum, dst */
4394 if (tuple == NULL)
4395 return NULL;
4396 assert(PyTuple_Size(tuple) == 9);
4397 result = wrap_strftime((PyObject *)self, format, tuple,
4398 Py_None);
4399 Py_DECREF(tuple);
4400 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004401}
Tim Peters2a799bf2002-12-16 20:18:38 +00004402
4403/*
4404 * Miscellaneous methods.
4405 */
4406
Tim Peters37f39822003-01-10 03:49:02 +00004407static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004408time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004409{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004410 PyObject *result = NULL;
4411 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004412 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004413
Brian Curtindfc80e32011-08-10 20:28:54 -05004414 if (! PyTime_Check(other))
4415 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004416
4417 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004418 diff = memcmp(((PyDateTime_Time *)self)->data,
4419 ((PyDateTime_Time *)other)->data,
4420 _PyDateTime_TIME_DATASIZE);
4421 return diff_to_bool(diff, op);
4422 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004423 offset1 = time_utcoffset(self, NULL);
4424 if (offset1 == NULL)
4425 return NULL;
4426 offset2 = time_utcoffset(other, NULL);
4427 if (offset2 == NULL)
4428 goto done;
4429 /* If they're both naive, or both aware and have the same offsets,
4430 * we get off cheap. Note that if they're both naive, offset1 ==
4431 * offset2 == Py_None at this point.
4432 */
4433 if ((offset1 == offset2) ||
4434 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4435 delta_cmp(offset1, offset2) == 0)) {
4436 diff = memcmp(((PyDateTime_Time *)self)->data,
4437 ((PyDateTime_Time *)other)->data,
4438 _PyDateTime_TIME_DATASIZE);
4439 result = diff_to_bool(diff, op);
4440 }
4441 /* The hard case: both aware with different UTC offsets */
4442 else if (offset1 != Py_None && offset2 != Py_None) {
4443 int offsecs1, offsecs2;
4444 assert(offset1 != offset2); /* else last "if" handled it */
4445 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4446 TIME_GET_MINUTE(self) * 60 +
4447 TIME_GET_SECOND(self) -
4448 GET_TD_DAYS(offset1) * 86400 -
4449 GET_TD_SECONDS(offset1);
4450 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4451 TIME_GET_MINUTE(other) * 60 +
4452 TIME_GET_SECOND(other) -
4453 GET_TD_DAYS(offset2) * 86400 -
4454 GET_TD_SECONDS(offset2);
4455 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004456 if (diff == 0)
4457 diff = TIME_GET_MICROSECOND(self) -
4458 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004459 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004460 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004461 else if (op == Py_EQ) {
4462 result = Py_False;
4463 Py_INCREF(result);
4464 }
4465 else if (op == Py_NE) {
4466 result = Py_True;
4467 Py_INCREF(result);
4468 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004469 else {
4470 PyErr_SetString(PyExc_TypeError,
4471 "can't compare offset-naive and "
4472 "offset-aware times");
4473 }
4474 done:
4475 Py_DECREF(offset1);
4476 Py_XDECREF(offset2);
4477 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004478}
4479
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004480static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004481time_hash(PyDateTime_Time *self)
4482{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004483 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004484 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004485 if (TIME_GET_FOLD(self)) {
4486 self0 = new_time_ex2(TIME_GET_HOUR(self),
4487 TIME_GET_MINUTE(self),
4488 TIME_GET_SECOND(self),
4489 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004490 HASTZINFO(self) ? self->tzinfo : Py_None,
4491 0, Py_TYPE(self));
4492 if (self0 == NULL)
4493 return -1;
4494 }
4495 else {
4496 self0 = (PyObject *)self;
4497 Py_INCREF(self0);
4498 }
4499 offset = time_utcoffset(self0, NULL);
4500 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004501
4502 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004503 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004505 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004506 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004507 self->hashcode = generic_hash(
4508 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004509 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004510 PyObject *temp1, *temp2;
4511 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004512 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004513 seconds = TIME_GET_HOUR(self) * 3600 +
4514 TIME_GET_MINUTE(self) * 60 +
4515 TIME_GET_SECOND(self);
4516 microseconds = TIME_GET_MICROSECOND(self);
4517 temp1 = new_delta(0, seconds, microseconds, 1);
4518 if (temp1 == NULL) {
4519 Py_DECREF(offset);
4520 return -1;
4521 }
4522 temp2 = delta_subtract(temp1, offset);
4523 Py_DECREF(temp1);
4524 if (temp2 == NULL) {
4525 Py_DECREF(offset);
4526 return -1;
4527 }
4528 self->hashcode = PyObject_Hash(temp2);
4529 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004530 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004531 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004532 }
4533 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004534}
Tim Peters2a799bf2002-12-16 20:18:38 +00004535
Tim Peters12bf3392002-12-24 05:41:27 +00004536static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004537time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004539 PyObject *clone;
4540 PyObject *tuple;
4541 int hh = TIME_GET_HOUR(self);
4542 int mm = TIME_GET_MINUTE(self);
4543 int ss = TIME_GET_SECOND(self);
4544 int us = TIME_GET_MICROSECOND(self);
4545 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004546 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004547
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004548 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004549 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004550 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004551 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004552 if (fold != 0 && fold != 1) {
4553 PyErr_SetString(PyExc_ValueError,
4554 "fold must be either 0 or 1");
4555 return NULL;
4556 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004557 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4558 if (tuple == NULL)
4559 return NULL;
4560 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004561 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004562 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004563 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004564 Py_DECREF(tuple);
4565 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004566}
4567
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004568static PyObject *
4569time_fromisoformat(PyObject *cls, PyObject *tstr) {
4570 assert(tstr != NULL);
4571
4572 if (!PyUnicode_Check(tstr)) {
4573 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4574 return NULL;
4575 }
4576
4577 Py_ssize_t len;
4578 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4579
Paul Ganssle096329f2018-08-23 11:06:20 -04004580 if (p == NULL) {
4581 goto invalid_string_error;
4582 }
4583
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004584 int hour = 0, minute = 0, second = 0, microsecond = 0;
4585 int tzoffset, tzimicrosecond = 0;
4586 int rv = parse_isoformat_time(p, len,
4587 &hour, &minute, &second, &microsecond,
4588 &tzoffset, &tzimicrosecond);
4589
4590 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04004591 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004592 }
4593
4594 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4595 tzimicrosecond);
4596
4597 if (tzinfo == NULL) {
4598 return NULL;
4599 }
4600
4601 PyObject *t;
4602 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4603 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4604 } else {
4605 t = PyObject_CallFunction(cls, "iiiiO",
4606 hour, minute, second, microsecond, tzinfo);
4607 }
4608
4609 Py_DECREF(tzinfo);
4610 return t;
Paul Ganssle096329f2018-08-23 11:06:20 -04004611
4612invalid_string_error:
4613 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4614 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004615}
4616
4617
Tim Peters371935f2003-02-01 01:52:50 +00004618/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004619
Tim Peters33e0f382003-01-10 02:05:14 +00004620/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004621 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4622 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004623 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004624 */
4625static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004626time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004628 PyObject *basestate;
4629 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 basestate = PyBytes_FromStringAndSize((char *)self->data,
4632 _PyDateTime_TIME_DATASIZE);
4633 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004634 if (proto > 3 && TIME_GET_FOLD(self))
4635 /* Set the first bit of the first byte */
4636 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004637 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4638 result = PyTuple_Pack(1, basestate);
4639 else
4640 result = PyTuple_Pack(2, basestate, self->tzinfo);
4641 Py_DECREF(basestate);
4642 }
4643 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004644}
4645
4646static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004647time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004648{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004649 int proto;
4650 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004651 return NULL;
4652
4653 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004654}
4655
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004656static PyObject *
4657time_reduce(PyDateTime_Time *self, PyObject *arg)
4658{
4659 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4660}
4661
Tim Peters37f39822003-01-10 03:49:02 +00004662static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004663
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004664 {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS,
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004665 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4666 "[+HH:MM].\n\n"
Ram Rachum52301312020-10-03 13:43:47 +03004667 "The optional argument timespec specifies the number "
4668 "of additional terms\nof the time to include. Valid "
4669 "options are 'auto', 'hours', 'minutes',\n'seconds', "
4670 "'milliseconds' and 'microseconds'.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004671
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004672 {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004673 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004675 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4676 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004678 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4679 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4682 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004684 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4685 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004686
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004687 {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004688 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004689
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004690 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4691 PyDoc_STR("string -> time from time.isoformat() output")},
4692
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004693 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004694 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004695
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004696 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4697 PyDoc_STR("__reduce__() -> (cls, state)")},
4698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004699 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004700};
4701
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004702static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004703PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4704\n\
4705All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004706a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004707
Neal Norwitz227b5332006-03-22 09:28:35 +00004708static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004709 PyVarObject_HEAD_INIT(NULL, 0)
4710 "datetime.time", /* tp_name */
4711 sizeof(PyDateTime_Time), /* tp_basicsize */
4712 0, /* tp_itemsize */
4713 (destructor)time_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004714 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004715 0, /* tp_getattr */
4716 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004717 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004718 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004719 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004720 0, /* tp_as_sequence */
4721 0, /* tp_as_mapping */
4722 (hashfunc)time_hash, /* tp_hash */
4723 0, /* tp_call */
4724 (reprfunc)time_str, /* tp_str */
4725 PyObject_GenericGetAttr, /* tp_getattro */
4726 0, /* tp_setattro */
4727 0, /* tp_as_buffer */
4728 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4729 time_doc, /* tp_doc */
4730 0, /* tp_traverse */
4731 0, /* tp_clear */
4732 time_richcompare, /* tp_richcompare */
4733 0, /* tp_weaklistoffset */
4734 0, /* tp_iter */
4735 0, /* tp_iternext */
4736 time_methods, /* tp_methods */
4737 0, /* tp_members */
4738 time_getset, /* tp_getset */
4739 0, /* tp_base */
4740 0, /* tp_dict */
4741 0, /* tp_descr_get */
4742 0, /* tp_descr_set */
4743 0, /* tp_dictoffset */
4744 0, /* tp_init */
4745 time_alloc, /* tp_alloc */
4746 time_new, /* tp_new */
4747 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004748};
4749
4750/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004751 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004752 */
4753
Tim Petersa9bc1682003-01-11 03:39:11 +00004754/* Accessor properties. Properties for day, month, and year are inherited
4755 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004756 */
4757
4758static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004759datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004761 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004762}
4763
Tim Petersa9bc1682003-01-11 03:39:11 +00004764static PyObject *
4765datetime_minute(PyDateTime_DateTime *self, void *unused)
4766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004767 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004768}
4769
4770static PyObject *
4771datetime_second(PyDateTime_DateTime *self, void *unused)
4772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004773 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004774}
4775
4776static PyObject *
4777datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004779 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004780}
4781
4782static PyObject *
4783datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4784{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004785 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4786 Py_INCREF(result);
4787 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004788}
4789
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004790static PyObject *
4791datetime_fold(PyDateTime_DateTime *self, void *unused)
4792{
4793 return PyLong_FromLong(DATE_GET_FOLD(self));
4794}
4795
Tim Petersa9bc1682003-01-11 03:39:11 +00004796static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004797 {"hour", (getter)datetime_hour},
4798 {"minute", (getter)datetime_minute},
4799 {"second", (getter)datetime_second},
4800 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004801 {"tzinfo", (getter)datetime_tzinfo},
4802 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004803 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004804};
4805
4806/*
4807 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004808 */
4809
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004810static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004811 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004812 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004813};
4814
Tim Peters2a799bf2002-12-16 20:18:38 +00004815static PyObject *
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004816datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4817{
4818 PyDateTime_DateTime *me;
4819 char aware = (char)(tzinfo != Py_None);
4820
4821 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4822 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4823 return NULL;
4824 }
4825
4826 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4827 if (me != NULL) {
4828 const char *pdata = PyBytes_AS_STRING(state);
4829
4830 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4831 me->hashcode = -1;
4832 me->hastzinfo = aware;
4833 if (aware) {
4834 Py_INCREF(tzinfo);
4835 me->tzinfo = tzinfo;
4836 }
4837 if (pdata[2] & (1 << 7)) {
4838 me->data[2] -= 128;
4839 me->fold = 1;
4840 }
4841 else {
4842 me->fold = 0;
4843 }
4844 }
4845 return (PyObject *)me;
4846}
4847
4848static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004849datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004851 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004852 int year;
4853 int month;
4854 int day;
4855 int hour = 0;
4856 int minute = 0;
4857 int second = 0;
4858 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004859 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004860 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004862 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004863 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4864 PyObject *state = PyTuple_GET_ITEM(args, 0);
4865 if (PyTuple_GET_SIZE(args) == 2) {
4866 tzinfo = PyTuple_GET_ITEM(args, 1);
4867 }
4868 if (PyBytes_Check(state)) {
4869 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4870 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4871 {
4872 return datetime_from_pickle(type, state, tzinfo);
4873 }
4874 }
4875 else if (PyUnicode_Check(state)) {
4876 if (PyUnicode_READY(state)) {
4877 return NULL;
4878 }
4879 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4880 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4881 {
4882 state = PyUnicode_AsLatin1String(state);
4883 if (state == NULL) {
4884 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4885 /* More informative error message. */
4886 PyErr_SetString(PyExc_ValueError,
4887 "Failed to encode latin1 string when unpickling "
4888 "a datetime object. "
4889 "pickle.load(data, encoding='latin1') is assumed.");
4890 }
Victor Stinnerb37672d2018-11-22 03:37:50 +01004891 return NULL;
4892 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004893 self = datetime_from_pickle(type, state, tzinfo);
4894 Py_DECREF(state);
4895 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004896 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004897 }
Serhiy Storchaka8452ca12018-12-07 13:42:10 +02004898 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004899 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004900
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004901 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004902 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004903 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004904 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004905 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004906 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004907 }
4908 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004909}
4910
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004911/* TM_FUNC is the shared type of _PyTime_localtime() and
4912 * _PyTime_gmtime(). */
4913typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004914
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004915/* As of version 2015f max fold in IANA database is
4916 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004917static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004918/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004919static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004920
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004921static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004922utc_to_seconds(int year, int month, int day,
4923 int hour, int minute, int second)
4924{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004925 long long ordinal;
4926
4927 /* ymd_to_ord() doesn't support year <= 0 */
4928 if (year < MINYEAR || year > MAXYEAR) {
4929 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4930 return -1;
4931 }
4932
4933 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004934 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4935}
4936
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004937static long long
4938local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004939{
4940 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004941 time_t t;
4942 u -= epoch;
4943 t = u;
4944 if (t != u) {
4945 PyErr_SetString(PyExc_OverflowError,
4946 "timestamp out of range for platform time_t");
4947 return -1;
4948 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004949 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004950 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004951 return utc_to_seconds(local_time.tm_year + 1900,
4952 local_time.tm_mon + 1,
4953 local_time.tm_mday,
4954 local_time.tm_hour,
4955 local_time.tm_min,
4956 local_time.tm_sec);
4957}
4958
Tim Petersa9bc1682003-01-11 03:39:11 +00004959/* Internal helper.
4960 * Build datetime from a time_t and a distinct count of microseconds.
4961 * Pass localtime or gmtime for f, to control the interpretation of timet.
4962 */
4963static PyObject *
4964datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004965 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004966{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004967 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004968 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004969
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004970 if (f(timet, &tm) != 0)
4971 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004972
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004973 year = tm.tm_year + 1900;
4974 month = tm.tm_mon + 1;
4975 day = tm.tm_mday;
4976 hour = tm.tm_hour;
4977 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004978 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004979 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004980 * except to the extent that passing them on to the datetime
4981 * constructor would raise ValueError for a reason that
4982 * made no sense to the user.
4983 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004984 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004985
Victor Stinnerb67f0962017-02-10 10:34:02 +01004986 /* local timezone requires to compute fold */
Ammar Askar96d1e692018-07-25 09:54:58 -07004987 if (tzinfo == Py_None && f == _PyTime_localtime
4988 /* On Windows, passing a negative value to local results
4989 * in an OSError because localtime_s on Windows does
4990 * not support negative timestamps. Unfortunately this
4991 * means that fold detection for time values between
4992 * 0 and max_fold_seconds will result in an identical
4993 * error since we subtract max_fold_seconds to detect a
4994 * fold. However, since we know there haven't been any
4995 * folds in the interval [0, max_fold_seconds) in any
4996 * timezone, we can hackily just forego fold detection
4997 * for this time range.
4998 */
4999#ifdef MS_WINDOWS
5000 && (timet - max_fold_seconds > 0)
5001#endif
5002 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005003 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005004
5005 result_seconds = utc_to_seconds(year, month, day,
5006 hour, minute, second);
5007 /* Probe max_fold_seconds to detect a fold. */
5008 probe_seconds = local(epoch + timet - max_fold_seconds);
5009 if (probe_seconds == -1)
5010 return NULL;
5011 transition = result_seconds - probe_seconds - max_fold_seconds;
5012 if (transition < 0) {
5013 probe_seconds = local(epoch + timet + transition);
5014 if (probe_seconds == -1)
5015 return NULL;
5016 if (probe_seconds == result_seconds)
5017 fold = 1;
5018 }
5019 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005020 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
5021 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00005022}
5023
5024/* Internal helper.
5025 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
5026 * to control the interpretation of the timestamp. Since a double doesn't
5027 * have enough bits to cover a datetime's full range of precision, it's
5028 * better to call datetime_from_timet_and_us provided you have a way
5029 * to get that much precision (e.g., C time() isn't good enough).
5030 */
5031static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01005032datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005033 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00005034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01005036 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00005037
Victor Stinnere4a994d2015-03-30 01:10:14 +02005038 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02005039 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005040 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02005041
Victor Stinner21f58932012-03-14 00:15:40 +01005042 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00005043}
5044
5045/* Internal helper.
5046 * Build most accurate possible datetime for current time. Pass localtime or
5047 * gmtime for f as appropriate.
5048 */
5049static PyObject *
5050datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
5051{
Victor Stinner09e5cf22015-03-30 00:09:18 +02005052 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02005053 time_t secs;
5054 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02005055
Victor Stinner1e2b6882015-09-18 13:23:02 +02005056 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02005057 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02005058 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02005059
Victor Stinner1e2b6882015-09-18 13:23:02 +02005060 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00005061}
5062
Larry Hastings61272b72014-01-07 12:41:53 -08005063/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07005064
5065@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005066datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07005067
5068 tz: object = None
5069 Timezone object.
5070
5071Returns new datetime object representing current time local to tz.
5072
5073If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08005074[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07005075
Larry Hastings31826802013-10-19 00:09:25 -07005076static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08005077datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005078/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00005079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005080 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005081
Larry Hastings31826802013-10-19 00:09:25 -07005082 /* Return best possible local time -- this isn't constrained by the
5083 * precision of a timestamp.
5084 */
5085 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005086 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00005087
Larry Hastings5c661892014-01-24 06:17:25 -08005088 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005089 tz == Py_None ? _PyTime_localtime :
5090 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07005091 tz);
5092 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005093 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02005094 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005095 }
5096 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005097}
5098
Tim Petersa9bc1682003-01-11 03:39:11 +00005099/* Return best possible UTC time -- this isn't constrained by the
5100 * precision of a timestamp.
5101 */
5102static PyObject *
5103datetime_utcnow(PyObject *cls, PyObject *dummy)
5104{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005105 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00005106}
5107
Tim Peters2a799bf2002-12-16 20:18:38 +00005108/* Return new local datetime from timestamp (Python timestamp -- a double). */
5109static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005110datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005111{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005112 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01005113 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005114 PyObject *tzinfo = Py_None;
5115 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00005116
Victor Stinner5d272cc2012-03-13 13:35:55 +01005117 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005118 keywords, &timestamp, &tzinfo))
5119 return NULL;
5120 if (check_tzinfo_subclass(tzinfo) < 0)
5121 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00005122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005123 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005124 tzinfo == Py_None ? _PyTime_localtime :
5125 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005126 timestamp,
5127 tzinfo);
5128 if (self != NULL && tzinfo != Py_None) {
5129 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02005130 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005131 }
5132 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00005133}
5134
Tim Petersa9bc1682003-01-11 03:39:11 +00005135/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
5136static PyObject *
5137datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
5138{
Victor Stinner5d272cc2012-03-13 13:35:55 +01005139 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005140 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005141
Victor Stinner5d272cc2012-03-13 13:35:55 +01005142 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005143 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005144 Py_None);
5145 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005146}
5147
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005148/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005149static PyObject *
5150datetime_strptime(PyObject *cls, PyObject *args)
5151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005152 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005153 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02005154 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005155
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02005156 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005157 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005158
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005159 if (module == NULL) {
5160 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00005161 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00005162 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005163 }
Victor Stinner20401de2016-12-09 15:24:31 +01005164 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
5165 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005166}
5167
Tim Petersa9bc1682003-01-11 03:39:11 +00005168/* Return new datetime from date/datetime and time arguments. */
5169static PyObject *
5170datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
5171{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005172 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005173 PyObject *date;
5174 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005175 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005176 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00005177
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005178 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005179 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04005180 &PyDateTime_TimeType, &time, &tzinfo)) {
5181 if (tzinfo == NULL) {
5182 if (HASTZINFO(time))
5183 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
5184 else
5185 tzinfo = Py_None;
5186 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005187 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
5188 GET_MONTH(date),
5189 GET_DAY(date),
5190 TIME_GET_HOUR(time),
5191 TIME_GET_MINUTE(time),
5192 TIME_GET_SECOND(time),
5193 TIME_GET_MICROSECOND(time),
5194 tzinfo,
5195 TIME_GET_FOLD(time),
5196 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005197 }
5198 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005199}
Tim Peters2a799bf2002-12-16 20:18:38 +00005200
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005201static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005202_sanitize_isoformat_str(PyObject *dtstr)
5203{
Paul Ganssle096329f2018-08-23 11:06:20 -04005204 // `fromisoformat` allows surrogate characters in exactly one position,
5205 // the separator; to allow datetime_fromisoformat to make the simplifying
5206 // assumption that all valid strings can be encoded in UTF-8, this function
5207 // replaces any surrogate character separators with `T`.
Paul Ganssle3df85402018-10-22 12:32:52 -04005208 //
5209 // The result of this, if not NULL, returns a new reference
Paul Ganssle096329f2018-08-23 11:06:20 -04005210 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005211 if (len < 0) {
5212 return NULL;
5213 }
5214
5215 if (len <= 10 ||
5216 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
5217 Py_INCREF(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005218 return dtstr;
5219 }
5220
Paul Ganssle3df85402018-10-22 12:32:52 -04005221 PyObject *str_out = _PyUnicode_Copy(dtstr);
Paul Ganssle096329f2018-08-23 11:06:20 -04005222 if (str_out == NULL) {
5223 return NULL;
5224 }
5225
Paul Ganssle3df85402018-10-22 12:32:52 -04005226 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005227 Py_DECREF(str_out);
5228 return NULL;
5229 }
5230
Paul Ganssle096329f2018-08-23 11:06:20 -04005231 return str_out;
5232}
5233
5234static PyObject *
Paul Ganssle3df85402018-10-22 12:32:52 -04005235datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5236{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005237 assert(dtstr != NULL);
5238
5239 if (!PyUnicode_Check(dtstr)) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005240 PyErr_SetString(PyExc_TypeError,
5241 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005242 return NULL;
5243 }
5244
Paul Ganssle3df85402018-10-22 12:32:52 -04005245 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5246 if (dtstr_clean == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005247 goto error;
5248 }
5249
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005250 Py_ssize_t len;
Paul Ganssle3df85402018-10-22 12:32:52 -04005251 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Paul Ganssle096329f2018-08-23 11:06:20 -04005252
5253 if (dt_ptr == NULL) {
Paul Ganssle3df85402018-10-22 12:32:52 -04005254 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5255 // Encoding errors are invalid string errors at this point
5256 goto invalid_string_error;
5257 }
5258 else {
5259 goto error;
5260 }
Paul Ganssle096329f2018-08-23 11:06:20 -04005261 }
5262
5263 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005264
5265 int year = 0, month = 0, day = 0;
5266 int hour = 0, minute = 0, second = 0, microsecond = 0;
5267 int tzoffset = 0, tzusec = 0;
5268
5269 // date has a fixed length of 10
5270 int rv = parse_isoformat_date(p, &year, &month, &day);
5271
5272 if (!rv && len > 10) {
5273 // In UTF-8, the length of multi-byte characters is encoded in the MSB
5274 if ((p[10] & 0x80) == 0) {
5275 p += 11;
Paul Ganssle3df85402018-10-22 12:32:52 -04005276 }
5277 else {
5278 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005279 case 0xe0:
5280 p += 13;
5281 break;
5282 case 0xf0:
5283 p += 14;
5284 break;
5285 default:
5286 p += 12;
5287 break;
5288 }
5289 }
5290
5291 len -= (p - dt_ptr);
Paul Ganssle3df85402018-10-22 12:32:52 -04005292 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5293 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005294 }
5295 if (rv < 0) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005296 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005297 }
5298
Paul Ganssle3df85402018-10-22 12:32:52 -04005299 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005300 if (tzinfo == NULL) {
Paul Ganssle096329f2018-08-23 11:06:20 -04005301 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005302 }
5303
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005304 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5305 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005306
5307 Py_DECREF(tzinfo);
Paul Ganssle3df85402018-10-22 12:32:52 -04005308 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005309 return dt;
Paul Ganssle096329f2018-08-23 11:06:20 -04005310
5311invalid_string_error:
5312 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5313
5314error:
Paul Ganssle3df85402018-10-22 12:32:52 -04005315 Py_XDECREF(dtstr_clean);
Paul Ganssle096329f2018-08-23 11:06:20 -04005316
5317 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005318}
5319
Tim Peters2a799bf2002-12-16 20:18:38 +00005320/*
5321 * Destructor.
5322 */
5323
5324static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005325datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005327 if (HASTZINFO(self)) {
5328 Py_XDECREF(self->tzinfo);
5329 }
5330 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005331}
5332
5333/*
5334 * Indirect access to tzinfo methods.
5335 */
5336
Tim Peters2a799bf2002-12-16 20:18:38 +00005337/* These are all METH_NOARGS, so don't need to check the arglist. */
5338static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005339datetime_utcoffset(PyObject *self, PyObject *unused) {
5340 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005341}
5342
5343static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005344datetime_dst(PyObject *self, PyObject *unused) {
5345 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005346}
5347
5348static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005349datetime_tzname(PyObject *self, PyObject *unused) {
5350 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005351}
5352
5353/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005354 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005355 */
5356
Tim Petersa9bc1682003-01-11 03:39:11 +00005357/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5358 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005359 */
5360static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005361add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005362 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005364 /* Note that the C-level additions can't overflow, because of
5365 * invariant bounds on the member values.
5366 */
5367 int year = GET_YEAR(date);
5368 int month = GET_MONTH(date);
5369 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5370 int hour = DATE_GET_HOUR(date);
5371 int minute = DATE_GET_MINUTE(date);
5372 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5373 int microsecond = DATE_GET_MICROSECOND(date) +
5374 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005376 assert(factor == 1 || factor == -1);
5377 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005378 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005379 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005380 }
5381
Paul Ganssle89427cd2019-02-04 14:42:04 -05005382 return new_datetime_subclass_ex(year, month, day,
5383 hour, minute, second, microsecond,
5384 HASTZINFO(date) ? date->tzinfo : Py_None,
5385 (PyObject *)Py_TYPE(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00005386}
5387
5388static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005389datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005391 if (PyDateTime_Check(left)) {
5392 /* datetime + ??? */
5393 if (PyDelta_Check(right))
5394 /* datetime + delta */
5395 return add_datetime_timedelta(
5396 (PyDateTime_DateTime *)left,
5397 (PyDateTime_Delta *)right,
5398 1);
5399 }
5400 else if (PyDelta_Check(left)) {
5401 /* delta + datetime */
5402 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5403 (PyDateTime_Delta *) left,
5404 1);
5405 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005406 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005407}
5408
5409static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005410datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005412 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005414 if (PyDateTime_Check(left)) {
5415 /* datetime - ??? */
5416 if (PyDateTime_Check(right)) {
5417 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005418 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005419 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005420
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005421 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5422 offset2 = offset1 = Py_None;
5423 Py_INCREF(offset1);
5424 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005425 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005426 else {
5427 offset1 = datetime_utcoffset(left, NULL);
5428 if (offset1 == NULL)
5429 return NULL;
5430 offset2 = datetime_utcoffset(right, NULL);
5431 if (offset2 == NULL) {
5432 Py_DECREF(offset1);
5433 return NULL;
5434 }
5435 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5436 PyErr_SetString(PyExc_TypeError,
5437 "can't subtract offset-naive and "
5438 "offset-aware datetimes");
5439 Py_DECREF(offset1);
5440 Py_DECREF(offset2);
5441 return NULL;
5442 }
5443 }
5444 if ((offset1 != offset2) &&
5445 delta_cmp(offset1, offset2) != 0) {
5446 offdiff = delta_subtract(offset1, offset2);
5447 if (offdiff == NULL) {
5448 Py_DECREF(offset1);
5449 Py_DECREF(offset2);
5450 return NULL;
5451 }
5452 }
5453 Py_DECREF(offset1);
5454 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005455 delta_d = ymd_to_ord(GET_YEAR(left),
5456 GET_MONTH(left),
5457 GET_DAY(left)) -
5458 ymd_to_ord(GET_YEAR(right),
5459 GET_MONTH(right),
5460 GET_DAY(right));
5461 /* These can't overflow, since the values are
5462 * normalized. At most this gives the number of
5463 * seconds in one day.
5464 */
5465 delta_s = (DATE_GET_HOUR(left) -
5466 DATE_GET_HOUR(right)) * 3600 +
5467 (DATE_GET_MINUTE(left) -
5468 DATE_GET_MINUTE(right)) * 60 +
5469 (DATE_GET_SECOND(left) -
5470 DATE_GET_SECOND(right));
5471 delta_us = DATE_GET_MICROSECOND(left) -
5472 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005473 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005474 if (result == NULL)
5475 return NULL;
5476
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005477 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005478 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005479 Py_DECREF(offdiff);
5480 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005481 }
5482 else if (PyDelta_Check(right)) {
5483 /* datetime - delta */
5484 result = add_datetime_timedelta(
5485 (PyDateTime_DateTime *)left,
5486 (PyDateTime_Delta *)right,
5487 -1);
5488 }
5489 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005491 if (result == Py_NotImplemented)
5492 Py_INCREF(result);
5493 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005494}
5495
5496/* Various ways to turn a datetime into a string. */
5497
5498static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005499datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005501 const char *type_name = Py_TYPE(self)->tp_name;
5502 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005504 if (DATE_GET_MICROSECOND(self)) {
5505 baserepr = PyUnicode_FromFormat(
5506 "%s(%d, %d, %d, %d, %d, %d, %d)",
5507 type_name,
5508 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5509 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5510 DATE_GET_SECOND(self),
5511 DATE_GET_MICROSECOND(self));
5512 }
5513 else if (DATE_GET_SECOND(self)) {
5514 baserepr = PyUnicode_FromFormat(
5515 "%s(%d, %d, %d, %d, %d, %d)",
5516 type_name,
5517 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5518 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5519 DATE_GET_SECOND(self));
5520 }
5521 else {
5522 baserepr = PyUnicode_FromFormat(
5523 "%s(%d, %d, %d, %d, %d)",
5524 type_name,
5525 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5526 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5527 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005528 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5529 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005530 if (baserepr == NULL || ! HASTZINFO(self))
5531 return baserepr;
5532 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005533}
5534
Tim Petersa9bc1682003-01-11 03:39:11 +00005535static PyObject *
5536datetime_str(PyDateTime_DateTime *self)
5537{
Victor Stinner4c381542016-12-09 00:33:39 +01005538 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005539}
Tim Peters2a799bf2002-12-16 20:18:38 +00005540
5541static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005542datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005543{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005544 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005545 char *timespec = NULL;
5546 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005547 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005548 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005549 int us = DATE_GET_MICROSECOND(self);
Andy Lesterc3fa6342020-02-24 00:40:43 -06005550 static const char *specs[][2] = {
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005551 {"hours", "%04d-%02d-%02d%c%02d"},
5552 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5553 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5554 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5555 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5556 };
5557 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005558
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005559 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005560 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005561
5562 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5563 if (us == 0) {
5564 /* seconds */
5565 given_spec = 2;
5566 }
5567 else {
5568 /* microseconds */
5569 given_spec = 4;
5570 }
5571 }
5572 else {
5573 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5574 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5575 if (given_spec == 3) {
5576 us = us / 1000;
5577 }
5578 break;
5579 }
5580 }
5581 }
5582
5583 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5584 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5585 return NULL;
5586 }
5587 else {
5588 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005589 GET_YEAR(self), GET_MONTH(self),
5590 GET_DAY(self), (int)sep,
5591 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5592 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005593 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005595 if (!result || !HASTZINFO(self))
5596 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005598 /* We need to append the UTC offset. */
5599 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5600 (PyObject *)self) < 0) {
5601 Py_DECREF(result);
5602 return NULL;
5603 }
5604 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5605 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005606}
5607
Tim Petersa9bc1682003-01-11 03:39:11 +00005608static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305609datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005611 return format_ctime((PyDateTime_Date *)self,
5612 DATE_GET_HOUR(self),
5613 DATE_GET_MINUTE(self),
5614 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005615}
5616
Tim Peters2a799bf2002-12-16 20:18:38 +00005617/* Miscellaneous methods. */
5618
Tim Petersa9bc1682003-01-11 03:39:11 +00005619static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005620flip_fold(PyObject *dt)
5621{
5622 return new_datetime_ex2(GET_YEAR(dt),
5623 GET_MONTH(dt),
5624 GET_DAY(dt),
5625 DATE_GET_HOUR(dt),
5626 DATE_GET_MINUTE(dt),
5627 DATE_GET_SECOND(dt),
5628 DATE_GET_MICROSECOND(dt),
5629 HASTZINFO(dt) ?
5630 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5631 !DATE_GET_FOLD(dt),
5632 Py_TYPE(dt));
5633}
5634
5635static PyObject *
5636get_flip_fold_offset(PyObject *dt)
5637{
5638 PyObject *result, *flip_dt;
5639
5640 flip_dt = flip_fold(dt);
5641 if (flip_dt == NULL)
5642 return NULL;
5643 result = datetime_utcoffset(flip_dt, NULL);
5644 Py_DECREF(flip_dt);
5645 return result;
5646}
5647
5648/* PEP 495 exception: Whenever one or both of the operands in
5649 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakabac2d5b2018-03-28 22:14:26 +03005650 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005651 *
5652 * Return 1 if exception applies, 0 if not, and -1 on error.
5653 */
5654static int
5655pep495_eq_exception(PyObject *self, PyObject *other,
5656 PyObject *offset_self, PyObject *offset_other)
5657{
5658 int result = 0;
5659 PyObject *flip_offset;
5660
5661 flip_offset = get_flip_fold_offset(self);
5662 if (flip_offset == NULL)
5663 return -1;
5664 if (flip_offset != offset_self &&
5665 delta_cmp(flip_offset, offset_self))
5666 {
5667 result = 1;
5668 goto done;
5669 }
5670 Py_DECREF(flip_offset);
5671
5672 flip_offset = get_flip_fold_offset(other);
5673 if (flip_offset == NULL)
5674 return -1;
5675 if (flip_offset != offset_other &&
5676 delta_cmp(flip_offset, offset_other))
5677 result = 1;
5678 done:
5679 Py_DECREF(flip_offset);
5680 return result;
5681}
5682
5683static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005684datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005685{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005686 PyObject *result = NULL;
5687 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005688 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005690 if (! PyDateTime_Check(other)) {
5691 if (PyDate_Check(other)) {
5692 /* Prevent invocation of date_richcompare. We want to
5693 return NotImplemented here to give the other object
5694 a chance. But since DateTime is a subclass of
5695 Date, if the other object is a Date, it would
5696 compute an ordering based on the date part alone,
5697 and we don't want that. So force unequal or
5698 uncomparable here in that case. */
5699 if (op == Py_EQ)
5700 Py_RETURN_FALSE;
5701 if (op == Py_NE)
5702 Py_RETURN_TRUE;
5703 return cmperror(self, other);
5704 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005705 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005706 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005707
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005708 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005709 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5710 ((PyDateTime_DateTime *)other)->data,
5711 _PyDateTime_DATETIME_DATASIZE);
5712 return diff_to_bool(diff, op);
5713 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005714 offset1 = datetime_utcoffset(self, NULL);
5715 if (offset1 == NULL)
5716 return NULL;
5717 offset2 = datetime_utcoffset(other, NULL);
5718 if (offset2 == NULL)
5719 goto done;
5720 /* If they're both naive, or both aware and have the same offsets,
5721 * we get off cheap. Note that if they're both naive, offset1 ==
5722 * offset2 == Py_None at this point.
5723 */
5724 if ((offset1 == offset2) ||
5725 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5726 delta_cmp(offset1, offset2) == 0)) {
5727 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5728 ((PyDateTime_DateTime *)other)->data,
5729 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005730 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5731 int ex = pep495_eq_exception(self, other, offset1, offset2);
5732 if (ex == -1)
5733 goto done;
5734 if (ex)
5735 diff = 1;
5736 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005737 result = diff_to_bool(diff, op);
5738 }
5739 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005740 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005741
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005742 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005743 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5744 other);
5745 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005746 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005747 diff = GET_TD_DAYS(delta);
5748 if (diff == 0)
5749 diff = GET_TD_SECONDS(delta) |
5750 GET_TD_MICROSECONDS(delta);
5751 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005752 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5753 int ex = pep495_eq_exception(self, other, offset1, offset2);
5754 if (ex == -1)
5755 goto done;
5756 if (ex)
5757 diff = 1;
5758 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005759 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005760 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005761 else if (op == Py_EQ) {
5762 result = Py_False;
5763 Py_INCREF(result);
5764 }
5765 else if (op == Py_NE) {
5766 result = Py_True;
5767 Py_INCREF(result);
5768 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005769 else {
5770 PyErr_SetString(PyExc_TypeError,
5771 "can't compare offset-naive and "
5772 "offset-aware datetimes");
5773 }
5774 done:
5775 Py_DECREF(offset1);
5776 Py_XDECREF(offset2);
5777 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005778}
5779
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005780static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005781datetime_hash(PyDateTime_DateTime *self)
5782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005783 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005784 PyObject *offset, *self0;
5785 if (DATE_GET_FOLD(self)) {
5786 self0 = new_datetime_ex2(GET_YEAR(self),
5787 GET_MONTH(self),
5788 GET_DAY(self),
5789 DATE_GET_HOUR(self),
5790 DATE_GET_MINUTE(self),
5791 DATE_GET_SECOND(self),
5792 DATE_GET_MICROSECOND(self),
5793 HASTZINFO(self) ? self->tzinfo : Py_None,
5794 0, Py_TYPE(self));
5795 if (self0 == NULL)
5796 return -1;
5797 }
5798 else {
5799 self0 = (PyObject *)self;
5800 Py_INCREF(self0);
5801 }
5802 offset = datetime_utcoffset(self0, NULL);
5803 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005804
5805 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005806 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005808 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005809 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005810 self->hashcode = generic_hash(
5811 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005812 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005813 PyObject *temp1, *temp2;
5814 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005816 assert(HASTZINFO(self));
5817 days = ymd_to_ord(GET_YEAR(self),
5818 GET_MONTH(self),
5819 GET_DAY(self));
5820 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005821 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005822 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005823 temp1 = new_delta(days, seconds,
5824 DATE_GET_MICROSECOND(self),
5825 1);
5826 if (temp1 == NULL) {
5827 Py_DECREF(offset);
5828 return -1;
5829 }
5830 temp2 = delta_subtract(temp1, offset);
5831 Py_DECREF(temp1);
5832 if (temp2 == NULL) {
5833 Py_DECREF(offset);
5834 return -1;
5835 }
5836 self->hashcode = PyObject_Hash(temp2);
5837 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005838 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005839 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005840 }
5841 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005842}
Tim Peters2a799bf2002-12-16 20:18:38 +00005843
5844static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005845datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005847 PyObject *clone;
5848 PyObject *tuple;
5849 int y = GET_YEAR(self);
5850 int m = GET_MONTH(self);
5851 int d = GET_DAY(self);
5852 int hh = DATE_GET_HOUR(self);
5853 int mm = DATE_GET_MINUTE(self);
5854 int ss = DATE_GET_SECOND(self);
5855 int us = DATE_GET_MICROSECOND(self);
5856 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005857 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005858
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005859 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005860 datetime_kws,
5861 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005862 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005863 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005864 if (fold != 0 && fold != 1) {
5865 PyErr_SetString(PyExc_ValueError,
5866 "fold must be either 0 or 1");
5867 return NULL;
5868 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005869 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5870 if (tuple == NULL)
5871 return NULL;
5872 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005873 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005874 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005875 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005876 Py_DECREF(tuple);
5877 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005878}
5879
5880static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005881local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005882{
5883 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005884 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005885 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005886 PyObject *nameo = NULL;
5887 const char *zone = NULL;
5888
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005889 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005890 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005891#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005892 zone = local_time_tm.tm_zone;
5893 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005894#else /* HAVE_STRUCT_TM_TM_ZONE */
5895 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005896 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005897 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005898 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005899 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005900 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005901 local_time = new_datetime(local_time_tm.tm_year + 1900,
5902 local_time_tm.tm_mon + 1,
5903 local_time_tm.tm_mday,
5904 local_time_tm.tm_hour,
5905 local_time_tm.tm_min,
5906 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005907 if (local_time == NULL) {
5908 return NULL;
5909 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005910 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005911 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005912 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5913 utc_time_tm.tm_mon + 1,
5914 utc_time_tm.tm_mday,
5915 utc_time_tm.tm_hour,
5916 utc_time_tm.tm_min,
5917 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005918 if (utc_time == NULL) {
5919 Py_DECREF(local_time);
5920 return NULL;
5921 }
5922 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005923 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005924 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005925 }
5926#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005927 if (delta == NULL) {
5928 return NULL;
5929 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005930 if (zone != NULL) {
5931 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5932 if (nameo == NULL)
5933 goto error;
5934 }
5935 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005936 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005937 error:
5938 Py_DECREF(delta);
5939 return result;
5940}
5941
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005942static PyObject *
5943local_timezone(PyDateTime_DateTime *utc_time)
5944{
5945 time_t timestamp;
5946 PyObject *delta;
5947 PyObject *one_second;
5948 PyObject *seconds;
5949
5950 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5951 if (delta == NULL)
5952 return NULL;
5953 one_second = new_delta(0, 1, 0, 0);
5954 if (one_second == NULL) {
5955 Py_DECREF(delta);
5956 return NULL;
5957 }
5958 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5959 (PyDateTime_Delta *)one_second);
5960 Py_DECREF(one_second);
5961 Py_DECREF(delta);
5962 if (seconds == NULL)
5963 return NULL;
5964 timestamp = _PyLong_AsTime_t(seconds);
5965 Py_DECREF(seconds);
5966 if (timestamp == -1 && PyErr_Occurred())
5967 return NULL;
5968 return local_timezone_from_timestamp(timestamp);
5969}
5970
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005971static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005972local_to_seconds(int year, int month, int day,
5973 int hour, int minute, int second, int fold);
5974
5975static PyObject *
5976local_timezone_from_local(PyDateTime_DateTime *local_dt)
5977{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005978 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005979 time_t timestamp;
5980 seconds = local_to_seconds(GET_YEAR(local_dt),
5981 GET_MONTH(local_dt),
5982 GET_DAY(local_dt),
5983 DATE_GET_HOUR(local_dt),
5984 DATE_GET_MINUTE(local_dt),
5985 DATE_GET_SECOND(local_dt),
5986 DATE_GET_FOLD(local_dt));
5987 if (seconds == -1)
5988 return NULL;
5989 /* XXX: add bounds check */
5990 timestamp = seconds - epoch;
5991 return local_timezone_from_timestamp(timestamp);
5992}
5993
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005994static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005995datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005996{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005997 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005998 PyObject *offset;
5999 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006000 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006001 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006002 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00006003
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006004 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07006005 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006006 return NULL;
6007
6008 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006009 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00006010
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006011 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Alexander Belopolsky877b2322018-06-10 17:02:58 -04006012 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006013 self_tzinfo = local_timezone_from_local(self);
6014 if (self_tzinfo == NULL)
6015 return NULL;
6016 } else {
6017 self_tzinfo = self->tzinfo;
6018 Py_INCREF(self_tzinfo);
6019 }
Tim Peters521fc152002-12-31 17:36:56 +00006020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006021 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006022 if (self_tzinfo == tzinfo) {
6023 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006024 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006025 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006026 }
Tim Peters521fc152002-12-31 17:36:56 +00006027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006028 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006029 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
6030 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006031 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006032 return NULL;
Alexander Belopolsky877b2322018-06-10 17:02:58 -04006033 else if(offset == Py_None) {
6034 Py_DECREF(offset);
6035 goto naive;
6036 }
6037 else if (!PyDelta_Check(offset)) {
6038 Py_DECREF(offset);
6039 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
6040 " expected timedelta or None", Py_TYPE(offset)->tp_name);
6041 return NULL;
6042 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006043 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006044 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6045 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006046 Py_DECREF(offset);
6047 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006048 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00006049
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006050 /* Make sure result is aware and UTC. */
6051 if (!HASTZINFO(result)) {
6052 temp = (PyObject *)result;
6053 result = (PyDateTime_DateTime *)
6054 new_datetime_ex2(GET_YEAR(result),
6055 GET_MONTH(result),
6056 GET_DAY(result),
6057 DATE_GET_HOUR(result),
6058 DATE_GET_MINUTE(result),
6059 DATE_GET_SECOND(result),
6060 DATE_GET_MICROSECOND(result),
6061 PyDateTime_TimeZone_UTC,
6062 DATE_GET_FOLD(result),
6063 Py_TYPE(result));
6064 Py_DECREF(temp);
6065 if (result == NULL)
6066 return NULL;
6067 }
6068 else {
6069 /* Result is already aware - just replace tzinfo. */
6070 temp = result->tzinfo;
6071 result->tzinfo = PyDateTime_TimeZone_UTC;
6072 Py_INCREF(result->tzinfo);
6073 Py_DECREF(temp);
6074 }
6075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006076 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006077 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04006078 if (tzinfo == Py_None) {
6079 tzinfo = local_timezone(result);
6080 if (tzinfo == NULL) {
6081 Py_DECREF(result);
6082 return NULL;
6083 }
6084 }
6085 else
6086 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006087 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006088 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00006089
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04006090 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006091 result = (PyDateTime_DateTime *)
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02006092 _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006093 Py_DECREF(temp);
6094
Alexander Belopolsky878054e2012-06-22 14:11:58 -04006095 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00006096}
6097
6098static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306099datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006101 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00006102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006103 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006104 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00006105
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006106 dst = call_dst(self->tzinfo, (PyObject *)self);
6107 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006108 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006109
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006110 if (dst != Py_None)
6111 dstflag = delta_bool((PyDateTime_Delta *)dst);
6112 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006113 }
6114 return build_struct_time(GET_YEAR(self),
6115 GET_MONTH(self),
6116 GET_DAY(self),
6117 DATE_GET_HOUR(self),
6118 DATE_GET_MINUTE(self),
6119 DATE_GET_SECOND(self),
6120 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00006121}
6122
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006123static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006124local_to_seconds(int year, int month, int day,
6125 int hour, int minute, int second, int fold)
6126{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006127 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006128 t = utc_to_seconds(year, month, day, hour, minute, second);
6129 /* Our goal is to solve t = local(u) for u. */
6130 lt = local(t);
6131 if (lt == -1)
6132 return -1;
6133 a = lt - t;
6134 u1 = t - a;
6135 t1 = local(u1);
6136 if (t1 == -1)
6137 return -1;
6138 if (t1 == t) {
6139 /* We found one solution, but it may not be the one we need.
6140 * Look for an earlier solution (if `fold` is 0), or a
6141 * later one (if `fold` is 1). */
6142 if (fold)
6143 u2 = u1 + max_fold_seconds;
6144 else
6145 u2 = u1 - max_fold_seconds;
6146 lt = local(u2);
6147 if (lt == -1)
6148 return -1;
6149 b = lt - u2;
6150 if (a == b)
6151 return u1;
6152 }
6153 else {
6154 b = t1 - u1;
6155 assert(a != b);
6156 }
6157 u2 = t - b;
6158 t2 = local(u2);
6159 if (t2 == -1)
6160 return -1;
6161 if (t2 == t)
6162 return u2;
6163 if (t1 == t)
6164 return u1;
6165 /* We have found both offsets a and b, but neither t - a nor t - b is
6166 * a solution. This means t is in the gap. */
6167 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
6168}
6169
6170/* date(1970,1,1).toordinal() == 719163 */
6171#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
6172
Tim Peters2a799bf2002-12-16 20:18:38 +00006173static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306174datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolskya4415142012-06-08 12:33:09 -04006175{
6176 PyObject *result;
6177
6178 if (HASTZINFO(self) && self->tzinfo != Py_None) {
6179 PyObject *delta;
6180 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
6181 if (delta == NULL)
6182 return NULL;
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306183 result = delta_total_seconds(delta, NULL);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006184 Py_DECREF(delta);
6185 }
6186 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07006187 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006188 seconds = local_to_seconds(GET_YEAR(self),
6189 GET_MONTH(self),
6190 GET_DAY(self),
6191 DATE_GET_HOUR(self),
6192 DATE_GET_MINUTE(self),
6193 DATE_GET_SECOND(self),
6194 DATE_GET_FOLD(self));
6195 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04006196 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006197 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
6198 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006199 }
6200 return result;
6201}
6202
6203static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306204datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006206 return new_date(GET_YEAR(self),
6207 GET_MONTH(self),
6208 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006209}
6210
6211static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306212datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006214 return new_time(DATE_GET_HOUR(self),
6215 DATE_GET_MINUTE(self),
6216 DATE_GET_SECOND(self),
6217 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006218 Py_None,
6219 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006220}
6221
6222static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306223datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00006224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006225 return new_time(DATE_GET_HOUR(self),
6226 DATE_GET_MINUTE(self),
6227 DATE_GET_SECOND(self),
6228 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006229 GET_DT_TZINFO(self),
6230 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006231}
6232
6233static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05306234datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00006235{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006236 int y, m, d, hh, mm, ss;
6237 PyObject *tzinfo;
6238 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006239
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006240 tzinfo = GET_DT_TZINFO(self);
6241 if (tzinfo == Py_None) {
6242 utcself = self;
6243 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006244 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006245 else {
6246 PyObject *offset;
6247 offset = call_utcoffset(tzinfo, (PyObject *)self);
6248 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006249 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006250 if (offset == Py_None) {
6251 Py_DECREF(offset);
6252 utcself = self;
6253 Py_INCREF(utcself);
6254 }
6255 else {
6256 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6257 (PyDateTime_Delta *)offset, -1);
6258 Py_DECREF(offset);
6259 if (utcself == NULL)
6260 return NULL;
6261 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006262 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006263 y = GET_YEAR(utcself);
6264 m = GET_MONTH(utcself);
6265 d = GET_DAY(utcself);
6266 hh = DATE_GET_HOUR(utcself);
6267 mm = DATE_GET_MINUTE(utcself);
6268 ss = DATE_GET_SECOND(utcself);
6269
6270 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006271 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006272}
6273
Tim Peters371935f2003-02-01 01:52:50 +00006274/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006275
Tim Petersa9bc1682003-01-11 03:39:11 +00006276/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006277 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6278 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006279 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006280 */
6281static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006282datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006284 PyObject *basestate;
6285 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006287 basestate = PyBytes_FromStringAndSize((char *)self->data,
6288 _PyDateTime_DATETIME_DATASIZE);
6289 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006290 if (proto > 3 && DATE_GET_FOLD(self))
6291 /* Set the first bit of the third byte */
6292 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006293 if (! HASTZINFO(self) || self->tzinfo == Py_None)
6294 result = PyTuple_Pack(1, basestate);
6295 else
6296 result = PyTuple_Pack(2, basestate, self->tzinfo);
6297 Py_DECREF(basestate);
6298 }
6299 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00006300}
6301
6302static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006303datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006304{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006305 int proto;
6306 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006307 return NULL;
6308
6309 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006310}
6311
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006312static PyObject *
6313datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6314{
6315 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6316}
6317
Tim Petersa9bc1682003-01-11 03:39:11 +00006318static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006320 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006321
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006322 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006324 {"utcnow", (PyCFunction)datetime_utcnow,
6325 METH_NOARGS | METH_CLASS,
6326 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006327
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006328 {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006329 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6330 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006332 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6333 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006334 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006336 {"strptime", (PyCFunction)datetime_strptime,
6337 METH_VARARGS | METH_CLASS,
6338 PyDoc_STR("string, format -> new datetime parsed from a string "
6339 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006340
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006341 {"combine", (PyCFunction)(void(*)(void))datetime_combine,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006342 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6343 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006344
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006345 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6346 METH_O | METH_CLASS,
6347 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006349 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006351 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6352 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006354 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6355 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006357 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6358 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006360 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6361 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006363 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6364 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006365
Alexander Belopolskya4415142012-06-08 12:33:09 -04006366 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6367 PyDoc_STR("Return POSIX timestamp as float.")},
6368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006369 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6370 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006371
Serhiy Storchaka62be7422018-11-27 13:27:31 +02006372 {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006373 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006374 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006375 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006376 "defaults to 'T'.\n"
Ram Rachum52301312020-10-03 13:43:47 +03006377 "The optional argument timespec specifies the number "
6378 "of additional terms\nof the time to include. Valid "
6379 "options are 'auto', 'hours', 'minutes',\n'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
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006497static int
6498_datetime_exec(PyObject *module)
Tim Peters2a799bf2002-12-16 20:18:38 +00006499{
Petr Viktorin459acc52020-05-28 18:14:46 +02006500 // `&...` is not a constant expression according to a strict reading
6501 // of C standards. Fill tp_base at run-time rather than statically.
6502 // See https://bugs.python.org/issue40777
6503 PyDateTime_IsoCalendarDateType.tp_base = &PyTuple_Type;
6504 PyDateTime_TimeZoneType.tp_base = &PyDateTime_TZInfoType;
6505 PyDateTime_DateTimeType.tp_base = &PyDateTime_DateType;
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006506
Dong-hee Na37fcbb62020-03-25 07:08:51 +09006507 PyTypeObject *types[] = {
6508 &PyDateTime_DateType,
6509 &PyDateTime_DateTimeType,
6510 &PyDateTime_TimeType,
6511 &PyDateTime_DeltaType,
6512 &PyDateTime_TZInfoType,
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006513 &PyDateTime_TimeZoneType,
Dong-hee Na37fcbb62020-03-25 07:08:51 +09006514 };
6515
6516 for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006517 if (PyModule_AddType(module, types[i]) < 0) {
6518 return -1;
Dong-hee Na37fcbb62020-03-25 07:08:51 +09006519 }
6520 }
Tim Peters2a799bf2002-12-16 20:18:38 +00006521
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006522 if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) {
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006523 return -1;
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006524 }
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006525
6526#define DATETIME_ADD_MACRO(dict, c, value_expr) \
6527 do { \
6528 PyObject *value = (value_expr); \
6529 if (value == NULL) { \
6530 return -1; \
6531 } \
6532 if (PyDict_SetItemString(dict, c, value) < 0) { \
6533 Py_DECREF(value); \
6534 return -1; \
6535 } \
6536 Py_DECREF(value); \
6537 } while(0)
Paul Ganssle1b97b9b2020-05-16 10:02:59 -04006538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006539 /* timedelta values */
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006540 PyObject *d = PyDateTime_DeltaType.tp_dict;
6541 DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
6542 DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0));
6543 DATETIME_ADD_MACRO(d, "max",
6544 new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0));
Tim Peters2a799bf2002-12-16 20:18:38 +00006545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006546 /* date values */
6547 d = PyDateTime_DateType.tp_dict;
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006548 DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1));
6549 DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31));
6550 DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0));
Tim Peters2a799bf2002-12-16 20:18:38 +00006551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006552 /* time values */
6553 d = PyDateTime_TimeType.tp_dict;
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006554 DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0));
6555 DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0));
6556 DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
Tim Peters2a799bf2002-12-16 20:18:38 +00006557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006558 /* datetime values */
6559 d = PyDateTime_DateTimeType.tp_dict;
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006560 DATETIME_ADD_MACRO(d, "min",
6561 new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0));
6562 DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59,
6563 999999, Py_None, 0));
6564 DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
Tim Peters2a799bf2002-12-16 20:18:38 +00006565
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006566 /* timezone values */
6567 d = PyDateTime_TimeZoneType.tp_dict;
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006568 PyObject *delta = new_delta(0, 0, 0, 0);
6569 if (delta == NULL) {
6570 return -1;
6571 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006572
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006573 PyObject *x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006574 Py_DECREF(delta);
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006575 if (x == NULL) {
6576 return -1;
6577 }
6578 if (PyDict_SetItemString(d, "utc", x) < 0) {
6579 Py_DECREF(x);
6580 return -1;
6581 }
6582
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006583 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006584 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006585
Ngalim Siregar92c7e302019-08-09 21:22:16 +07006586 /* bpo-37642: These attributes are rounded to the nearest minute for backwards
6587 * compatibility, even though the constructor will accept a wider range of
6588 * values. This may change in the future.*/
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006589 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006590 if (delta == NULL) {
6591 return -1;
6592 }
6593
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006594 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006595 Py_DECREF(delta);
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006596 DATETIME_ADD_MACRO(d, "min", x);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006597
6598 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006599 if (delta == NULL) {
6600 return -1;
6601 }
6602
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006603 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006604 Py_DECREF(delta);
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006605 DATETIME_ADD_MACRO(d, "max", x);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006606
Alexander Belopolskya4415142012-06-08 12:33:09 -04006607 /* Epoch */
6608 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006609 PyDateTime_TimeZone_UTC, 0);
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006610 if (PyDateTime_Epoch == NULL) {
6611 return -1;
6612 }
Alexander Belopolskya4415142012-06-08 12:33:09 -04006613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006614 /* module initialization */
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006615 if (PyModule_AddIntMacro(module, MINYEAR) < 0) {
6616 return -1;
6617 }
6618 if (PyModule_AddIntMacro(module, MAXYEAR) < 0) {
6619 return -1;
6620 }
Tim Peters2a799bf2002-12-16 20:18:38 +00006621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006622 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006623 if (x == NULL) {
6624 return -1;
6625 }
6626
6627 if (PyModule_AddObject(module, "datetime_CAPI", x) < 0) {
6628 Py_DECREF(x);
6629 return -1;
6630 }
Tim Peters9ddf40b2004-06-20 22:41:32 +00006631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006632 /* A 4-year cycle has an extra leap day over what we'd get from
6633 * pasting together 4 single years.
6634 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006635 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006636 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006638 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6639 * get from pasting together 4 100-year cycles.
6640 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006641 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006642 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006644 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6645 * pasting together 25 4-year cycles.
6646 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006647 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006648 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006650 us_per_ms = PyLong_FromLong(1000);
6651 us_per_second = PyLong_FromLong(1000000);
6652 us_per_minute = PyLong_FromLong(60000000);
6653 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006654 if (us_per_ms == NULL || us_per_second == NULL ||
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006655 us_per_minute == NULL || seconds_per_day == NULL) {
6656 return -1;
6657 }
Tim Peters2a799bf2002-12-16 20:18:38 +00006658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006659 /* The rest are too big for 32-bit ints, but even
6660 * us_per_week fits in 40 bits, so doubles should be exact.
6661 */
6662 us_per_hour = PyLong_FromDouble(3600000000.0);
6663 us_per_day = PyLong_FromDouble(86400000000.0);
6664 us_per_week = PyLong_FromDouble(604800000000.0);
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006665 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) {
6666 return -1;
6667 }
6668 return 0;
6669}
6670
6671static struct PyModuleDef datetimemodule = {
6672 PyModuleDef_HEAD_INIT,
6673 .m_name = "_datetime",
6674 .m_doc = "Fast implementation of the datetime type.",
6675 .m_size = -1,
6676 .m_methods = module_methods,
6677};
6678
6679PyMODINIT_FUNC
6680PyInit__datetime(void)
6681{
6682 PyObject *mod = PyModule_Create(&datetimemodule);
6683 if (mod == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006684 return NULL;
Mohamed Koubaa2db8e352020-11-20 04:39:40 -06006685
6686 if (_datetime_exec(mod) < 0) {
6687 Py_DECREF(mod);
6688 return NULL;
6689 }
6690
6691 return mod;
Tim Peters2a799bf2002-12-16 20:18:38 +00006692}
Tim Petersf3615152003-01-01 21:51:37 +00006693
6694/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006695Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006696 x.n = x stripped of its timezone -- its naive time.
6697 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006698 return None
Tim Petersf3615152003-01-01 21:51:37 +00006699 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006700 return None
Tim Petersf3615152003-01-01 21:51:37 +00006701 x.s = x's standard offset, x.o - x.d
6702
6703Now some derived rules, where k is a duration (timedelta).
6704
67051. x.o = x.s + x.d
6706 This follows from the definition of x.s.
6707
Tim Petersc5dc4da2003-01-02 17:55:03 +000067082. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006709 This is actually a requirement, an assumption we need to make about
6710 sane tzinfo classes.
6711
67123. The naive UTC time corresponding to x is x.n - x.o.
6713 This is again a requirement for a sane tzinfo class.
6714
67154. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006716 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006717
Tim Petersc5dc4da2003-01-02 17:55:03 +000067185. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006719 Again follows from how arithmetic is defined.
6720
Tim Peters8bb5ad22003-01-24 02:44:45 +00006721Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006722(meaning that the various tzinfo methods exist, and don't blow up or return
6723None when called).
6724
Tim Petersa9bc1682003-01-11 03:39:11 +00006725The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006726x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006727
6728By #3, we want
6729
Tim Peters8bb5ad22003-01-24 02:44:45 +00006730 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006731
6732The algorithm starts by attaching tz to x.n, and calling that y. So
6733x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6734becomes true; in effect, we want to solve [2] for k:
6735
Tim Peters8bb5ad22003-01-24 02:44:45 +00006736 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006737
6738By #1, this is the same as
6739
Tim Peters8bb5ad22003-01-24 02:44:45 +00006740 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006741
6742By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6743Substituting that into [3],
6744
Tim Peters8bb5ad22003-01-24 02:44:45 +00006745 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6746 k - (y+k).s - (y+k).d = 0; rearranging,
6747 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6748 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006749
Tim Peters8bb5ad22003-01-24 02:44:45 +00006750On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6751approximate k by ignoring the (y+k).d term at first. Note that k can't be
6752very large, since all offset-returning methods return a duration of magnitude
6753less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6754be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006755
6756In any case, the new value is
6757
Tim Peters8bb5ad22003-01-24 02:44:45 +00006758 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006759
Tim Peters8bb5ad22003-01-24 02:44:45 +00006760It's helpful to step back at look at [4] from a higher level: it's simply
6761mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006762
6763At this point, if
6764
Tim Peters8bb5ad22003-01-24 02:44:45 +00006765 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006766
6767we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006768at the start of daylight time. Picture US Eastern for concreteness. The wall
6769time 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 +00006770sense then. The docs ask that an Eastern tzinfo class consider such a time to
6771be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6772on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006773the only spelling that makes sense on the local wall clock.
6774
Tim Petersc5dc4da2003-01-02 17:55:03 +00006775In fact, if [5] holds at this point, we do have the standard-time spelling,
6776but that takes a bit of proof. We first prove a stronger result. What's the
6777difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006778
Tim Peters8bb5ad22003-01-24 02:44:45 +00006779 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006780
Tim Petersc5dc4da2003-01-02 17:55:03 +00006781Now
6782 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006783 (y + y.s).n = by #5
6784 y.n + y.s = since y.n = x.n
6785 x.n + y.s = since z and y are have the same tzinfo member,
6786 y.s = z.s by #2
6787 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006788
Tim Petersc5dc4da2003-01-02 17:55:03 +00006789Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006790
Tim Petersc5dc4da2003-01-02 17:55:03 +00006791 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006792 x.n - ((x.n + z.s) - z.o) = expanding
6793 x.n - x.n - z.s + z.o = cancelling
6794 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006795 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006796
Tim Petersc5dc4da2003-01-02 17:55:03 +00006797So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006798
Tim Petersc5dc4da2003-01-02 17:55:03 +00006799If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006800spelling we wanted in the endcase described above. We're done. Contrarily,
6801if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006802
Tim Petersc5dc4da2003-01-02 17:55:03 +00006803If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6804add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006805local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006806
Tim Petersc5dc4da2003-01-02 17:55:03 +00006807Let
Tim Petersf3615152003-01-01 21:51:37 +00006808
Tim Peters4fede1a2003-01-04 00:26:59 +00006809 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006810
Tim Peters4fede1a2003-01-04 00:26:59 +00006811and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006812
Tim Peters8bb5ad22003-01-24 02:44:45 +00006813 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006814
Tim Peters8bb5ad22003-01-24 02:44:45 +00006815If so, we're done. If not, the tzinfo class is insane, according to the
6816assumptions we've made. This also requires a bit of proof. As before, let's
6817compute the difference between the LHS and RHS of [8] (and skipping some of
6818the justifications for the kinds of substitutions we've done several times
6819already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006820
Tim Peters8bb5ad22003-01-24 02:44:45 +00006821 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006822 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6823 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6824 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6825 - z.n + z.n - z.o + z'.o = cancel z.n
6826 - z.o + z'.o = #1 twice
6827 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6828 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006829
6830So 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 +00006831we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6832return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006833
Tim Peters8bb5ad22003-01-24 02:44:45 +00006834How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6835a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6836would have to change the result dst() returns: we start in DST, and moving
6837a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006838
Tim Peters8bb5ad22003-01-24 02:44:45 +00006839There isn't a sane case where this can happen. The closest it gets is at
6840the end of DST, where there's an hour in UTC with no spelling in a hybrid
6841tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6842that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6843UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6844time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6845clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6846standard time. Since that's what the local clock *does*, we want to map both
6847UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006848in local time, but so it goes -- it's the way the local clock works.
6849
Tim Peters8bb5ad22003-01-24 02:44:45 +00006850When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6851so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6852z' = 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 +00006853(correctly) concludes that z' is not UTC-equivalent to x.
6854
6855Because we know z.d said z was in daylight time (else [5] would have held and
6856we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006857and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006858return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6859but the reasoning doesn't depend on the example -- it depends on there being
6860two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006861z' must be in standard time, and is the spelling we want in this case.
6862
6863Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6864concerned (because it takes z' as being in standard time rather than the
6865daylight time we intend here), but returning it gives the real-life "local
6866clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6867tz.
6868
6869When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6870the 1:MM standard time spelling we want.
6871
6872So how can this break? One of the assumptions must be violated. Two
6873possibilities:
6874
68751) [2] effectively says that y.s is invariant across all y belong to a given
6876 time zone. This isn't true if, for political reasons or continental drift,
6877 a region decides to change its base offset from UTC.
6878
68792) There may be versions of "double daylight" time where the tail end of
6880 the analysis gives up a step too early. I haven't thought about that
6881 enough to say.
6882
6883In any case, it's clear that the default fromutc() is strong enough to handle
6884"almost all" time zones: so long as the standard offset is invariant, it
6885doesn't matter if daylight time transition points change from year to year, or
6886if daylight time is skipped in some years; it doesn't matter how large or
6887small dst() may get within its bounds; and it doesn't even matter if some
6888perverse time zone returns a negative dst()). So a breaking case must be
6889pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006890--------------------------------------------------------------------------- */