blob: 9477f776138c3bad83294f42aa147f9ae2284924 [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
5#include "Python.h"
Tim Peters2a799bf2002-12-16 20:18:38 +00006#include "structmember.h"
7
8#include <time.h>
9
Victor Stinner09e5cf22015-03-30 00:09:18 +020010#ifdef MS_WINDOWS
11# include <winsock2.h> /* struct timeval */
12#endif
13
Tim Peters9ddf40b2004-06-20 22:41:32 +000014/* Differentiate between building the core module and building extension
15 * modules.
16 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000017#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000018#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000019#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000020#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000021#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000022
Larry Hastings61272b72014-01-07 12:41:53 -080023/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080024module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080025class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Larry Hastings61272b72014-01-07 12:41:53 -080026[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -080027/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080028
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030029#include "clinic/_datetimemodule.c.h"
30
Tim Peters2a799bf2002-12-16 20:18:38 +000031/* We require that C int be at least 32 bits, and use int virtually
32 * everywhere. In just a few cases we use a temp long, where a Python
33 * API returns a C long. In such cases, we have to ensure that the
34 * final result fits in a C int (this can be an issue on 64-bit boxes).
35 */
36#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000037# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000038#endif
39
40#define MINYEAR 1
41#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000042#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000043
44/* Nine decimal digits is easy to communicate, and leaves enough room
45 * so that two delta days can be added w/o fear of overflowing a signed
46 * 32-bit int, and with plenty of room left over to absorb any possible
47 * carries from adding seconds.
48 */
49#define MAX_DELTA_DAYS 999999999
50
51/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define GET_YEAR PyDateTime_GET_YEAR
53#define GET_MONTH PyDateTime_GET_MONTH
54#define GET_DAY PyDateTime_GET_DAY
55#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
56#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
57#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
58#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040059#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000060
61/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
63 ((o)->data[1] = ((v) & 0x00ff)))
64#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
65#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000066
67/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
69#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
70#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
71#define DATE_SET_MICROSECOND(o, v) \
72 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
73 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
74 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040075#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000076
77/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
79#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
80#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
81#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040082#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
84#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
85#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
86#define TIME_SET_MICROSECOND(o, v) \
87 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
88 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
89 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040090#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000091
92/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
94#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
95#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097#define SET_TD_DAYS(o, v) ((o)->days = (v))
98#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000099#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
100
Tim Petersa032d2e2003-01-11 00:15:54 +0000101/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
102 * p->hastzinfo.
103 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000104#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
105#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
106 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
107#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
108 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000109/* M is a char or int claiming to be a valid month. The macro is equivalent
110 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000112 */
113#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
114
Tim Peters2a799bf2002-12-16 20:18:38 +0000115/* Forward declarations. */
116static PyTypeObject PyDateTime_DateType;
117static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000118static PyTypeObject PyDateTime_DeltaType;
119static PyTypeObject PyDateTime_TimeType;
120static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000121static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000122
Victor Stinnerb67f0962017-02-10 10:34:02 +0100123static int check_tzinfo_subclass(PyObject *p);
124
Martin v. Löwise75fc142013-11-07 18:46:53 +0100125_Py_IDENTIFIER(as_integer_ratio);
126_Py_IDENTIFIER(fromutc);
127_Py_IDENTIFIER(isoformat);
128_Py_IDENTIFIER(strftime);
129
Tim Peters2a799bf2002-12-16 20:18:38 +0000130/* ---------------------------------------------------------------------------
131 * Math utilities.
132 */
133
134/* k = i+j overflows iff k differs in sign from both inputs,
135 * iff k^i has sign bit set and k^j has sign bit set,
136 * iff (k^i)&(k^j) has sign bit set.
137 */
138#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000140
141/* Compute Python divmod(x, y), returning the quotient and storing the
142 * remainder into *r. The quotient is the floor of x/y, and that's
143 * the real point of this. C will probably truncate instead (C99
144 * requires truncation; C89 left it implementation-defined).
145 * Simplification: we *require* that y > 0 here. That's appropriate
146 * for all the uses made of it. This simplifies the code and makes
147 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
148 * overflow case).
149 */
150static int
151divmod(int x, int y, int *r)
152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 assert(y > 0);
156 quo = x / y;
157 *r = x - quo * y;
158 if (*r < 0) {
159 --quo;
160 *r += y;
161 }
162 assert(0 <= *r && *r < y);
163 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000164}
165
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000166/* Nearest integer to m / n for integers m and n. Half-integer results
167 * are rounded to even.
168 */
169static PyObject *
170divide_nearest(PyObject *m, PyObject *n)
171{
172 PyObject *result;
173 PyObject *temp;
174
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000175 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000176 if (temp == NULL)
177 return NULL;
178 result = PyTuple_GET_ITEM(temp, 0);
179 Py_INCREF(result);
180 Py_DECREF(temp);
181
182 return result;
183}
184
Tim Peters2a799bf2002-12-16 20:18:38 +0000185/* ---------------------------------------------------------------------------
186 * General calendrical helper functions
187 */
188
189/* For each month ordinal in 1..12, the number of days in that month,
190 * and the number of days before that month in the same year. These
191 * are correct for non-leap years only.
192 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200193static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 0, /* unused; this vector uses 1-based indexing */
195 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000196};
197
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200198static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 0, /* unused; this vector uses 1-based indexing */
200 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000201};
202
203/* year -> 1 if leap year, else 0. */
204static int
205is_leap(int year)
206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* Cast year to unsigned. The result is the same either way, but
208 * C can generate faster code for unsigned mod than for signed
209 * mod (especially for % 4 -- a good compiler should just grab
210 * the last 2 bits when the LHS is unsigned).
211 */
212 const unsigned int ayear = (unsigned int)year;
213 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000214}
215
216/* year, month -> number of days in that month in that year */
217static int
218days_in_month(int year, int month)
219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 assert(month >= 1);
221 assert(month <= 12);
222 if (month == 2 && is_leap(year))
223 return 29;
224 else
225 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000226}
227
Martin Panter46f50722016-05-26 05:35:26 +0000228/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000229static int
230days_before_month(int year, int month)
231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 assert(month >= 1);
235 assert(month <= 12);
236 days = _days_before_month[month];
237 if (month > 2 && is_leap(year))
238 ++days;
239 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000240}
241
242/* year -> number of days before January 1st of year. Remember that we
243 * start with year 1, so days_before_year(1) == 0.
244 */
245static int
246days_before_year(int year)
247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 int y = year - 1;
249 /* This is incorrect if year <= 0; we really want the floor
250 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000251 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000253 assert (year >= 1);
254 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000255}
256
257/* Number of days in 4, 100, and 400 year cycles. That these have
258 * the correct values is asserted in the module init function.
259 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260#define DI4Y 1461 /* days_before_year(5); days in 4 years */
261#define DI100Y 36524 /* days_before_year(101); days in 100 years */
262#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000263
264/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
265static void
266ord_to_ymd(int ordinal, int *year, int *month, int *day)
267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
271 * leap years repeats exactly every 400 years. The basic strategy is
272 * to find the closest 400-year boundary at or before ordinal, then
273 * work with the offset from that boundary to ordinal. Life is much
274 * clearer if we subtract 1 from ordinal first -- then the values
275 * of ordinal at 400-year boundaries are exactly those divisible
276 * by DI400Y:
277 *
278 * D M Y n n-1
279 * -- --- ---- ---------- ----------------
280 * 31 Dec -400 -DI400Y -DI400Y -1
281 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
282 * ...
283 * 30 Dec 000 -1 -2
284 * 31 Dec 000 0 -1
285 * 1 Jan 001 1 0 400-year boundary
286 * 2 Jan 001 2 1
287 * 3 Jan 001 3 2
288 * ...
289 * 31 Dec 400 DI400Y DI400Y -1
290 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
291 */
292 assert(ordinal >= 1);
293 --ordinal;
294 n400 = ordinal / DI400Y;
295 n = ordinal % DI400Y;
296 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 /* Now n is the (non-negative) offset, in days, from January 1 of
299 * year, to the desired date. Now compute how many 100-year cycles
300 * precede n.
301 * Note that it's possible for n100 to equal 4! In that case 4 full
302 * 100-year cycles precede the desired day, which implies the
303 * desired day is December 31 at the end of a 400-year cycle.
304 */
305 n100 = n / DI100Y;
306 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 /* Now compute how many 4-year cycles precede it. */
309 n4 = n / DI4Y;
310 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 /* And now how many single years. Again n1 can be 4, and again
313 * meaning that the desired day is December 31 at the end of the
314 * 4-year cycle.
315 */
316 n1 = n / 365;
317 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 *year += n100 * 100 + n4 * 4 + n1;
320 if (n1 == 4 || n100 == 4) {
321 assert(n == 0);
322 *year -= 1;
323 *month = 12;
324 *day = 31;
325 return;
326 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 /* Now the year is correct, and n is the offset from January 1. We
329 * find the month via an estimate that's either exact or one too
330 * large.
331 */
332 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
333 assert(leapyear == is_leap(*year));
334 *month = (n + 50) >> 5;
335 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
336 if (preceding > n) {
337 /* estimate is too large */
338 *month -= 1;
339 preceding -= days_in_month(*year, *month);
340 }
341 n -= preceding;
342 assert(0 <= n);
343 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000346}
347
348/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
349static int
350ymd_to_ord(int year, int month, int day)
351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000353}
354
355/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
356static int
357weekday(int year, int month, int day)
358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000360}
361
362/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
363 * first calendar week containing a Thursday.
364 */
365static int
366iso_week1_monday(int year)
367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
369 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
370 int first_weekday = (first_day + 6) % 7;
371 /* ordinal of closest Monday at or before 1/1 */
372 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
375 week1_monday += 7;
376 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000377}
378
379/* ---------------------------------------------------------------------------
380 * Range checkers.
381 */
382
383/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
384 * If not, raise OverflowError and return -1.
385 */
386static int
387check_delta_day_range(int days)
388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
390 return 0;
391 PyErr_Format(PyExc_OverflowError,
392 "days=%d; must have magnitude <= %d",
393 days, MAX_DELTA_DAYS);
394 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000395}
396
397/* Check that date arguments are in range. Return 0 if they are. If they
398 * aren't, raise ValueError and return -1.
399 */
400static int
401check_date_args(int year, int month, int day)
402{
403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 if (year < MINYEAR || year > MAXYEAR) {
Victor Stinnerb67f0962017-02-10 10:34:02 +0100405 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 return -1;
407 }
408 if (month < 1 || month > 12) {
409 PyErr_SetString(PyExc_ValueError,
410 "month must be in 1..12");
411 return -1;
412 }
413 if (day < 1 || day > days_in_month(year, month)) {
414 PyErr_SetString(PyExc_ValueError,
415 "day is out of range for month");
416 return -1;
417 }
418 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000419}
420
421/* Check that time arguments are in range. Return 0 if they are. If they
422 * aren't, raise ValueError and return -1.
423 */
424static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400425check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 if (h < 0 || h > 23) {
428 PyErr_SetString(PyExc_ValueError,
429 "hour must be in 0..23");
430 return -1;
431 }
432 if (m < 0 || m > 59) {
433 PyErr_SetString(PyExc_ValueError,
434 "minute must be in 0..59");
435 return -1;
436 }
437 if (s < 0 || s > 59) {
438 PyErr_SetString(PyExc_ValueError,
439 "second must be in 0..59");
440 return -1;
441 }
442 if (us < 0 || us > 999999) {
443 PyErr_SetString(PyExc_ValueError,
444 "microsecond must be in 0..999999");
445 return -1;
446 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400447 if (fold != 0 && fold != 1) {
448 PyErr_SetString(PyExc_ValueError,
449 "fold must be either 0 or 1");
450 return -1;
451 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000453}
454
455/* ---------------------------------------------------------------------------
456 * Normalization utilities.
457 */
458
459/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
460 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
461 * at least factor, enough of *lo is converted into "hi" units so that
462 * 0 <= *lo < factor. The input values must be such that int overflow
463 * is impossible.
464 */
465static void
466normalize_pair(int *hi, int *lo, int factor)
467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 assert(factor > 0);
469 assert(lo != hi);
470 if (*lo < 0 || *lo >= factor) {
471 const int num_hi = divmod(*lo, factor, lo);
472 const int new_hi = *hi + num_hi;
473 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
474 *hi = new_hi;
475 }
476 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000477}
478
479/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 * 0 <= *s < 24*3600
481 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000482 * The input values must be such that the internals don't overflow.
483 * The way this routine is used, we don't get close.
484 */
485static void
486normalize_d_s_us(int *d, int *s, int *us)
487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 if (*us < 0 || *us >= 1000000) {
489 normalize_pair(s, us, 1000000);
490 /* |s| can't be bigger than about
491 * |original s| + |original us|/1000000 now.
492 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 }
495 if (*s < 0 || *s >= 24*3600) {
496 normalize_pair(d, s, 24*3600);
497 /* |d| can't be bigger than about
498 * |original d| +
499 * (|original s| + |original us|/1000000) / (24*3600) now.
500 */
501 }
502 assert(0 <= *s && *s < 24*3600);
503 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000504}
505
506/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 * 1 <= *m <= 12
508 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000509 * The input values must be such that the internals don't overflow.
510 * The way this routine is used, we don't get close.
511 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000512static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000513normalize_y_m_d(int *y, int *m, int *d)
514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000516
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000517 /* In actual use, m is always the month component extracted from a
518 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 /* Now only day can be out of bounds (year may also be out of bounds
524 * for a datetime object, but we don't care about that here).
525 * If day is out of bounds, what to do is arguable, but at least the
526 * method here is principled and explainable.
527 */
528 dim = days_in_month(*y, *m);
529 if (*d < 1 || *d > dim) {
530 /* Move day-1 days from the first of the month. First try to
531 * get off cheap if we're only one day out of range
532 * (adjustments for timezone alone can't be worse than that).
533 */
534 if (*d == 0) {
535 --*m;
536 if (*m > 0)
537 *d = days_in_month(*y, *m);
538 else {
539 --*y;
540 *m = 12;
541 *d = 31;
542 }
543 }
544 else if (*d == dim + 1) {
545 /* move forward a day */
546 ++*m;
547 *d = 1;
548 if (*m > 12) {
549 *m = 1;
550 ++*y;
551 }
552 }
553 else {
554 int ordinal = ymd_to_ord(*y, *m, 1) +
555 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000556 if (ordinal < 1 || ordinal > MAXORDINAL) {
557 goto error;
558 } else {
559 ord_to_ymd(ordinal, y, m, d);
560 return 0;
561 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 }
563 }
564 assert(*m > 0);
565 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000566 if (MINYEAR <= *y && *y <= MAXYEAR)
567 return 0;
568 error:
569 PyErr_SetString(PyExc_OverflowError,
570 "date value out of range");
571 return -1;
572
Tim Peters2a799bf2002-12-16 20:18:38 +0000573}
574
575/* Fiddle out-of-bounds months and days so that the result makes some kind
576 * of sense. The parameters are both inputs and outputs. Returns < 0 on
577 * failure, where failure means the adjusted year is out of bounds.
578 */
579static int
580normalize_date(int *year, int *month, int *day)
581{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000582 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000583}
584
585/* Force all the datetime fields into range. The parameters are both
586 * inputs and outputs. Returns < 0 on error.
587 */
588static int
589normalize_datetime(int *year, int *month, int *day,
590 int *hour, int *minute, int *second,
591 int *microsecond)
592{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 normalize_pair(second, microsecond, 1000000);
594 normalize_pair(minute, second, 60);
595 normalize_pair(hour, minute, 60);
596 normalize_pair(day, hour, 24);
597 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000598}
599
600/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000601 * Basic object allocation: tp_alloc implementations. These allocate
602 * Python objects of the right size and type, and do the Python object-
603 * initialization bit. If there's not enough memory, they return NULL after
604 * setting MemoryError. All data members remain uninitialized trash.
605 *
606 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000607 * member is needed. This is ugly, imprecise, and possibly insecure.
608 * tp_basicsize for the time and datetime types is set to the size of the
609 * struct that has room for the tzinfo member, so subclasses in Python will
610 * allocate enough space for a tzinfo member whether or not one is actually
611 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
612 * part is that PyType_GenericAlloc() (which subclasses in Python end up
613 * using) just happens today to effectively ignore the nitems argument
614 * when tp_itemsize is 0, which it is for these type objects. If that
615 * changes, perhaps the callers of tp_alloc slots in this file should
616 * be changed to force a 0 nitems argument unless the type being allocated
617 * is a base type implemented in this file (so that tp_alloc is time_alloc
618 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000619 */
620
621static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000622time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 self = (PyObject *)
627 PyObject_MALLOC(aware ?
628 sizeof(PyDateTime_Time) :
629 sizeof(_PyDateTime_BaseTime));
630 if (self == NULL)
631 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100632 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000634}
635
636static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000637datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 self = (PyObject *)
642 PyObject_MALLOC(aware ?
643 sizeof(PyDateTime_DateTime) :
644 sizeof(_PyDateTime_BaseDateTime));
645 if (self == NULL)
646 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100647 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000649}
650
651/* ---------------------------------------------------------------------------
652 * Helpers for setting object fields. These work on pointers to the
653 * appropriate base class.
654 */
655
656/* For date and datetime. */
657static void
658set_date_fields(PyDateTime_Date *self, int y, int m, int d)
659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 self->hashcode = -1;
661 SET_YEAR(self, y);
662 SET_MONTH(self, m);
663 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000664}
665
666/* ---------------------------------------------------------------------------
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500667 * String parsing utilities and helper functions
668 */
669
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700670static const char *
671parse_digits(const char *ptr, int *var, size_t num_digits)
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500672{
673 for (size_t i = 0; i < num_digits; ++i) {
674 unsigned int tmp = (unsigned int)(*(ptr++) - '0');
675 if (tmp > 9) {
676 return NULL;
677 }
678 *var *= 10;
679 *var += (signed int)tmp;
680 }
681
682 return ptr;
683}
684
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700685static int
686parse_isoformat_date(const char *dtstr, int *year, int *month, int *day)
687{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500688 /* Parse the date components of the result of date.isoformat()
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700689 *
690 * Return codes:
691 * 0: Success
692 * -1: Failed to parse date component
693 * -2: Failed to parse dateseparator
694 */
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500695 const char *p = dtstr;
696 p = parse_digits(p, year, 4);
697 if (NULL == p) {
698 return -1;
699 }
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100700
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500701 if (*(p++) != '-') {
702 return -2;
703 }
704
705 p = parse_digits(p, month, 2);
706 if (NULL == p) {
707 return -1;
708 }
709
710 if (*(p++) != '-') {
711 return -2;
712 }
713
714 p = parse_digits(p, day, 2);
715 if (p == NULL) {
716 return -1;
717 }
718
719 return 0;
720}
721
722static int
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700723parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
724 int *minute, int *second, int *microsecond)
725{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500726 const char *p = tstr;
727 const char *p_end = tstr_end;
728 int *vals[3] = {hour, minute, second};
729
730 // Parse [HH[:MM[:SS]]]
731 for (size_t i = 0; i < 3; ++i) {
732 p = parse_digits(p, vals[i], 2);
733 if (NULL == p) {
734 return -3;
735 }
736
737 char c = *(p++);
738 if (p >= p_end) {
739 return c != '\0';
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700740 }
741 else if (c == ':') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500742 continue;
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700743 }
744 else if (c == '.') {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500745 break;
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700746 }
747 else {
748 return -4; // Malformed time separator
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500749 }
750 }
751
752 // Parse .fff[fff]
753 size_t len_remains = p_end - p;
754 if (!(len_remains == 6 || len_remains == 3)) {
755 return -3;
756 }
757
758 p = parse_digits(p, microsecond, len_remains);
759 if (NULL == p) {
760 return -3;
761 }
762
763 if (len_remains == 3) {
764 *microsecond *= 1000;
765 }
766
767 // Return 1 if it's not the end of the string
768 return *p != '\0';
769}
770
771static int
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700772parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
773 int *second, int *microsecond, int *tzoffset,
774 int *tzmicrosecond)
775{
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500776 // Parse the time portion of a datetime.isoformat() string
777 //
778 // Return codes:
779 // 0: Success (no tzoffset)
780 // 1: Success (with tzoffset)
781 // -3: Failed to parse time component
782 // -4: Failed to parse time separator
783 // -5: Malformed timezone string
784
785 const char *p = dtstr;
786 const char *p_end = dtstr + dtlen;
787
788 const char *tzinfo_pos = p;
789 do {
790 if (*tzinfo_pos == '+' || *tzinfo_pos == '-') {
791 break;
792 }
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700793 } while (++tzinfo_pos < p_end);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500794
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700795 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second,
796 microsecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500797
798 if (rv < 0) {
799 return rv;
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700800 }
801 else if (tzinfo_pos == p_end) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500802 // We know that there's no time zone, so if there's stuff at the
803 // end of the string it's an error.
804 if (rv == 1) {
805 return -5;
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700806 }
807 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500808 return 0;
809 }
810 }
811
812 // Parse time zone component
813 // Valid formats are:
814 // - +HH:MM (len 6)
815 // - +HH:MM:SS (len 9)
816 // - +HH:MM:SS.ffffff (len 16)
817 size_t tzlen = p_end - tzinfo_pos;
818 if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) {
819 return -5;
820 }
821
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700822 int tzsign = (*tzinfo_pos == '-') ? -1 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500823 tzinfo_pos++;
824 int tzhour = 0, tzminute = 0, tzsecond = 0;
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700825 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond,
826 tzmicrosecond);
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500827
828 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
829 *tzmicrosecond *= tzsign;
830
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700831 return rv ? -5 : 1;
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500832}
833
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500834/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000835 * Create various objects, mostly without range checking.
836 */
837
838/* Create a date instance with no range checking. */
839static PyObject *
840new_date_ex(int year, int month, int day, PyTypeObject *type)
841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000843
Victor Stinnerb67f0962017-02-10 10:34:02 +0100844 if (check_date_args(year, month, day) < 0) {
845 return NULL;
846 }
847
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700848 self = (PyDateTime_Date *)(type->tp_alloc(type, 0));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 if (self != NULL)
850 set_date_fields(self, year, month, day);
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700851 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000852}
853
854#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000856
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500857// Forward declaration
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700858static PyObject *
859new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500860
861/* Create date instance with no range checking, or call subclass constructor */
862static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700863new_date_subclass_ex(int year, int month, int day, PyObject *cls)
864{
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500865 PyObject *result;
866 // We have "fast path" constructors for two subclasses: date and datetime
867 if ((PyTypeObject *)cls == &PyDateTime_DateType) {
868 result = new_date_ex(year, month, day, (PyTypeObject *)cls);
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700869 }
870 else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500871 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
872 (PyTypeObject *)cls);
Miss Islington (bot)18450be2018-10-22 15:35:15 -0700873 }
874 else {
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500875 result = PyObject_CallFunction(cls, "iii", year, month, day);
876 }
877
878 return result;
879}
880
Tim Petersb0c854d2003-05-17 15:57:00 +0000881/* Create a datetime instance with no range checking. */
882static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400883new_datetime_ex2(int year, int month, int day, int hour, int minute,
884 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000885{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 PyDateTime_DateTime *self;
887 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000888
Victor Stinnerb67f0962017-02-10 10:34:02 +0100889 if (check_date_args(year, month, day) < 0) {
890 return NULL;
891 }
892 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
893 return NULL;
894 }
895 if (check_tzinfo_subclass(tzinfo) < 0) {
896 return NULL;
897 }
898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
900 if (self != NULL) {
901 self->hastzinfo = aware;
902 set_date_fields((PyDateTime_Date *)self, year, month, day);
903 DATE_SET_HOUR(self, hour);
904 DATE_SET_MINUTE(self, minute);
905 DATE_SET_SECOND(self, second);
906 DATE_SET_MICROSECOND(self, usecond);
907 if (aware) {
908 Py_INCREF(tzinfo);
909 self->tzinfo = tzinfo;
910 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400911 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 }
913 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000914}
915
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400916static PyObject *
917new_datetime_ex(int year, int month, int day, int hour, int minute,
918 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
919{
920 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
921 tzinfo, 0, type);
922}
923
924#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
925 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000927
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500928static PyObject *
929new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
930 int second, int usecond, PyObject *tzinfo,
931 int fold, PyObject *cls) {
932 PyObject* dt;
933 if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) {
934 // Use the fast path constructor
935 dt = new_datetime(year, month, day, hour, minute, second, usecond,
936 tzinfo, fold);
937 } else {
938 // Subclass
939 dt = PyObject_CallFunction(cls, "iiiiiiiO",
940 year,
941 month,
942 day,
943 hour,
944 minute,
945 second,
946 usecond,
947 tzinfo);
948 }
949
950 return dt;
951}
952
953static PyObject *
954new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
955 int second, int usecond, PyObject *tzinfo,
956 PyObject *cls) {
957 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
958 second, usecond, tzinfo, 0,
959 cls);
960}
961
Tim Petersb0c854d2003-05-17 15:57:00 +0000962/* Create a time instance with no range checking. */
963static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400964new_time_ex2(int hour, int minute, int second, int usecond,
965 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000966{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 PyDateTime_Time *self;
968 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000969
Victor Stinnerb67f0962017-02-10 10:34:02 +0100970 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
971 return NULL;
972 }
973 if (check_tzinfo_subclass(tzinfo) < 0) {
974 return NULL;
975 }
976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
978 if (self != NULL) {
979 self->hastzinfo = aware;
980 self->hashcode = -1;
981 TIME_SET_HOUR(self, hour);
982 TIME_SET_MINUTE(self, minute);
983 TIME_SET_SECOND(self, second);
984 TIME_SET_MICROSECOND(self, usecond);
985 if (aware) {
986 Py_INCREF(tzinfo);
987 self->tzinfo = tzinfo;
988 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400989 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 }
991 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000992}
993
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400994static PyObject *
995new_time_ex(int hour, int minute, int second, int usecond,
996 PyObject *tzinfo, PyTypeObject *type)
997{
998 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
999}
1000
1001#define new_time(hh, mm, ss, us, tzinfo, fold) \
1002 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001003
1004/* Create a timedelta instance. Normalize the members iff normalize is
1005 * true. Passing false is a speed optimization, if you know for sure
1006 * that seconds and microseconds are already in their proper ranges. In any
1007 * case, raises OverflowError and returns NULL if the normalized days is out
1008 * of range).
1009 */
1010static PyObject *
1011new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +00001013{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 if (normalize)
1017 normalize_d_s_us(&days, &seconds, &microseconds);
1018 assert(0 <= seconds && seconds < 24*3600);
1019 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +00001020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 if (check_delta_day_range(days) < 0)
1022 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +00001023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1025 if (self != NULL) {
1026 self->hashcode = -1;
1027 SET_TD_DAYS(self, days);
1028 SET_TD_SECONDS(self, seconds);
1029 SET_TD_MICROSECONDS(self, microseconds);
1030 }
1031 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001032}
1033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034#define new_delta(d, s, us, normalize) \
1035 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001036
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001037
1038typedef struct
1039{
1040 PyObject_HEAD
1041 PyObject *offset;
1042 PyObject *name;
1043} PyDateTime_TimeZone;
1044
Victor Stinner6ced7c42011-03-21 18:15:42 +01001045/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001046static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -04001047/* The interned Epoch datetime instance */
1048static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00001049
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001050/* Create new timezone instance checking offset range. This
1051 function does not check the name argument. Caller must assure
1052 that offset is a timedelta instance and name is either NULL
1053 or a unicode object. */
1054static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001055create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001056{
1057 PyDateTime_TimeZone *self;
1058 PyTypeObject *type = &PyDateTime_TimeZoneType;
1059
1060 assert(offset != NULL);
1061 assert(PyDelta_Check(offset));
1062 assert(name == NULL || PyUnicode_Check(name));
1063
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001064 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1065 if (self == NULL) {
1066 return NULL;
1067 }
1068 Py_INCREF(offset);
1069 self->offset = offset;
1070 Py_XINCREF(name);
1071 self->name = name;
1072 return (PyObject *)self;
1073}
1074
1075static int delta_bool(PyDateTime_Delta *self);
1076
1077static PyObject *
1078new_timezone(PyObject *offset, PyObject *name)
1079{
1080 assert(offset != NULL);
1081 assert(PyDelta_Check(offset));
1082 assert(name == NULL || PyUnicode_Check(name));
1083
1084 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
1085 Py_INCREF(PyDateTime_TimeZone_UTC);
1086 return PyDateTime_TimeZone_UTC;
1087 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001088 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1089 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1090 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1091 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04001092 " timedelta(hours=24),"
1093 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001094 return NULL;
1095 }
1096
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001097 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001098}
1099
Tim Petersb0c854d2003-05-17 15:57:00 +00001100/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001101 * tzinfo helpers.
1102 */
1103
Tim Peters855fe882002-12-22 03:43:39 +00001104/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
1105 * raise TypeError and return -1.
1106 */
1107static int
1108check_tzinfo_subclass(PyObject *p)
1109{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 if (p == Py_None || PyTZInfo_Check(p))
1111 return 0;
1112 PyErr_Format(PyExc_TypeError,
1113 "tzinfo argument must be None or of a tzinfo subclass, "
1114 "not type '%s'",
1115 Py_TYPE(p)->tp_name);
1116 return -1;
Tim Peters855fe882002-12-22 03:43:39 +00001117}
1118
Tim Peters2a799bf2002-12-16 20:18:38 +00001119/* If self has a tzinfo member, return a BORROWED reference to it. Else
1120 * return NULL, which is NOT AN ERROR. There are no error returns here,
1121 * and the caller must not decref the result.
1122 */
1123static PyObject *
1124get_tzinfo_member(PyObject *self)
1125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 if (PyDateTime_Check(self) && HASTZINFO(self))
1129 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1130 else if (PyTime_Check(self) && HASTZINFO(self))
1131 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001134}
1135
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001136/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
1137 * be an instance of the tzinfo class. If the method returns None, this
1138 * returns None. If the method doesn't return None or timedelta, TypeError is
1139 * raised and this returns NULL. If it returns a timedelta and the value is
1140 * out of range or isn't a whole number of minutes, ValueError is raised and
1141 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +00001142 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001143static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001144call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001145{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001146 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001149 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001151
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001152 if (tzinfo == Py_None)
1153 Py_RETURN_NONE;
1154 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1155 if (offset == Py_None || offset == NULL)
1156 return offset;
1157 if (PyDelta_Check(offset)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001158 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1159 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1160 Py_DECREF(offset);
1161 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1162 " strictly between -timedelta(hours=24) and"
1163 " timedelta(hours=24).");
1164 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 }
1166 }
1167 else {
1168 PyErr_Format(PyExc_TypeError,
1169 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001170 "timedelta, not '%.200s'",
1171 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07001172 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001173 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001175
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001176 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001177}
1178
1179/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1180 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
1181 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +00001182 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001183 * If utcoffset() returns an out of range timedelta,
1184 * ValueError is raised and this returns -1. Else *none is
1185 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001186 */
Tim Peters855fe882002-12-22 03:43:39 +00001187static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001188call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1189{
1190 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001191}
1192
Tim Peters2a799bf2002-12-16 20:18:38 +00001193/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1194 * result. tzinfo must be an instance of the tzinfo class. If dst()
1195 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001196 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00001197 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +00001198 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001199 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001200 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001201static PyObject *
1202call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001203{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001204 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001205}
1206
Tim Petersbad8ff02002-12-30 20:52:32 +00001207/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +00001208 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001209 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001210 * returns NULL. If the result is a string, we ensure it is a Unicode
1211 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001212 */
1213static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001214call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001215{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001217 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 assert(tzinfo != NULL);
1220 assert(check_tzinfo_subclass(tzinfo) >= 0);
1221 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001224 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001225
Victor Stinner20401de2016-12-09 15:24:31 +01001226 result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname,
1227 tzinfoarg, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001228
1229 if (result == NULL || result == Py_None)
1230 return result;
1231
1232 if (!PyUnicode_Check(result)) {
1233 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1234 "return None or a string, not '%s'",
1235 Py_TYPE(result)->tp_name);
1236 Py_DECREF(result);
1237 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001239
1240 return result;
Tim Peters00237032002-12-27 02:21:51 +00001241}
1242
Tim Peters2a799bf2002-12-16 20:18:38 +00001243/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1244 * stuff
1245 * ", tzinfo=" + repr(tzinfo)
1246 * before the closing ")".
1247 */
1248static PyObject *
1249append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 assert(PyUnicode_Check(repr));
1254 assert(tzinfo);
1255 if (tzinfo == Py_None)
1256 return repr;
1257 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001258 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1259 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 Py_DECREF(repr);
1261 if (temp == NULL)
1262 return NULL;
1263 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1264 Py_DECREF(temp);
1265 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001266}
1267
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001268/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1269 * stuff
1270 * ", fold=" + repr(tzinfo)
1271 * before the closing ")".
1272 */
1273static PyObject *
1274append_keyword_fold(PyObject *repr, int fold)
1275{
1276 PyObject *temp;
1277
1278 assert(PyUnicode_Check(repr));
1279 if (fold == 0)
1280 return repr;
1281 /* Get rid of the trailing ')'. */
1282 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1283 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1284 Py_DECREF(repr);
1285 if (temp == NULL)
1286 return NULL;
1287 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1288 Py_DECREF(temp);
1289 return repr;
1290}
1291
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001292static inline PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07001293tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds)
1294{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001295 PyObject *tzinfo;
1296 if (rv == 1) {
1297 // Create a timezone from offset in seconds (0 returns UTC)
1298 if (tzoffset == 0) {
1299 Py_INCREF(PyDateTime_TimeZone_UTC);
1300 return PyDateTime_TimeZone_UTC;
1301 }
1302
1303 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
Miss Islington (bot)c7f54352018-08-24 12:13:57 -04001304 if (delta == NULL) {
1305 return NULL;
1306 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001307 tzinfo = new_timezone(delta, NULL);
Miss Islington (bot)c7f54352018-08-24 12:13:57 -04001308 Py_DECREF(delta);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07001309 }
1310 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001311 tzinfo = Py_None;
1312 Py_INCREF(Py_None);
1313 }
1314
1315 return tzinfo;
1316}
1317
Tim Peters2a799bf2002-12-16 20:18:38 +00001318/* ---------------------------------------------------------------------------
1319 * String format helpers.
1320 */
1321
1322static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001323format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001324{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001325 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1327 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001328 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1330 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1331 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1336 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1337 GET_DAY(date), hours, minutes, seconds,
1338 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001339}
1340
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001341static PyObject *delta_negative(PyDateTime_Delta *self);
1342
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001343/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001344 * buflen bytes remaining. The UTC offset is gotten by calling
1345 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1346 * *buf, and that's all. Else the returned value is checked for sanity (an
1347 * integer in range), and if that's OK it's converted to an hours & minutes
1348 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001349 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001350 * Returns 0 if everything is OK. If the return value from utcoffset() is
1351 * bogus, an appropriate exception is set and -1 is returned.
1352 */
1353static int
Tim Peters328fff72002-12-20 01:31:27 +00001354format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001356{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001357 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001358 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001362
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001363 offset = call_utcoffset(tzinfo, tzinfoarg);
1364 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001366 if (offset == Py_None) {
1367 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 *buf = '\0';
1369 return 0;
1370 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001371 /* Offset is normalized, so it is negative if days < 0 */
1372 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001374 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001375 if (offset == NULL)
1376 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001378 else {
1379 sign = '+';
1380 }
1381 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001382 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001383 seconds = GET_TD_SECONDS(offset);
1384 Py_DECREF(offset);
1385 minutes = divmod(seconds, 60, &seconds);
1386 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001387 if (microseconds) {
1388 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1389 hours, sep, minutes, sep, seconds, microseconds);
1390 return 0;
1391 }
1392 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001393 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1394 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001395 return 0;
1396 }
1397 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001399}
1400
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001401static PyObject *
1402make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 PyObject *temp;
1405 PyObject *tzinfo = get_tzinfo_member(object);
1406 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001407 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 if (Zreplacement == NULL)
1410 return NULL;
1411 if (tzinfo == Py_None || tzinfo == NULL)
1412 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 assert(tzinfoarg != NULL);
1415 temp = call_tzname(tzinfo, tzinfoarg);
1416 if (temp == NULL)
1417 goto Error;
1418 if (temp == Py_None) {
1419 Py_DECREF(temp);
1420 return Zreplacement;
1421 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 assert(PyUnicode_Check(temp));
1424 /* Since the tzname is getting stuffed into the
1425 * format, we have to double any % signs so that
1426 * strftime doesn't treat them as format codes.
1427 */
1428 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001429 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 Py_DECREF(temp);
1431 if (Zreplacement == NULL)
1432 return NULL;
1433 if (!PyUnicode_Check(Zreplacement)) {
1434 PyErr_SetString(PyExc_TypeError,
1435 "tzname.replace() did not return a string");
1436 goto Error;
1437 }
1438 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001439
1440 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 Py_DECREF(Zreplacement);
1442 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001443}
1444
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001445static PyObject *
1446make_freplacement(PyObject *object)
1447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 char freplacement[64];
1449 if (PyTime_Check(object))
1450 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1451 else if (PyDateTime_Check(object))
1452 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1453 else
1454 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001457}
1458
Tim Peters2a799bf2002-12-16 20:18:38 +00001459/* I sure don't want to reproduce the strftime code from the time module,
1460 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001461 * giving special meanings to the %z, %Z and %f format codes via a
1462 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001463 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1464 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001465 */
1466static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001467wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1473 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1474 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 const char *pin; /* pointer to next char in input format */
1477 Py_ssize_t flen; /* length of input format */
1478 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 PyObject *newfmt = NULL; /* py string, the output format */
1481 char *pnew; /* pointer to available byte in output format */
1482 size_t totalnew; /* number bytes total in output format buffer,
1483 exclusive of trailing \0 */
1484 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 const char *ptoappend; /* ptr to string to append to output buffer */
1487 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 assert(object && format && timetuple);
1490 assert(PyUnicode_Check(format));
1491 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001492 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 if (!pin)
1494 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 /* Scan the input format, looking for %z/%Z/%f escapes, building
1497 * a new format. Since computing the replacements for those codes
1498 * is expensive, don't unless they're actually used.
1499 */
1500 if (flen > INT_MAX - 1) {
1501 PyErr_NoMemory();
1502 goto Done;
1503 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 totalnew = flen + 1; /* realistic if no %z/%Z */
1506 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1507 if (newfmt == NULL) goto Done;
1508 pnew = PyBytes_AsString(newfmt);
1509 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 while ((ch = *pin++) != '\0') {
1512 if (ch != '%') {
1513 ptoappend = pin - 1;
1514 ntoappend = 1;
1515 }
1516 else if ((ch = *pin++) == '\0') {
1517 /* There's a lone trailing %; doesn't make sense. */
1518 PyErr_SetString(PyExc_ValueError, "strftime format "
1519 "ends with raw %");
1520 goto Done;
1521 }
1522 /* A % has been seen and ch is the character after it. */
1523 else if (ch == 'z') {
1524 if (zreplacement == NULL) {
1525 /* format utcoffset */
1526 char buf[100];
1527 PyObject *tzinfo = get_tzinfo_member(object);
1528 zreplacement = PyBytes_FromStringAndSize("", 0);
1529 if (zreplacement == NULL) goto Done;
1530 if (tzinfo != Py_None && tzinfo != NULL) {
1531 assert(tzinfoarg != NULL);
1532 if (format_utcoffset(buf,
1533 sizeof(buf),
1534 "",
1535 tzinfo,
1536 tzinfoarg) < 0)
1537 goto Done;
1538 Py_DECREF(zreplacement);
1539 zreplacement =
1540 PyBytes_FromStringAndSize(buf,
1541 strlen(buf));
1542 if (zreplacement == NULL)
1543 goto Done;
1544 }
1545 }
1546 assert(zreplacement != NULL);
1547 ptoappend = PyBytes_AS_STRING(zreplacement);
1548 ntoappend = PyBytes_GET_SIZE(zreplacement);
1549 }
1550 else if (ch == 'Z') {
1551 /* format tzname */
1552 if (Zreplacement == NULL) {
1553 Zreplacement = make_Zreplacement(object,
1554 tzinfoarg);
1555 if (Zreplacement == NULL)
1556 goto Done;
1557 }
1558 assert(Zreplacement != NULL);
1559 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001560 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001562 if (ptoappend == NULL)
1563 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 }
1565 else if (ch == 'f') {
1566 /* format microseconds */
1567 if (freplacement == NULL) {
1568 freplacement = make_freplacement(object);
1569 if (freplacement == NULL)
1570 goto Done;
1571 }
1572 assert(freplacement != NULL);
1573 assert(PyBytes_Check(freplacement));
1574 ptoappend = PyBytes_AS_STRING(freplacement);
1575 ntoappend = PyBytes_GET_SIZE(freplacement);
1576 }
1577 else {
1578 /* percent followed by neither z nor Z */
1579 ptoappend = pin - 2;
1580 ntoappend = 2;
1581 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 /* Append the ntoappend chars starting at ptoappend to
1584 * the new format.
1585 */
1586 if (ntoappend == 0)
1587 continue;
1588 assert(ptoappend != NULL);
1589 assert(ntoappend > 0);
1590 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001591 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 PyErr_NoMemory();
1593 goto Done;
1594 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001595 totalnew <<= 1;
1596 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 pnew = PyBytes_AsString(newfmt) + usednew;
1599 }
1600 memcpy(pnew, ptoappend, ntoappend);
1601 pnew += ntoappend;
1602 usednew += ntoappend;
1603 assert(usednew <= totalnew);
1604 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1607 goto Done;
1608 {
1609 PyObject *format;
1610 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 if (time == NULL)
1613 goto Done;
1614 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1615 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001616 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1617 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 Py_DECREF(format);
1619 }
1620 Py_DECREF(time);
1621 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001622 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 Py_XDECREF(freplacement);
1624 Py_XDECREF(zreplacement);
1625 Py_XDECREF(Zreplacement);
1626 Py_XDECREF(newfmt);
1627 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001628}
1629
Tim Peters2a799bf2002-12-16 20:18:38 +00001630/* ---------------------------------------------------------------------------
1631 * Wrap functions from the time module. These aren't directly available
1632 * from C. Perhaps they should be.
1633 */
1634
1635/* Call time.time() and return its result (a Python float). */
1636static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001637time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 PyObject *result = NULL;
1640 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001643 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001644
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001645 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 Py_DECREF(time);
1647 }
1648 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001649}
1650
1651/* Build a time.struct_time. The weekday and day number are automatically
1652 * computed from the y,m,d args.
1653 */
1654static PyObject *
1655build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1656{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001658 PyObject *result;
1659 _Py_IDENTIFIER(struct_time);
1660 PyObject *args;
1661
Tim Peters2a799bf2002-12-16 20:18:38 +00001662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001664 if (time == NULL) {
1665 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 }
Victor Stinner2b635972016-12-09 00:38:16 +01001667
1668 args = Py_BuildValue("iiiiiiiii",
1669 y, m, d,
1670 hh, mm, ss,
1671 weekday(y, m, d),
1672 days_before_month(y, m) + d,
1673 dstflag);
1674 if (args == NULL) {
1675 Py_DECREF(time);
1676 return NULL;
1677 }
1678
1679 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1680 args, NULL);
1681 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001682 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001684}
1685
1686/* ---------------------------------------------------------------------------
1687 * Miscellaneous helpers.
1688 */
1689
Mark Dickinsone94c6792009-02-02 20:36:42 +00001690/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001691 * The comparisons here all most naturally compute a cmp()-like result.
1692 * This little helper turns that into a bool result for rich comparisons.
1693 */
1694static PyObject *
1695diff_to_bool(int diff, int op)
1696{
stratakise8b19652017-11-02 11:32:54 +01001697 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001698}
1699
Tim Peters07534a62003-02-07 22:50:28 +00001700/* Raises a "can't compare" TypeError and returns NULL. */
1701static PyObject *
1702cmperror(PyObject *a, PyObject *b)
1703{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001704 PyErr_Format(PyExc_TypeError,
1705 "can't compare %s to %s",
1706 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1707 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001708}
1709
Tim Peters2a799bf2002-12-16 20:18:38 +00001710/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001711 * Cached Python objects; these are set by the module init function.
1712 */
1713
1714/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715static PyObject *us_per_ms = NULL; /* 1000 */
1716static PyObject *us_per_second = NULL; /* 1000000 */
1717static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001718static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1719static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1720static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001721static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1722
Tim Peters2a799bf2002-12-16 20:18:38 +00001723/* ---------------------------------------------------------------------------
1724 * Class implementations.
1725 */
1726
1727/*
1728 * PyDateTime_Delta implementation.
1729 */
1730
1731/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001733 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001734 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1735 * due to ubiquitous overflow possibilities.
1736 */
1737static PyObject *
1738delta_to_microseconds(PyDateTime_Delta *self)
1739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 PyObject *x1 = NULL;
1741 PyObject *x2 = NULL;
1742 PyObject *x3 = NULL;
1743 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1746 if (x1 == NULL)
1747 goto Done;
1748 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1749 if (x2 == NULL)
1750 goto Done;
1751 Py_DECREF(x1);
1752 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 /* x2 has days in seconds */
1755 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1756 if (x1 == NULL)
1757 goto Done;
1758 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1759 if (x3 == NULL)
1760 goto Done;
1761 Py_DECREF(x1);
1762 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001763 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 /* x3 has days+seconds in seconds */
1766 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1767 if (x1 == NULL)
1768 goto Done;
1769 Py_DECREF(x3);
1770 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 /* x1 has days+seconds in us */
1773 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1774 if (x2 == NULL)
1775 goto Done;
1776 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001777 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001778
1779Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 Py_XDECREF(x1);
1781 Py_XDECREF(x2);
1782 Py_XDECREF(x3);
1783 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001784}
1785
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001786static PyObject *
1787checked_divmod(PyObject *a, PyObject *b)
1788{
1789 PyObject *result = PyNumber_Divmod(a, b);
1790 if (result != NULL) {
1791 if (!PyTuple_Check(result)) {
1792 PyErr_Format(PyExc_TypeError,
1793 "divmod() returned non-tuple (type %.200s)",
1794 result->ob_type->tp_name);
1795 Py_DECREF(result);
1796 return NULL;
1797 }
1798 if (PyTuple_GET_SIZE(result) != 2) {
1799 PyErr_Format(PyExc_TypeError,
1800 "divmod() returned a tuple of size %zd",
1801 PyTuple_GET_SIZE(result));
1802 Py_DECREF(result);
1803 return NULL;
1804 }
1805 }
1806 return result;
1807}
1808
Serhiy Storchaka95949422013-08-27 19:40:23 +03001809/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001810 */
1811static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001812microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 int us;
1815 int s;
1816 int d;
Tim Peters2a799bf2002-12-16 20:18:38 +00001817
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 PyObject *tuple = NULL;
1819 PyObject *num = NULL;
1820 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001821
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001822 tuple = checked_divmod(pyus, us_per_second);
1823 if (tuple == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 goto Done;
1825 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001826
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001827 num = PyTuple_GET_ITEM(tuple, 1); /* us */
1828 us = _PyLong_AsInt(num);
1829 num = NULL;
1830 if (us == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 goto Done;
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001832 }
1833 if (!(0 <= us && us < 1000000)) {
1834 goto BadDivmod;
1835 }
1836
1837 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 Py_INCREF(num);
1839 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001840
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001841 tuple = checked_divmod(num, seconds_per_day);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 if (tuple == NULL)
1843 goto Done;
1844 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001845
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001846 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */
1847 s = _PyLong_AsInt(num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 num = NULL;
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001849 if (s == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 goto Done;
1851 }
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001852 if (!(0 <= s && s < 24*3600)) {
1853 goto BadDivmod;
1854 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001855
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001856 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 Py_INCREF(num);
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001858 d = _PyLong_AsInt(num);
1859 if (d == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 goto Done;
1861 }
1862 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001863
1864Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 Py_XDECREF(tuple);
1866 Py_XDECREF(num);
1867 return result;
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001868
1869BadDivmod:
1870 PyErr_SetString(PyExc_TypeError,
1871 "divmod() returned a value out of range");
1872 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001873}
1874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875#define microseconds_to_delta(pymicros) \
1876 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001877
Tim Peters2a799bf2002-12-16 20:18:38 +00001878static PyObject *
1879multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 PyObject *pyus_in;
1882 PyObject *pyus_out;
1883 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 pyus_in = delta_to_microseconds(delta);
1886 if (pyus_in == NULL)
1887 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001888
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001889 pyus_out = PyNumber_Multiply(intobj, pyus_in);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 Py_DECREF(pyus_in);
1891 if (pyus_out == NULL)
1892 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 result = microseconds_to_delta(pyus_out);
1895 Py_DECREF(pyus_out);
1896 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001897}
1898
1899static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001900get_float_as_integer_ratio(PyObject *floatobj)
1901{
1902 PyObject *ratio;
1903
1904 assert(floatobj && PyFloat_Check(floatobj));
1905 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1906 if (ratio == NULL) {
1907 return NULL;
1908 }
1909 if (!PyTuple_Check(ratio)) {
1910 PyErr_Format(PyExc_TypeError,
1911 "unexpected return type from as_integer_ratio(): "
1912 "expected tuple, got '%.200s'",
1913 Py_TYPE(ratio)->tp_name);
1914 Py_DECREF(ratio);
1915 return NULL;
1916 }
1917 if (PyTuple_Size(ratio) != 2) {
1918 PyErr_SetString(PyExc_ValueError,
1919 "as_integer_ratio() must return a 2-tuple");
1920 Py_DECREF(ratio);
1921 return NULL;
1922 }
1923 return ratio;
1924}
1925
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001926/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001927static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001928multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001929{
1930 PyObject *result = NULL;
1931 PyObject *pyus_in = NULL, *temp, *pyus_out;
1932 PyObject *ratio = NULL;
1933
1934 pyus_in = delta_to_microseconds(delta);
1935 if (pyus_in == NULL)
1936 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001937 ratio = get_float_as_integer_ratio(floatobj);
1938 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001939 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001940 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001941 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001942 Py_DECREF(pyus_in);
1943 pyus_in = NULL;
1944 if (temp == NULL)
1945 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001946 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001947 Py_DECREF(temp);
1948 if (pyus_out == NULL)
1949 goto error;
1950 result = microseconds_to_delta(pyus_out);
1951 Py_DECREF(pyus_out);
1952 error:
1953 Py_XDECREF(pyus_in);
1954 Py_XDECREF(ratio);
1955
1956 return result;
1957}
1958
1959static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001960divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 PyObject *pyus_in;
1963 PyObject *pyus_out;
1964 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 pyus_in = delta_to_microseconds(delta);
1967 if (pyus_in == NULL)
1968 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1971 Py_DECREF(pyus_in);
1972 if (pyus_out == NULL)
1973 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 result = microseconds_to_delta(pyus_out);
1976 Py_DECREF(pyus_out);
1977 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001978}
1979
1980static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001981divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 PyObject *pyus_left;
1984 PyObject *pyus_right;
1985 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 pyus_left = delta_to_microseconds(left);
1988 if (pyus_left == NULL)
1989 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 pyus_right = delta_to_microseconds(right);
1992 if (pyus_right == NULL) {
1993 Py_DECREF(pyus_left);
1994 return NULL;
1995 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1998 Py_DECREF(pyus_left);
1999 Py_DECREF(pyus_right);
2000 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002001}
2002
2003static PyObject *
2004truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 PyObject *pyus_left;
2007 PyObject *pyus_right;
2008 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 pyus_left = delta_to_microseconds(left);
2011 if (pyus_left == NULL)
2012 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 pyus_right = delta_to_microseconds(right);
2015 if (pyus_right == NULL) {
2016 Py_DECREF(pyus_left);
2017 return NULL;
2018 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2021 Py_DECREF(pyus_left);
2022 Py_DECREF(pyus_right);
2023 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002024}
2025
2026static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002027truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2028{
2029 PyObject *result;
2030 PyObject *pyus_in, *pyus_out;
2031 pyus_in = delta_to_microseconds(delta);
2032 if (pyus_in == NULL)
2033 return NULL;
2034 pyus_out = divide_nearest(pyus_in, i);
2035 Py_DECREF(pyus_in);
2036 if (pyus_out == NULL)
2037 return NULL;
2038 result = microseconds_to_delta(pyus_out);
2039 Py_DECREF(pyus_out);
2040
2041 return result;
2042}
2043
2044static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002045delta_add(PyObject *left, PyObject *right)
2046{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2050 /* delta + delta */
2051 /* The C-level additions can't overflow because of the
2052 * invariant bounds.
2053 */
2054 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2055 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2056 int microseconds = GET_TD_MICROSECONDS(left) +
2057 GET_TD_MICROSECONDS(right);
2058 result = new_delta(days, seconds, microseconds, 1);
2059 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 if (result == Py_NotImplemented)
2062 Py_INCREF(result);
2063 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002064}
2065
2066static PyObject *
2067delta_negative(PyDateTime_Delta *self)
2068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 return new_delta(-GET_TD_DAYS(self),
2070 -GET_TD_SECONDS(self),
2071 -GET_TD_MICROSECONDS(self),
2072 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002073}
2074
2075static PyObject *
2076delta_positive(PyDateTime_Delta *self)
2077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 /* Could optimize this (by returning self) if this isn't a
2079 * subclass -- but who uses unary + ? Approximately nobody.
2080 */
2081 return new_delta(GET_TD_DAYS(self),
2082 GET_TD_SECONDS(self),
2083 GET_TD_MICROSECONDS(self),
2084 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002085}
2086
2087static PyObject *
2088delta_abs(PyDateTime_Delta *self)
2089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002092 assert(GET_TD_MICROSECONDS(self) >= 0);
2093 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 if (GET_TD_DAYS(self) < 0)
2096 result = delta_negative(self);
2097 else
2098 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002101}
2102
2103static PyObject *
2104delta_subtract(PyObject *left, PyObject *right)
2105{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2109 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002110 /* The C-level additions can't overflow because of the
2111 * invariant bounds.
2112 */
2113 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2114 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2115 int microseconds = GET_TD_MICROSECONDS(left) -
2116 GET_TD_MICROSECONDS(right);
2117 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 if (result == Py_NotImplemented)
2121 Py_INCREF(result);
2122 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002123}
2124
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002125static int
2126delta_cmp(PyObject *self, PyObject *other)
2127{
2128 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2129 if (diff == 0) {
2130 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2131 if (diff == 0)
2132 diff = GET_TD_MICROSECONDS(self) -
2133 GET_TD_MICROSECONDS(other);
2134 }
2135 return diff;
2136}
2137
Tim Peters2a799bf2002-12-16 20:18:38 +00002138static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002139delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002140{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002142 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 return diff_to_bool(diff, op);
2144 }
2145 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002146 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002148}
2149
2150static PyObject *delta_getstate(PyDateTime_Delta *self);
2151
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002152static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002153delta_hash(PyDateTime_Delta *self)
2154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 if (self->hashcode == -1) {
2156 PyObject *temp = delta_getstate(self);
2157 if (temp != NULL) {
2158 self->hashcode = PyObject_Hash(temp);
2159 Py_DECREF(temp);
2160 }
2161 }
2162 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002163}
2164
2165static PyObject *
2166delta_multiply(PyObject *left, PyObject *right)
2167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 if (PyDelta_Check(left)) {
2171 /* delta * ??? */
2172 if (PyLong_Check(right))
2173 result = multiply_int_timedelta(right,
2174 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002175 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002176 result = multiply_truedivide_timedelta_float(
2177 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 }
2179 else if (PyLong_Check(left))
2180 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002181 (PyDateTime_Delta *) right);
2182 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002183 result = multiply_truedivide_timedelta_float(
2184 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 if (result == Py_NotImplemented)
2187 Py_INCREF(result);
2188 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002189}
2190
2191static PyObject *
2192delta_divide(PyObject *left, PyObject *right)
2193{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 if (PyDelta_Check(left)) {
2197 /* delta * ??? */
2198 if (PyLong_Check(right))
2199 result = divide_timedelta_int(
2200 (PyDateTime_Delta *)left,
2201 right);
2202 else if (PyDelta_Check(right))
2203 result = divide_timedelta_timedelta(
2204 (PyDateTime_Delta *)left,
2205 (PyDateTime_Delta *)right);
2206 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002208 if (result == Py_NotImplemented)
2209 Py_INCREF(result);
2210 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002211}
2212
Mark Dickinson7c186e22010-04-20 22:32:49 +00002213static PyObject *
2214delta_truedivide(PyObject *left, PyObject *right)
2215{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002216 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002218 if (PyDelta_Check(left)) {
2219 if (PyDelta_Check(right))
2220 result = truedivide_timedelta_timedelta(
2221 (PyDateTime_Delta *)left,
2222 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002223 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002224 result = multiply_truedivide_timedelta_float(
2225 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002226 else if (PyLong_Check(right))
2227 result = truedivide_timedelta_int(
2228 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 if (result == Py_NotImplemented)
2232 Py_INCREF(result);
2233 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002234}
2235
2236static PyObject *
2237delta_remainder(PyObject *left, PyObject *right)
2238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 PyObject *pyus_left;
2240 PyObject *pyus_right;
2241 PyObject *pyus_remainder;
2242 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002243
Brian Curtindfc80e32011-08-10 20:28:54 -05002244 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2245 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2248 if (pyus_left == NULL)
2249 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2252 if (pyus_right == NULL) {
2253 Py_DECREF(pyus_left);
2254 return NULL;
2255 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2258 Py_DECREF(pyus_left);
2259 Py_DECREF(pyus_right);
2260 if (pyus_remainder == NULL)
2261 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 remainder = microseconds_to_delta(pyus_remainder);
2264 Py_DECREF(pyus_remainder);
2265 if (remainder == NULL)
2266 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002269}
2270
2271static PyObject *
2272delta_divmod(PyObject *left, PyObject *right)
2273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 PyObject *pyus_left;
2275 PyObject *pyus_right;
2276 PyObject *divmod;
2277 PyObject *delta;
2278 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002279
Brian Curtindfc80e32011-08-10 20:28:54 -05002280 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2281 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2284 if (pyus_left == NULL)
2285 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2288 if (pyus_right == NULL) {
2289 Py_DECREF(pyus_left);
2290 return NULL;
2291 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002292
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08002293 divmod = checked_divmod(pyus_left, pyus_right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 Py_DECREF(pyus_left);
2295 Py_DECREF(pyus_right);
2296 if (divmod == NULL)
2297 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2300 if (delta == NULL) {
2301 Py_DECREF(divmod);
2302 return NULL;
2303 }
2304 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2305 Py_DECREF(delta);
2306 Py_DECREF(divmod);
2307 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002308}
2309
Tim Peters2a799bf2002-12-16 20:18:38 +00002310/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2311 * timedelta constructor. sofar is the # of microseconds accounted for
2312 * so far, and there are factor microseconds per current unit, the number
2313 * of which is given by num. num * factor is added to sofar in a
2314 * numerically careful way, and that's the result. Any fractional
2315 * microseconds left over (this can happen if num is a float type) are
2316 * added into *leftover.
2317 * Note that there are many ways this can give an error (NULL) return.
2318 */
2319static PyObject *
2320accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2321 double *leftover)
2322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002323 PyObject *prod;
2324 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002326 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002328 if (PyLong_Check(num)) {
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08002329 prod = PyNumber_Multiply(num, factor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002330 if (prod == NULL)
2331 return NULL;
2332 sum = PyNumber_Add(sofar, prod);
2333 Py_DECREF(prod);
2334 return sum;
2335 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 if (PyFloat_Check(num)) {
2338 double dnum;
2339 double fracpart;
2340 double intpart;
2341 PyObject *x;
2342 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 /* The Plan: decompose num into an integer part and a
2345 * fractional part, num = intpart + fracpart.
2346 * Then num * factor ==
2347 * intpart * factor + fracpart * factor
2348 * and the LHS can be computed exactly in long arithmetic.
2349 * The RHS is again broken into an int part and frac part.
2350 * and the frac part is added into *leftover.
2351 */
2352 dnum = PyFloat_AsDouble(num);
2353 if (dnum == -1.0 && PyErr_Occurred())
2354 return NULL;
2355 fracpart = modf(dnum, &intpart);
2356 x = PyLong_FromDouble(intpart);
2357 if (x == NULL)
2358 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 prod = PyNumber_Multiply(x, factor);
2361 Py_DECREF(x);
2362 if (prod == NULL)
2363 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002365 sum = PyNumber_Add(sofar, prod);
2366 Py_DECREF(prod);
2367 if (sum == NULL)
2368 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370 if (fracpart == 0.0)
2371 return sum;
2372 /* So far we've lost no information. Dealing with the
2373 * fractional part requires float arithmetic, and may
2374 * lose a little info.
2375 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002376 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 dnum *= fracpart;
2380 fracpart = modf(dnum, &intpart);
2381 x = PyLong_FromDouble(intpart);
2382 if (x == NULL) {
2383 Py_DECREF(sum);
2384 return NULL;
2385 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 y = PyNumber_Add(sum, x);
2388 Py_DECREF(sum);
2389 Py_DECREF(x);
2390 *leftover += fracpart;
2391 return y;
2392 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 PyErr_Format(PyExc_TypeError,
2395 "unsupported type for timedelta %s component: %s",
2396 tag, Py_TYPE(num)->tp_name);
2397 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002398}
2399
2400static PyObject *
2401delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 /* Argument objects. */
2406 PyObject *day = NULL;
2407 PyObject *second = NULL;
2408 PyObject *us = NULL;
2409 PyObject *ms = NULL;
2410 PyObject *minute = NULL;
2411 PyObject *hour = NULL;
2412 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 PyObject *x = NULL; /* running sum of microseconds */
2415 PyObject *y = NULL; /* temp sum of microseconds */
2416 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 static char *keywords[] = {
2419 "days", "seconds", "microseconds", "milliseconds",
2420 "minutes", "hours", "weeks", NULL
2421 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2424 keywords,
2425 &day, &second, &us,
2426 &ms, &minute, &hour, &week) == 0)
2427 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 x = PyLong_FromLong(0);
2430 if (x == NULL)
2431 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433#define CLEANUP \
2434 Py_DECREF(x); \
2435 x = y; \
2436 if (x == NULL) \
2437 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002440 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002441 CLEANUP;
2442 }
2443 if (ms) {
2444 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2445 CLEANUP;
2446 }
2447 if (second) {
2448 y = accum("seconds", x, second, us_per_second, &leftover_us);
2449 CLEANUP;
2450 }
2451 if (minute) {
2452 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2453 CLEANUP;
2454 }
2455 if (hour) {
2456 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2457 CLEANUP;
2458 }
2459 if (day) {
2460 y = accum("days", x, day, us_per_day, &leftover_us);
2461 CLEANUP;
2462 }
2463 if (week) {
2464 y = accum("weeks", x, week, us_per_week, &leftover_us);
2465 CLEANUP;
2466 }
2467 if (leftover_us) {
2468 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002469 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002470 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002471 PyObject *temp;
2472
Victor Stinner69cc4872015-09-08 23:58:54 +02002473 whole_us = round(leftover_us);
2474 if (fabs(whole_us - leftover_us) == 0.5) {
2475 /* We're exactly halfway between two integers. In order
2476 * to do round-half-to-even, we must determine whether x
2477 * is odd. Note that x is odd when it's last bit is 1. The
2478 * code below uses bitwise and operation to check the last
2479 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002480 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002481 if (temp == NULL) {
2482 Py_DECREF(x);
2483 goto Done;
2484 }
2485 x_is_odd = PyObject_IsTrue(temp);
2486 Py_DECREF(temp);
2487 if (x_is_odd == -1) {
2488 Py_DECREF(x);
2489 goto Done;
2490 }
2491 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2492 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002493
Victor Stinner36a5a062013-08-28 01:53:39 +02002494 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 if (temp == NULL) {
2497 Py_DECREF(x);
2498 goto Done;
2499 }
2500 y = PyNumber_Add(x, temp);
2501 Py_DECREF(temp);
2502 CLEANUP;
2503 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002505 self = microseconds_to_delta_ex(x, type);
2506 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002507Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002508 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002509
2510#undef CLEANUP
2511}
2512
2513static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002514delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002515{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 return (GET_TD_DAYS(self) != 0
2517 || GET_TD_SECONDS(self) != 0
2518 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002519}
2520
2521static PyObject *
2522delta_repr(PyDateTime_Delta *self)
2523{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002524 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002525
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002526 if (args == NULL) {
2527 return NULL;
2528 }
2529
2530 const char *sep = "";
2531
2532 if (GET_TD_DAYS(self) != 0) {
2533 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2534 if (args == NULL) {
2535 return NULL;
2536 }
2537 sep = ", ";
2538 }
2539
2540 if (GET_TD_SECONDS(self) != 0) {
2541 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2542 GET_TD_SECONDS(self)));
2543 if (args == NULL) {
2544 return NULL;
2545 }
2546 sep = ", ";
2547 }
2548
2549 if (GET_TD_MICROSECONDS(self) != 0) {
2550 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2551 GET_TD_MICROSECONDS(self)));
2552 if (args == NULL) {
2553 return NULL;
2554 }
2555 }
2556
2557 if (PyUnicode_GET_LENGTH(args) == 0) {
2558 Py_SETREF(args, PyUnicode_FromString("0"));
2559 if (args == NULL) {
2560 return NULL;
2561 }
2562 }
2563
2564 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2565 args);
2566 Py_DECREF(args);
2567 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002568}
2569
2570static PyObject *
2571delta_str(PyDateTime_Delta *self)
2572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002573 int us = GET_TD_MICROSECONDS(self);
2574 int seconds = GET_TD_SECONDS(self);
2575 int minutes = divmod(seconds, 60, &seconds);
2576 int hours = divmod(minutes, 60, &minutes);
2577 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002579 if (days) {
2580 if (us)
2581 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2582 days, (days == 1 || days == -1) ? "" : "s",
2583 hours, minutes, seconds, us);
2584 else
2585 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2586 days, (days == 1 || days == -1) ? "" : "s",
2587 hours, minutes, seconds);
2588 } else {
2589 if (us)
2590 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2591 hours, minutes, seconds, us);
2592 else
2593 return PyUnicode_FromFormat("%d:%02d:%02d",
2594 hours, minutes, seconds);
2595 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002596
Tim Peters2a799bf2002-12-16 20:18:38 +00002597}
2598
Tim Peters371935f2003-02-01 01:52:50 +00002599/* Pickle support, a simple use of __reduce__. */
2600
Tim Petersb57f8f02003-02-01 02:54:15 +00002601/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002602static PyObject *
2603delta_getstate(PyDateTime_Delta *self)
2604{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002605 return Py_BuildValue("iii", GET_TD_DAYS(self),
2606 GET_TD_SECONDS(self),
2607 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002608}
2609
Tim Peters2a799bf2002-12-16 20:18:38 +00002610static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002611delta_total_seconds(PyObject *self)
2612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 PyObject *total_seconds;
2614 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2617 if (total_microseconds == NULL)
2618 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002619
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002620 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002623 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002624}
2625
2626static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002627delta_reduce(PyDateTime_Delta* self)
2628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002629 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002630}
2631
2632#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2633
2634static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 {"days", T_INT, OFFSET(days), READONLY,
2637 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 {"seconds", T_INT, OFFSET(seconds), READONLY,
2640 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2643 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2644 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002645};
2646
2647static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002648 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2649 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002651 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2652 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002655};
2656
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002657static const char delta_doc[] =
Miss Islington (bot)ef7f29f2018-10-19 16:02:13 -07002658PyDoc_STR("Difference between two datetime values.\n\n"
2659 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2660 "minutes=0, hours=0, weeks=0)\n\n"
2661 "All arguments are optional and default to 0.\n"
2662 "Arguments may be integers or floats, and may be positive or negative.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002663
2664static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002665 delta_add, /* nb_add */
2666 delta_subtract, /* nb_subtract */
2667 delta_multiply, /* nb_multiply */
2668 delta_remainder, /* nb_remainder */
2669 delta_divmod, /* nb_divmod */
2670 0, /* nb_power */
2671 (unaryfunc)delta_negative, /* nb_negative */
2672 (unaryfunc)delta_positive, /* nb_positive */
2673 (unaryfunc)delta_abs, /* nb_absolute */
2674 (inquiry)delta_bool, /* nb_bool */
2675 0, /*nb_invert*/
2676 0, /*nb_lshift*/
2677 0, /*nb_rshift*/
2678 0, /*nb_and*/
2679 0, /*nb_xor*/
2680 0, /*nb_or*/
2681 0, /*nb_int*/
2682 0, /*nb_reserved*/
2683 0, /*nb_float*/
2684 0, /*nb_inplace_add*/
2685 0, /*nb_inplace_subtract*/
2686 0, /*nb_inplace_multiply*/
2687 0, /*nb_inplace_remainder*/
2688 0, /*nb_inplace_power*/
2689 0, /*nb_inplace_lshift*/
2690 0, /*nb_inplace_rshift*/
2691 0, /*nb_inplace_and*/
2692 0, /*nb_inplace_xor*/
2693 0, /*nb_inplace_or*/
2694 delta_divide, /* nb_floor_divide */
2695 delta_truedivide, /* nb_true_divide */
2696 0, /* nb_inplace_floor_divide */
2697 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002698};
2699
2700static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002701 PyVarObject_HEAD_INIT(NULL, 0)
2702 "datetime.timedelta", /* tp_name */
2703 sizeof(PyDateTime_Delta), /* tp_basicsize */
2704 0, /* tp_itemsize */
2705 0, /* tp_dealloc */
2706 0, /* tp_print */
2707 0, /* tp_getattr */
2708 0, /* tp_setattr */
2709 0, /* tp_reserved */
2710 (reprfunc)delta_repr, /* tp_repr */
2711 &delta_as_number, /* tp_as_number */
2712 0, /* tp_as_sequence */
2713 0, /* tp_as_mapping */
2714 (hashfunc)delta_hash, /* tp_hash */
2715 0, /* tp_call */
2716 (reprfunc)delta_str, /* tp_str */
2717 PyObject_GenericGetAttr, /* tp_getattro */
2718 0, /* tp_setattro */
2719 0, /* tp_as_buffer */
2720 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2721 delta_doc, /* tp_doc */
2722 0, /* tp_traverse */
2723 0, /* tp_clear */
2724 delta_richcompare, /* tp_richcompare */
2725 0, /* tp_weaklistoffset */
2726 0, /* tp_iter */
2727 0, /* tp_iternext */
2728 delta_methods, /* tp_methods */
2729 delta_members, /* tp_members */
2730 0, /* tp_getset */
2731 0, /* tp_base */
2732 0, /* tp_dict */
2733 0, /* tp_descr_get */
2734 0, /* tp_descr_set */
2735 0, /* tp_dictoffset */
2736 0, /* tp_init */
2737 0, /* tp_alloc */
2738 delta_new, /* tp_new */
2739 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002740};
2741
2742/*
2743 * PyDateTime_Date implementation.
2744 */
2745
2746/* Accessor properties. */
2747
2748static PyObject *
2749date_year(PyDateTime_Date *self, void *unused)
2750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002751 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002752}
2753
2754static PyObject *
2755date_month(PyDateTime_Date *self, void *unused)
2756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002757 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002758}
2759
2760static PyObject *
2761date_day(PyDateTime_Date *self, void *unused)
2762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002763 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002764}
2765
2766static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002767 {"year", (getter)date_year},
2768 {"month", (getter)date_month},
2769 {"day", (getter)date_day},
2770 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002771};
2772
2773/* Constructors. */
2774
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002775static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002776
Tim Peters2a799bf2002-12-16 20:18:38 +00002777static PyObject *
2778date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2779{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002780 PyObject *self = NULL;
2781 PyObject *state;
2782 int year;
2783 int month;
2784 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002786 /* Check for invocation from pickle with __getstate__ state */
2787 if (PyTuple_GET_SIZE(args) == 1 &&
2788 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2789 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2790 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2791 {
2792 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002794 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2795 if (me != NULL) {
2796 char *pdata = PyBytes_AS_STRING(state);
2797 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2798 me->hashcode = -1;
2799 }
2800 return (PyObject *)me;
2801 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002803 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2804 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 self = new_date_ex(year, month, day, type);
2806 }
2807 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002808}
2809
2810/* Return new date from localtime(t). */
2811static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002812date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002813{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002814 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002816
Victor Stinnere4a994d2015-03-30 01:10:14 +02002817 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002818 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002819
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002820 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002821 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002822
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002823 return new_date_subclass_ex(tm.tm_year + 1900,
2824 tm.tm_mon + 1,
2825 tm.tm_mday,
2826 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002827}
2828
2829/* Return new date from current time.
2830 * We say this is equivalent to fromtimestamp(time.time()), and the
2831 * only way to be sure of that is to *call* time.time(). That's not
2832 * generally the same as calling C's time.
2833 */
2834static PyObject *
2835date_today(PyObject *cls, PyObject *dummy)
2836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 PyObject *time;
2838 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002839 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002841 time = time_time();
2842 if (time == NULL)
2843 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 /* Note well: today() is a class method, so this may not call
2846 * date.fromtimestamp. For example, it may call
2847 * datetime.fromtimestamp. That's why we need all the accuracy
2848 * time.time() delivers; if someone were gonzo about optimization,
2849 * date.today() could get away with plain C time().
2850 */
Victor Stinner20401de2016-12-09 15:24:31 +01002851 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2852 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 Py_DECREF(time);
2854 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002855}
2856
2857/* Return new date from given timestamp (Python timestamp -- a double). */
2858static PyObject *
2859date_fromtimestamp(PyObject *cls, PyObject *args)
2860{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002861 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002863
Victor Stinner5d272cc2012-03-13 13:35:55 +01002864 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2865 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002866 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002867}
2868
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002869
Tim Peters2a799bf2002-12-16 20:18:38 +00002870/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2871 * the ordinal is out of range.
2872 */
2873static PyObject *
2874date_fromordinal(PyObject *cls, PyObject *args)
2875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002876 PyObject *result = NULL;
2877 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002879 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2880 int year;
2881 int month;
2882 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 if (ordinal < 1)
2885 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2886 ">= 1");
2887 else {
2888 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002889 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 }
2891 }
2892 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002893}
2894
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002895/* Return the new date from a string as generated by date.isoformat() */
2896static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002897date_fromisoformat(PyObject *cls, PyObject *dtstr)
2898{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002899 assert(dtstr != NULL);
2900
2901 if (!PyUnicode_Check(dtstr)) {
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002902 PyErr_SetString(PyExc_TypeError,
2903 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002904 return NULL;
2905 }
2906
2907 Py_ssize_t len;
2908
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002909 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002910 if (dt_ptr == NULL) {
2911 goto invalid_string_error;
2912 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002913
2914 int year = 0, month = 0, day = 0;
2915
2916 int rv;
2917 if (len == 10) {
2918 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002919 }
2920 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002921 rv = -1;
2922 }
2923
2924 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002925 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002926 }
2927
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002928 return new_date_subclass_ex(year, month, day, cls);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002929
2930invalid_string_error:
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002931 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002932 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002933}
2934
Tim Peters2a799bf2002-12-16 20:18:38 +00002935/*
2936 * Date arithmetic.
2937 */
2938
2939/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2940 * instead.
2941 */
2942static PyObject *
2943add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2944{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002945 PyObject *result = NULL;
2946 int year = GET_YEAR(date);
2947 int month = GET_MONTH(date);
2948 int deltadays = GET_TD_DAYS(delta);
2949 /* C-level overflow is impossible because |deltadays| < 1e9. */
2950 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002952 if (normalize_date(&year, &month, &day) >= 0)
2953 result = new_date(year, month, day);
2954 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002955}
2956
2957static PyObject *
2958date_add(PyObject *left, PyObject *right)
2959{
Brian Curtindfc80e32011-08-10 20:28:54 -05002960 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2961 Py_RETURN_NOTIMPLEMENTED;
2962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002963 if (PyDate_Check(left)) {
2964 /* date + ??? */
2965 if (PyDelta_Check(right))
2966 /* date + delta */
2967 return add_date_timedelta((PyDateTime_Date *) left,
2968 (PyDateTime_Delta *) right,
2969 0);
2970 }
2971 else {
2972 /* ??? + date
2973 * 'right' must be one of us, or we wouldn't have been called
2974 */
2975 if (PyDelta_Check(left))
2976 /* delta + date */
2977 return add_date_timedelta((PyDateTime_Date *) right,
2978 (PyDateTime_Delta *) left,
2979 0);
2980 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002981 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002982}
2983
2984static PyObject *
2985date_subtract(PyObject *left, PyObject *right)
2986{
Brian Curtindfc80e32011-08-10 20:28:54 -05002987 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2988 Py_RETURN_NOTIMPLEMENTED;
2989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002990 if (PyDate_Check(left)) {
2991 if (PyDate_Check(right)) {
2992 /* date - date */
2993 int left_ord = ymd_to_ord(GET_YEAR(left),
2994 GET_MONTH(left),
2995 GET_DAY(left));
2996 int right_ord = ymd_to_ord(GET_YEAR(right),
2997 GET_MONTH(right),
2998 GET_DAY(right));
2999 return new_delta(left_ord - right_ord, 0, 0, 0);
3000 }
3001 if (PyDelta_Check(right)) {
3002 /* date - delta */
3003 return add_date_timedelta((PyDateTime_Date *) left,
3004 (PyDateTime_Delta *) right,
3005 1);
3006 }
3007 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003008 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003009}
3010
3011
3012/* Various ways to turn a date into a string. */
3013
3014static PyObject *
3015date_repr(PyDateTime_Date *self)
3016{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003017 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3018 Py_TYPE(self)->tp_name,
3019 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003020}
3021
3022static PyObject *
3023date_isoformat(PyDateTime_Date *self)
3024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003025 return PyUnicode_FromFormat("%04d-%02d-%02d",
3026 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003027}
3028
Tim Peterse2df5ff2003-05-02 18:39:55 +00003029/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003030static PyObject *
3031date_str(PyDateTime_Date *self)
3032{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003033 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003034}
3035
3036
3037static PyObject *
3038date_ctime(PyDateTime_Date *self)
3039{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003040 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003041}
3042
3043static PyObject *
3044date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3045{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003046 /* This method can be inherited, and needs to call the
3047 * timetuple() method appropriate to self's class.
3048 */
3049 PyObject *result;
3050 PyObject *tuple;
3051 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003052 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003053 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003054
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003055 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3056 &format))
3057 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003058
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003059 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003060 if (tuple == NULL)
3061 return NULL;
3062 result = wrap_strftime((PyObject *)self, format, tuple,
3063 (PyObject *)self);
3064 Py_DECREF(tuple);
3065 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003066}
3067
Eric Smith1ba31142007-09-11 18:06:02 +00003068static PyObject *
3069date_format(PyDateTime_Date *self, PyObject *args)
3070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003071 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003073 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3074 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003076 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003077 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003078 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003079
Victor Stinner20401de2016-12-09 15:24:31 +01003080 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3081 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003082}
3083
Tim Peters2a799bf2002-12-16 20:18:38 +00003084/* ISO methods. */
3085
3086static PyObject *
3087date_isoweekday(PyDateTime_Date *self)
3088{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003089 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003091 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003092}
3093
3094static PyObject *
3095date_isocalendar(PyDateTime_Date *self)
3096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003097 int year = GET_YEAR(self);
3098 int week1_monday = iso_week1_monday(year);
3099 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3100 int week;
3101 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003103 week = divmod(today - week1_monday, 7, &day);
3104 if (week < 0) {
3105 --year;
3106 week1_monday = iso_week1_monday(year);
3107 week = divmod(today - week1_monday, 7, &day);
3108 }
3109 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3110 ++year;
3111 week = 0;
3112 }
3113 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003114}
3115
3116/* Miscellaneous methods. */
3117
Tim Peters2a799bf2002-12-16 20:18:38 +00003118static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003119date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003121 if (PyDate_Check(other)) {
3122 int diff = memcmp(((PyDateTime_Date *)self)->data,
3123 ((PyDateTime_Date *)other)->data,
3124 _PyDateTime_DATE_DATASIZE);
3125 return diff_to_bool(diff, op);
3126 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003127 else
3128 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003129}
3130
3131static PyObject *
3132date_timetuple(PyDateTime_Date *self)
3133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003134 return build_struct_time(GET_YEAR(self),
3135 GET_MONTH(self),
3136 GET_DAY(self),
3137 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003138}
3139
Tim Peters12bf3392002-12-24 05:41:27 +00003140static PyObject *
3141date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 PyObject *clone;
3144 PyObject *tuple;
3145 int year = GET_YEAR(self);
3146 int month = GET_MONTH(self);
3147 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003149 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3150 &year, &month, &day))
3151 return NULL;
3152 tuple = Py_BuildValue("iii", year, month, day);
3153 if (tuple == NULL)
3154 return NULL;
3155 clone = date_new(Py_TYPE(self), tuple, NULL);
3156 Py_DECREF(tuple);
3157 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003158}
3159
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003160static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003161generic_hash(unsigned char *data, int len)
3162{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003163 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003164}
3165
3166
3167static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003168
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003169static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003170date_hash(PyDateTime_Date *self)
3171{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003172 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003173 self->hashcode = generic_hash(
3174 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003175 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003177 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003178}
3179
3180static PyObject *
3181date_toordinal(PyDateTime_Date *self)
3182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003183 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3184 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003185}
3186
3187static PyObject *
3188date_weekday(PyDateTime_Date *self)
3189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003190 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003192 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003193}
3194
Tim Peters371935f2003-02-01 01:52:50 +00003195/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003196
Tim Petersb57f8f02003-02-01 02:54:15 +00003197/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003198static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003199date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003201 PyObject* field;
3202 field = PyBytes_FromStringAndSize((char*)self->data,
3203 _PyDateTime_DATE_DATASIZE);
3204 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003205}
3206
3207static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003208date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003210 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003211}
3212
3213static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00003216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
3218 METH_CLASS,
3219 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
3220 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003222 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3223 METH_CLASS,
3224 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3225 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003226
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003227 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3228 METH_CLASS,
3229 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003231 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3232 PyDoc_STR("Current date or datetime: same as "
3233 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003235 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003237 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3238 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003240 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
3241 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003243 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3244 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003246 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3247 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003249 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3250 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3251 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003253 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3254 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003256 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3257 PyDoc_STR("Return the day of the week represented by the date.\n"
3258 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003260 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3261 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3262 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003264 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3265 PyDoc_STR("Return the day of the week represented by the date.\n"
3266 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003268 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3269 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003271 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3272 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003274 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003275};
3276
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003277static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003278PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003279
3280static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003281 date_add, /* nb_add */
3282 date_subtract, /* nb_subtract */
3283 0, /* nb_multiply */
3284 0, /* nb_remainder */
3285 0, /* nb_divmod */
3286 0, /* nb_power */
3287 0, /* nb_negative */
3288 0, /* nb_positive */
3289 0, /* nb_absolute */
3290 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003291};
3292
3293static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003294 PyVarObject_HEAD_INIT(NULL, 0)
3295 "datetime.date", /* tp_name */
3296 sizeof(PyDateTime_Date), /* tp_basicsize */
3297 0, /* tp_itemsize */
3298 0, /* tp_dealloc */
3299 0, /* tp_print */
3300 0, /* tp_getattr */
3301 0, /* tp_setattr */
3302 0, /* tp_reserved */
3303 (reprfunc)date_repr, /* tp_repr */
3304 &date_as_number, /* tp_as_number */
3305 0, /* tp_as_sequence */
3306 0, /* tp_as_mapping */
3307 (hashfunc)date_hash, /* tp_hash */
3308 0, /* tp_call */
3309 (reprfunc)date_str, /* tp_str */
3310 PyObject_GenericGetAttr, /* tp_getattro */
3311 0, /* tp_setattro */
3312 0, /* tp_as_buffer */
3313 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3314 date_doc, /* tp_doc */
3315 0, /* tp_traverse */
3316 0, /* tp_clear */
3317 date_richcompare, /* tp_richcompare */
3318 0, /* tp_weaklistoffset */
3319 0, /* tp_iter */
3320 0, /* tp_iternext */
3321 date_methods, /* tp_methods */
3322 0, /* tp_members */
3323 date_getset, /* tp_getset */
3324 0, /* tp_base */
3325 0, /* tp_dict */
3326 0, /* tp_descr_get */
3327 0, /* tp_descr_set */
3328 0, /* tp_dictoffset */
3329 0, /* tp_init */
3330 0, /* tp_alloc */
3331 date_new, /* tp_new */
3332 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003333};
3334
3335/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003336 * PyDateTime_TZInfo implementation.
3337 */
3338
3339/* This is a pure abstract base class, so doesn't do anything beyond
3340 * raising NotImplemented exceptions. Real tzinfo classes need
3341 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003342 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003343 * be subclasses of this tzinfo class, which is easy and quick to check).
3344 *
3345 * Note: For reasons having to do with pickling of subclasses, we have
3346 * to allow tzinfo objects to be instantiated. This wasn't an issue
3347 * in the Python implementation (__init__() could raise NotImplementedError
3348 * there without ill effect), but doing so in the C implementation hit a
3349 * brick wall.
3350 */
3351
3352static PyObject *
3353tzinfo_nogo(const char* methodname)
3354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003355 PyErr_Format(PyExc_NotImplementedError,
3356 "a tzinfo subclass must implement %s()",
3357 methodname);
3358 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003359}
3360
3361/* Methods. A subclass must implement these. */
3362
Tim Peters52dcce22003-01-23 16:36:11 +00003363static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003364tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003366 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003367}
3368
Tim Peters52dcce22003-01-23 16:36:11 +00003369static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003370tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003372 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003373}
3374
Tim Peters52dcce22003-01-23 16:36:11 +00003375static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003376tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003378 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003379}
3380
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003381
3382static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3383 PyDateTime_Delta *delta,
3384 int factor);
3385static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3386static PyObject *datetime_dst(PyObject *self, PyObject *);
3387
Tim Peters52dcce22003-01-23 16:36:11 +00003388static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003389tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003390{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003391 PyObject *result = NULL;
3392 PyObject *off = NULL, *dst = NULL;
3393 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003394
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003395 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003396 PyErr_SetString(PyExc_TypeError,
3397 "fromutc: argument must be a datetime");
3398 return NULL;
3399 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003400 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003401 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3402 "is not self");
3403 return NULL;
3404 }
Tim Peters52dcce22003-01-23 16:36:11 +00003405
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003406 off = datetime_utcoffset(dt, NULL);
3407 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003408 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003409 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003410 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3411 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003412 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003413 }
Tim Peters52dcce22003-01-23 16:36:11 +00003414
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003415 dst = datetime_dst(dt, NULL);
3416 if (dst == NULL)
3417 goto Fail;
3418 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003419 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3420 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003421 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003422 }
Tim Peters52dcce22003-01-23 16:36:11 +00003423
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003424 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3425 if (delta == NULL)
3426 goto Fail;
3427 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003428 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003429 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003430
3431 Py_DECREF(dst);
3432 dst = call_dst(GET_DT_TZINFO(dt), result);
3433 if (dst == NULL)
3434 goto Fail;
3435 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003436 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003437 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003438 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003439 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003440 if (result == NULL)
3441 goto Fail;
3442 }
3443 Py_DECREF(delta);
3444 Py_DECREF(dst);
3445 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003446 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003447
3448Inconsistent:
Miss Islington (bot)7beb8c52018-11-05 06:52:58 -08003449 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003450 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003451
Miss Islington (bot)e86db342018-02-03 17:41:43 -08003452 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003453Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003454 Py_XDECREF(off);
3455 Py_XDECREF(dst);
3456 Py_XDECREF(delta);
3457 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003458 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003459}
3460
Tim Peters2a799bf2002-12-16 20:18:38 +00003461/*
3462 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003463 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003464 */
3465
Guido van Rossum177e41a2003-01-30 22:06:23 +00003466static PyObject *
3467tzinfo_reduce(PyObject *self)
3468{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003469 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003470 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003471 _Py_IDENTIFIER(__getinitargs__);
3472 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003473
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003474 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003475 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003476 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003477 Py_DECREF(getinitargs);
3478 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003479 return NULL;
3480 }
3481 }
3482 else {
3483 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003484
3485 args = PyTuple_New(0);
3486 if (args == NULL) {
3487 return NULL;
3488 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003490
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003491 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003492 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003493 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003494 Py_DECREF(getstate);
3495 if (state == NULL) {
3496 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003497 return NULL;
3498 }
3499 }
3500 else {
3501 PyObject **dictptr;
3502 PyErr_Clear();
3503 state = Py_None;
3504 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003505 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003506 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003507 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 Py_INCREF(state);
3509 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003511 if (state == Py_None) {
3512 Py_DECREF(state);
3513 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3514 }
3515 else
3516 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003517}
Tim Peters2a799bf2002-12-16 20:18:38 +00003518
3519static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003521 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3522 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003524 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003525 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3526 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003528 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003529 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003531 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003532 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003534 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3535 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003537 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003538};
3539
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003540static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003541PyDoc_STR("Abstract base class for time zone info objects.");
3542
Neal Norwitz227b5332006-03-22 09:28:35 +00003543static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003544 PyVarObject_HEAD_INIT(NULL, 0)
3545 "datetime.tzinfo", /* tp_name */
3546 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3547 0, /* tp_itemsize */
3548 0, /* tp_dealloc */
3549 0, /* tp_print */
3550 0, /* tp_getattr */
3551 0, /* tp_setattr */
3552 0, /* tp_reserved */
3553 0, /* tp_repr */
3554 0, /* tp_as_number */
3555 0, /* tp_as_sequence */
3556 0, /* tp_as_mapping */
3557 0, /* tp_hash */
3558 0, /* tp_call */
3559 0, /* tp_str */
3560 PyObject_GenericGetAttr, /* tp_getattro */
3561 0, /* tp_setattro */
3562 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003563 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003564 tzinfo_doc, /* tp_doc */
3565 0, /* tp_traverse */
3566 0, /* tp_clear */
3567 0, /* tp_richcompare */
3568 0, /* tp_weaklistoffset */
3569 0, /* tp_iter */
3570 0, /* tp_iternext */
3571 tzinfo_methods, /* tp_methods */
3572 0, /* tp_members */
3573 0, /* tp_getset */
3574 0, /* tp_base */
3575 0, /* tp_dict */
3576 0, /* tp_descr_get */
3577 0, /* tp_descr_set */
3578 0, /* tp_dictoffset */
3579 0, /* tp_init */
3580 0, /* tp_alloc */
3581 PyType_GenericNew, /* tp_new */
3582 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003583};
3584
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003585static char *timezone_kws[] = {"offset", "name", NULL};
3586
3587static PyObject *
3588timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3589{
3590 PyObject *offset;
3591 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003592 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3593 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003594 return new_timezone(offset, name);
3595
3596 return NULL;
3597}
3598
3599static void
3600timezone_dealloc(PyDateTime_TimeZone *self)
3601{
3602 Py_CLEAR(self->offset);
3603 Py_CLEAR(self->name);
3604 Py_TYPE(self)->tp_free((PyObject *)self);
3605}
3606
3607static PyObject *
3608timezone_richcompare(PyDateTime_TimeZone *self,
3609 PyDateTime_TimeZone *other, int op)
3610{
Brian Curtindfc80e32011-08-10 20:28:54 -05003611 if (op != Py_EQ && op != Py_NE)
3612 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003613 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003614 if (op == Py_EQ)
3615 Py_RETURN_FALSE;
3616 else
3617 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003618 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003619 return delta_richcompare(self->offset, other->offset, op);
3620}
3621
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003622static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003623timezone_hash(PyDateTime_TimeZone *self)
3624{
3625 return delta_hash((PyDateTime_Delta *)self->offset);
3626}
3627
3628/* Check argument type passed to tzname, utcoffset, or dst methods.
3629 Returns 0 for good argument. Returns -1 and sets exception info
3630 otherwise.
3631 */
3632static int
3633_timezone_check_argument(PyObject *dt, const char *meth)
3634{
3635 if (dt == Py_None || PyDateTime_Check(dt))
3636 return 0;
3637 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3638 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3639 return -1;
3640}
3641
3642static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003643timezone_repr(PyDateTime_TimeZone *self)
3644{
3645 /* Note that although timezone is not subclassable, it is convenient
3646 to use Py_TYPE(self)->tp_name here. */
3647 const char *type_name = Py_TYPE(self)->tp_name;
3648
3649 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3650 return PyUnicode_FromFormat("%s.utc", type_name);
3651
3652 if (self->name == NULL)
3653 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3654
3655 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3656 self->name);
3657}
3658
3659
3660static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003661timezone_str(PyDateTime_TimeZone *self)
3662{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003663 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003664 PyObject *offset;
3665 char sign;
3666
3667 if (self->name != NULL) {
3668 Py_INCREF(self->name);
3669 return self->name;
3670 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003671 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003672 (GET_TD_DAYS(self->offset) == 0 &&
3673 GET_TD_SECONDS(self->offset) == 0 &&
3674 GET_TD_MICROSECONDS(self->offset) == 0))
3675 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003676 /* Offset is normalized, so it is negative if days < 0 */
3677 if (GET_TD_DAYS(self->offset) < 0) {
3678 sign = '-';
3679 offset = delta_negative((PyDateTime_Delta *)self->offset);
3680 if (offset == NULL)
3681 return NULL;
3682 }
3683 else {
3684 sign = '+';
3685 offset = self->offset;
3686 Py_INCREF(offset);
3687 }
3688 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003689 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003690 seconds = GET_TD_SECONDS(offset);
3691 Py_DECREF(offset);
3692 minutes = divmod(seconds, 60, &seconds);
3693 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003694 if (microseconds != 0) {
3695 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3696 sign, hours, minutes,
3697 seconds, microseconds);
3698 }
3699 if (seconds != 0) {
3700 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3701 sign, hours, minutes, seconds);
3702 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003703 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003704}
3705
3706static PyObject *
3707timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3708{
3709 if (_timezone_check_argument(dt, "tzname") == -1)
3710 return NULL;
3711
3712 return timezone_str(self);
3713}
3714
3715static PyObject *
3716timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3717{
3718 if (_timezone_check_argument(dt, "utcoffset") == -1)
3719 return NULL;
3720
3721 Py_INCREF(self->offset);
3722 return self->offset;
3723}
3724
3725static PyObject *
3726timezone_dst(PyObject *self, PyObject *dt)
3727{
3728 if (_timezone_check_argument(dt, "dst") == -1)
3729 return NULL;
3730
3731 Py_RETURN_NONE;
3732}
3733
3734static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003735timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3736{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003737 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003738 PyErr_SetString(PyExc_TypeError,
3739 "fromutc: argument must be a datetime");
3740 return NULL;
3741 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003742 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003743 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3744 "is not self");
3745 return NULL;
3746 }
3747
3748 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3749}
3750
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003751static PyObject *
3752timezone_getinitargs(PyDateTime_TimeZone *self)
3753{
3754 if (self->name == NULL)
3755 return Py_BuildValue("(O)", self->offset);
3756 return Py_BuildValue("(OO)", self->offset, self->name);
3757}
3758
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003759static PyMethodDef timezone_methods[] = {
3760 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3761 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003762 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003763
3764 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003765 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003766
3767 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003768 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003769
3770 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3771 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3772
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003773 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3774 PyDoc_STR("pickle support")},
3775
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003776 {NULL, NULL}
3777};
3778
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003779static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003780PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3781
3782static PyTypeObject PyDateTime_TimeZoneType = {
3783 PyVarObject_HEAD_INIT(NULL, 0)
3784 "datetime.timezone", /* tp_name */
3785 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3786 0, /* tp_itemsize */
3787 (destructor)timezone_dealloc, /* tp_dealloc */
3788 0, /* tp_print */
3789 0, /* tp_getattr */
3790 0, /* tp_setattr */
3791 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003792 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003793 0, /* tp_as_number */
3794 0, /* tp_as_sequence */
3795 0, /* tp_as_mapping */
3796 (hashfunc)timezone_hash, /* tp_hash */
3797 0, /* tp_call */
3798 (reprfunc)timezone_str, /* tp_str */
3799 0, /* tp_getattro */
3800 0, /* tp_setattro */
3801 0, /* tp_as_buffer */
3802 Py_TPFLAGS_DEFAULT, /* tp_flags */
3803 timezone_doc, /* tp_doc */
3804 0, /* tp_traverse */
3805 0, /* tp_clear */
3806 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3807 0, /* tp_weaklistoffset */
3808 0, /* tp_iter */
3809 0, /* tp_iternext */
3810 timezone_methods, /* tp_methods */
3811 0, /* tp_members */
3812 0, /* tp_getset */
3813 &PyDateTime_TZInfoType, /* tp_base */
3814 0, /* tp_dict */
3815 0, /* tp_descr_get */
3816 0, /* tp_descr_set */
3817 0, /* tp_dictoffset */
3818 0, /* tp_init */
3819 0, /* tp_alloc */
3820 timezone_new, /* tp_new */
3821};
3822
Tim Peters2a799bf2002-12-16 20:18:38 +00003823/*
Tim Peters37f39822003-01-10 03:49:02 +00003824 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003825 */
3826
Tim Peters37f39822003-01-10 03:49:02 +00003827/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003828 */
3829
3830static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003831time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003833 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003834}
3835
Tim Peters37f39822003-01-10 03:49:02 +00003836static PyObject *
3837time_minute(PyDateTime_Time *self, void *unused)
3838{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003839 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003840}
3841
3842/* The name time_second conflicted with some platform header file. */
3843static PyObject *
3844py_time_second(PyDateTime_Time *self, void *unused)
3845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003846 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003847}
3848
3849static PyObject *
3850time_microsecond(PyDateTime_Time *self, void *unused)
3851{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003852 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003853}
3854
3855static PyObject *
3856time_tzinfo(PyDateTime_Time *self, void *unused)
3857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3859 Py_INCREF(result);
3860 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003861}
3862
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003863static PyObject *
3864time_fold(PyDateTime_Time *self, void *unused)
3865{
3866 return PyLong_FromLong(TIME_GET_FOLD(self));
3867}
3868
Tim Peters37f39822003-01-10 03:49:02 +00003869static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003870 {"hour", (getter)time_hour},
3871 {"minute", (getter)time_minute},
3872 {"second", (getter)py_time_second},
3873 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003874 {"tzinfo", (getter)time_tzinfo},
3875 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003876 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003877};
3878
3879/*
3880 * Constructors.
3881 */
3882
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003883static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003884 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003885
Tim Peters2a799bf2002-12-16 20:18:38 +00003886static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003887time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003888{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003889 PyObject *self = NULL;
3890 PyObject *state;
3891 int hour = 0;
3892 int minute = 0;
3893 int second = 0;
3894 int usecond = 0;
3895 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003896 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003898 /* Check for invocation from pickle with __getstate__ state */
3899 if (PyTuple_GET_SIZE(args) >= 1 &&
3900 PyTuple_GET_SIZE(args) <= 2 &&
3901 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3902 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003903 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003904 {
3905 PyDateTime_Time *me;
3906 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003908 if (PyTuple_GET_SIZE(args) == 2) {
3909 tzinfo = PyTuple_GET_ITEM(args, 1);
3910 if (check_tzinfo_subclass(tzinfo) < 0) {
3911 PyErr_SetString(PyExc_TypeError, "bad "
3912 "tzinfo state arg");
3913 return NULL;
3914 }
3915 }
3916 aware = (char)(tzinfo != Py_None);
3917 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3918 if (me != NULL) {
3919 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003921 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3922 me->hashcode = -1;
3923 me->hastzinfo = aware;
3924 if (aware) {
3925 Py_INCREF(tzinfo);
3926 me->tzinfo = tzinfo;
3927 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003928 if (pdata[0] & (1 << 7)) {
3929 me->data[0] -= 128;
3930 me->fold = 1;
3931 }
3932 else {
3933 me->fold = 0;
3934 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003935 }
3936 return (PyObject *)me;
3937 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003938
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003939 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003940 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003941 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003942 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3943 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003944 }
3945 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003946}
3947
3948/*
3949 * Destructor.
3950 */
3951
3952static void
Tim Peters37f39822003-01-10 03:49:02 +00003953time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003955 if (HASTZINFO(self)) {
3956 Py_XDECREF(self->tzinfo);
3957 }
3958 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003959}
3960
3961/*
Tim Peters855fe882002-12-22 03:43:39 +00003962 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003963 */
3964
Tim Peters2a799bf2002-12-16 20:18:38 +00003965/* These are all METH_NOARGS, so don't need to check the arglist. */
3966static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003967time_utcoffset(PyObject *self, PyObject *unused) {
3968 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003969}
3970
3971static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003972time_dst(PyObject *self, PyObject *unused) {
3973 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003974}
3975
3976static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003977time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003978 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003979}
3980
3981/*
Tim Peters37f39822003-01-10 03:49:02 +00003982 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003983 */
3984
3985static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003986time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003988 const char *type_name = Py_TYPE(self)->tp_name;
3989 int h = TIME_GET_HOUR(self);
3990 int m = TIME_GET_MINUTE(self);
3991 int s = TIME_GET_SECOND(self);
3992 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003993 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003994 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003996 if (us)
3997 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3998 type_name, h, m, s, us);
3999 else if (s)
4000 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4001 type_name, h, m, s);
4002 else
4003 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4004 if (result != NULL && HASTZINFO(self))
4005 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004006 if (result != NULL && fold)
4007 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004008 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004009}
4010
Tim Peters37f39822003-01-10 03:49:02 +00004011static PyObject *
4012time_str(PyDateTime_Time *self)
4013{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07004014 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00004015}
Tim Peters2a799bf2002-12-16 20:18:38 +00004016
4017static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004018time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004019{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004020 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004021 char *timespec = NULL;
4022 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004023 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004024 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004025 static char *specs[][2] = {
4026 {"hours", "%02d"},
4027 {"minutes", "%02d:%02d"},
4028 {"seconds", "%02d:%02d:%02d"},
4029 {"milliseconds", "%02d:%02d:%02d.%03d"},
4030 {"microseconds", "%02d:%02d:%02d.%06d"},
4031 };
4032 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004033
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004034 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4035 return NULL;
4036
4037 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4038 if (us == 0) {
4039 /* seconds */
4040 given_spec = 2;
4041 }
4042 else {
4043 /* microseconds */
4044 given_spec = 4;
4045 }
4046 }
4047 else {
4048 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4049 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4050 if (given_spec == 3) {
4051 /* milliseconds */
4052 us = us / 1000;
4053 }
4054 break;
4055 }
4056 }
4057 }
4058
4059 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4060 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4061 return NULL;
4062 }
4063 else {
4064 result = PyUnicode_FromFormat(specs[given_spec][1],
4065 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4066 TIME_GET_SECOND(self), us);
4067 }
Tim Peters37f39822003-01-10 03:49:02 +00004068
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004069 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004070 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004072 /* We need to append the UTC offset. */
4073 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4074 Py_None) < 0) {
4075 Py_DECREF(result);
4076 return NULL;
4077 }
4078 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4079 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004080}
4081
Tim Peters37f39822003-01-10 03:49:02 +00004082static PyObject *
4083time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004085 PyObject *result;
4086 PyObject *tuple;
4087 PyObject *format;
4088 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004090 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4091 &format))
4092 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004094 /* Python's strftime does insane things with the year part of the
4095 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004096 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004097 */
4098 tuple = Py_BuildValue("iiiiiiiii",
4099 1900, 1, 1, /* year, month, day */
4100 TIME_GET_HOUR(self),
4101 TIME_GET_MINUTE(self),
4102 TIME_GET_SECOND(self),
4103 0, 1, -1); /* weekday, daynum, dst */
4104 if (tuple == NULL)
4105 return NULL;
4106 assert(PyTuple_Size(tuple) == 9);
4107 result = wrap_strftime((PyObject *)self, format, tuple,
4108 Py_None);
4109 Py_DECREF(tuple);
4110 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004111}
Tim Peters2a799bf2002-12-16 20:18:38 +00004112
4113/*
4114 * Miscellaneous methods.
4115 */
4116
Tim Peters37f39822003-01-10 03:49:02 +00004117static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004118time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004119{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004120 PyObject *result = NULL;
4121 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004122 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004123
Brian Curtindfc80e32011-08-10 20:28:54 -05004124 if (! PyTime_Check(other))
4125 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004126
4127 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004128 diff = memcmp(((PyDateTime_Time *)self)->data,
4129 ((PyDateTime_Time *)other)->data,
4130 _PyDateTime_TIME_DATASIZE);
4131 return diff_to_bool(diff, op);
4132 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004133 offset1 = time_utcoffset(self, NULL);
4134 if (offset1 == NULL)
4135 return NULL;
4136 offset2 = time_utcoffset(other, NULL);
4137 if (offset2 == NULL)
4138 goto done;
4139 /* If they're both naive, or both aware and have the same offsets,
4140 * we get off cheap. Note that if they're both naive, offset1 ==
4141 * offset2 == Py_None at this point.
4142 */
4143 if ((offset1 == offset2) ||
4144 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4145 delta_cmp(offset1, offset2) == 0)) {
4146 diff = memcmp(((PyDateTime_Time *)self)->data,
4147 ((PyDateTime_Time *)other)->data,
4148 _PyDateTime_TIME_DATASIZE);
4149 result = diff_to_bool(diff, op);
4150 }
4151 /* The hard case: both aware with different UTC offsets */
4152 else if (offset1 != Py_None && offset2 != Py_None) {
4153 int offsecs1, offsecs2;
4154 assert(offset1 != offset2); /* else last "if" handled it */
4155 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4156 TIME_GET_MINUTE(self) * 60 +
4157 TIME_GET_SECOND(self) -
4158 GET_TD_DAYS(offset1) * 86400 -
4159 GET_TD_SECONDS(offset1);
4160 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4161 TIME_GET_MINUTE(other) * 60 +
4162 TIME_GET_SECOND(other) -
4163 GET_TD_DAYS(offset2) * 86400 -
4164 GET_TD_SECONDS(offset2);
4165 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004166 if (diff == 0)
4167 diff = TIME_GET_MICROSECOND(self) -
4168 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004169 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004170 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004171 else if (op == Py_EQ) {
4172 result = Py_False;
4173 Py_INCREF(result);
4174 }
4175 else if (op == Py_NE) {
4176 result = Py_True;
4177 Py_INCREF(result);
4178 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004179 else {
4180 PyErr_SetString(PyExc_TypeError,
4181 "can't compare offset-naive and "
4182 "offset-aware times");
4183 }
4184 done:
4185 Py_DECREF(offset1);
4186 Py_XDECREF(offset2);
4187 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004188}
4189
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004190static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004191time_hash(PyDateTime_Time *self)
4192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004194 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004195 if (TIME_GET_FOLD(self)) {
4196 self0 = new_time_ex2(TIME_GET_HOUR(self),
4197 TIME_GET_MINUTE(self),
4198 TIME_GET_SECOND(self),
4199 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004200 HASTZINFO(self) ? self->tzinfo : Py_None,
4201 0, Py_TYPE(self));
4202 if (self0 == NULL)
4203 return -1;
4204 }
4205 else {
4206 self0 = (PyObject *)self;
4207 Py_INCREF(self0);
4208 }
4209 offset = time_utcoffset(self0, NULL);
4210 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004211
4212 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004213 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004215 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004216 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004217 self->hashcode = generic_hash(
4218 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004219 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004220 PyObject *temp1, *temp2;
4221 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004222 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004223 seconds = TIME_GET_HOUR(self) * 3600 +
4224 TIME_GET_MINUTE(self) * 60 +
4225 TIME_GET_SECOND(self);
4226 microseconds = TIME_GET_MICROSECOND(self);
4227 temp1 = new_delta(0, seconds, microseconds, 1);
4228 if (temp1 == NULL) {
4229 Py_DECREF(offset);
4230 return -1;
4231 }
4232 temp2 = delta_subtract(temp1, offset);
4233 Py_DECREF(temp1);
4234 if (temp2 == NULL) {
4235 Py_DECREF(offset);
4236 return -1;
4237 }
4238 self->hashcode = PyObject_Hash(temp2);
4239 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004240 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004241 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004242 }
4243 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004244}
Tim Peters2a799bf2002-12-16 20:18:38 +00004245
Tim Peters12bf3392002-12-24 05:41:27 +00004246static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004247time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004248{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004249 PyObject *clone;
4250 PyObject *tuple;
4251 int hh = TIME_GET_HOUR(self);
4252 int mm = TIME_GET_MINUTE(self);
4253 int ss = TIME_GET_SECOND(self);
4254 int us = TIME_GET_MICROSECOND(self);
4255 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004256 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004257
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004258 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004259 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004260 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004261 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004262 if (fold != 0 && fold != 1) {
4263 PyErr_SetString(PyExc_ValueError,
4264 "fold must be either 0 or 1");
4265 return NULL;
4266 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004267 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4268 if (tuple == NULL)
4269 return NULL;
4270 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004271 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004272 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004273 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004274 Py_DECREF(tuple);
4275 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004276}
4277
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004278static PyObject *
4279time_fromisoformat(PyObject *cls, PyObject *tstr) {
4280 assert(tstr != NULL);
4281
4282 if (!PyUnicode_Check(tstr)) {
4283 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4284 return NULL;
4285 }
4286
4287 Py_ssize_t len;
4288 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4289
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004290 if (p == NULL) {
4291 goto invalid_string_error;
4292 }
4293
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004294 int hour = 0, minute = 0, second = 0, microsecond = 0;
4295 int tzoffset, tzimicrosecond = 0;
4296 int rv = parse_isoformat_time(p, len,
4297 &hour, &minute, &second, &microsecond,
4298 &tzoffset, &tzimicrosecond);
4299
4300 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004301 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004302 }
4303
4304 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4305 tzimicrosecond);
4306
4307 if (tzinfo == NULL) {
4308 return NULL;
4309 }
4310
4311 PyObject *t;
4312 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4313 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4314 } else {
4315 t = PyObject_CallFunction(cls, "iiiiO",
4316 hour, minute, second, microsecond, tzinfo);
4317 }
4318
4319 Py_DECREF(tzinfo);
4320 return t;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004321
4322invalid_string_error:
4323 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4324 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004325}
4326
4327
Tim Peters371935f2003-02-01 01:52:50 +00004328/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004329
Tim Peters33e0f382003-01-10 02:05:14 +00004330/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004331 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4332 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004333 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004334 */
4335static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004336time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004338 PyObject *basestate;
4339 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004341 basestate = PyBytes_FromStringAndSize((char *)self->data,
4342 _PyDateTime_TIME_DATASIZE);
4343 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004344 if (proto > 3 && TIME_GET_FOLD(self))
4345 /* Set the first bit of the first byte */
4346 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004347 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4348 result = PyTuple_Pack(1, basestate);
4349 else
4350 result = PyTuple_Pack(2, basestate, self->tzinfo);
4351 Py_DECREF(basestate);
4352 }
4353 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004354}
4355
4356static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004357time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004358{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004359 int proto;
4360 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004361 return NULL;
4362
4363 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004364}
4365
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004366static PyObject *
4367time_reduce(PyDateTime_Time *self, PyObject *arg)
4368{
4369 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4370}
4371
Tim Peters37f39822003-01-10 03:49:02 +00004372static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004373
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004374 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4375 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4376 "[+HH:MM].\n\n"
4377 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004379 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4380 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004382 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4383 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004385 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4386 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004388 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4389 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004391 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4392 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004394 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4395 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004396
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004397 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4398 PyDoc_STR("string -> time from time.isoformat() output")},
4399
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004400 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004401 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004402
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004403 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4404 PyDoc_STR("__reduce__() -> (cls, state)")},
4405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004406 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004407};
4408
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004409static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004410PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4411\n\
4412All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004413a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004414
Neal Norwitz227b5332006-03-22 09:28:35 +00004415static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004416 PyVarObject_HEAD_INIT(NULL, 0)
4417 "datetime.time", /* tp_name */
4418 sizeof(PyDateTime_Time), /* tp_basicsize */
4419 0, /* tp_itemsize */
4420 (destructor)time_dealloc, /* tp_dealloc */
4421 0, /* tp_print */
4422 0, /* tp_getattr */
4423 0, /* tp_setattr */
4424 0, /* tp_reserved */
4425 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004426 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004427 0, /* tp_as_sequence */
4428 0, /* tp_as_mapping */
4429 (hashfunc)time_hash, /* tp_hash */
4430 0, /* tp_call */
4431 (reprfunc)time_str, /* tp_str */
4432 PyObject_GenericGetAttr, /* tp_getattro */
4433 0, /* tp_setattro */
4434 0, /* tp_as_buffer */
4435 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4436 time_doc, /* tp_doc */
4437 0, /* tp_traverse */
4438 0, /* tp_clear */
4439 time_richcompare, /* tp_richcompare */
4440 0, /* tp_weaklistoffset */
4441 0, /* tp_iter */
4442 0, /* tp_iternext */
4443 time_methods, /* tp_methods */
4444 0, /* tp_members */
4445 time_getset, /* tp_getset */
4446 0, /* tp_base */
4447 0, /* tp_dict */
4448 0, /* tp_descr_get */
4449 0, /* tp_descr_set */
4450 0, /* tp_dictoffset */
4451 0, /* tp_init */
4452 time_alloc, /* tp_alloc */
4453 time_new, /* tp_new */
4454 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004455};
4456
4457/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004458 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004459 */
4460
Tim Petersa9bc1682003-01-11 03:39:11 +00004461/* Accessor properties. Properties for day, month, and year are inherited
4462 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004463 */
4464
4465static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004466datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004468 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004469}
4470
Tim Petersa9bc1682003-01-11 03:39:11 +00004471static PyObject *
4472datetime_minute(PyDateTime_DateTime *self, void *unused)
4473{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004474 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004475}
4476
4477static PyObject *
4478datetime_second(PyDateTime_DateTime *self, void *unused)
4479{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004480 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004481}
4482
4483static PyObject *
4484datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004486 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004487}
4488
4489static PyObject *
4490datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004492 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4493 Py_INCREF(result);
4494 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004495}
4496
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004497static PyObject *
4498datetime_fold(PyDateTime_DateTime *self, void *unused)
4499{
4500 return PyLong_FromLong(DATE_GET_FOLD(self));
4501}
4502
Tim Petersa9bc1682003-01-11 03:39:11 +00004503static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004504 {"hour", (getter)datetime_hour},
4505 {"minute", (getter)datetime_minute},
4506 {"second", (getter)datetime_second},
4507 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004508 {"tzinfo", (getter)datetime_tzinfo},
4509 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004510 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004511};
4512
4513/*
4514 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004515 */
4516
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004517static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004518 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004519 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004520};
4521
Tim Peters2a799bf2002-12-16 20:18:38 +00004522static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004523datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004524{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004525 PyObject *self = NULL;
4526 PyObject *state;
4527 int year;
4528 int month;
4529 int day;
4530 int hour = 0;
4531 int minute = 0;
4532 int second = 0;
4533 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004534 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004535 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004537 /* Check for invocation from pickle with __getstate__ state */
4538 if (PyTuple_GET_SIZE(args) >= 1 &&
4539 PyTuple_GET_SIZE(args) <= 2 &&
4540 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4541 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004542 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004543 {
4544 PyDateTime_DateTime *me;
4545 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004547 if (PyTuple_GET_SIZE(args) == 2) {
4548 tzinfo = PyTuple_GET_ITEM(args, 1);
4549 if (check_tzinfo_subclass(tzinfo) < 0) {
4550 PyErr_SetString(PyExc_TypeError, "bad "
4551 "tzinfo state arg");
4552 return NULL;
4553 }
4554 }
4555 aware = (char)(tzinfo != Py_None);
4556 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4557 if (me != NULL) {
4558 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004560 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4561 me->hashcode = -1;
4562 me->hastzinfo = aware;
4563 if (aware) {
4564 Py_INCREF(tzinfo);
4565 me->tzinfo = tzinfo;
4566 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004567 if (pdata[2] & (1 << 7)) {
4568 me->data[2] -= 128;
4569 me->fold = 1;
4570 }
4571 else {
4572 me->fold = 0;
4573 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004574 }
4575 return (PyObject *)me;
4576 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004577
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004578 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004579 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004580 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004581 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004582 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004583 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004584 }
4585 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004586}
4587
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004588/* TM_FUNC is the shared type of _PyTime_localtime() and
4589 * _PyTime_gmtime(). */
4590typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004591
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004592/* As of version 2015f max fold in IANA database is
4593 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004594static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004595/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004596static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004597
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004598static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004599utc_to_seconds(int year, int month, int day,
4600 int hour, int minute, int second)
4601{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004602 long long ordinal;
4603
4604 /* ymd_to_ord() doesn't support year <= 0 */
4605 if (year < MINYEAR || year > MAXYEAR) {
4606 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4607 return -1;
4608 }
4609
4610 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004611 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4612}
4613
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004614static long long
4615local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004616{
4617 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004618 time_t t;
4619 u -= epoch;
4620 t = u;
4621 if (t != u) {
4622 PyErr_SetString(PyExc_OverflowError,
4623 "timestamp out of range for platform time_t");
4624 return -1;
4625 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004626 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004627 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004628 return utc_to_seconds(local_time.tm_year + 1900,
4629 local_time.tm_mon + 1,
4630 local_time.tm_mday,
4631 local_time.tm_hour,
4632 local_time.tm_min,
4633 local_time.tm_sec);
4634}
4635
Tim Petersa9bc1682003-01-11 03:39:11 +00004636/* Internal helper.
4637 * Build datetime from a time_t and a distinct count of microseconds.
4638 * Pass localtime or gmtime for f, to control the interpretation of timet.
4639 */
4640static PyObject *
4641datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004642 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004643{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004644 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004645 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004646
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004647 if (f(timet, &tm) != 0)
4648 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004649
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004650 year = tm.tm_year + 1900;
4651 month = tm.tm_mon + 1;
4652 day = tm.tm_mday;
4653 hour = tm.tm_hour;
4654 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004655 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004656 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004657 * except to the extent that passing them on to the datetime
4658 * constructor would raise ValueError for a reason that
4659 * made no sense to the user.
4660 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004661 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004662
Victor Stinnerb67f0962017-02-10 10:34:02 +01004663 /* local timezone requires to compute fold */
Miss Islington (bot)97364932018-07-25 13:34:09 -07004664 if (tzinfo == Py_None && f == _PyTime_localtime
4665 /* On Windows, passing a negative value to local results
4666 * in an OSError because localtime_s on Windows does
4667 * not support negative timestamps. Unfortunately this
4668 * means that fold detection for time values between
4669 * 0 and max_fold_seconds will result in an identical
4670 * error since we subtract max_fold_seconds to detect a
4671 * fold. However, since we know there haven't been any
4672 * folds in the interval [0, max_fold_seconds) in any
4673 * timezone, we can hackily just forego fold detection
4674 * for this time range.
4675 */
4676#ifdef MS_WINDOWS
4677 && (timet - max_fold_seconds > 0)
4678#endif
4679 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004680 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004681
4682 result_seconds = utc_to_seconds(year, month, day,
4683 hour, minute, second);
4684 /* Probe max_fold_seconds to detect a fold. */
4685 probe_seconds = local(epoch + timet - max_fold_seconds);
4686 if (probe_seconds == -1)
4687 return NULL;
4688 transition = result_seconds - probe_seconds - max_fold_seconds;
4689 if (transition < 0) {
4690 probe_seconds = local(epoch + timet + transition);
4691 if (probe_seconds == -1)
4692 return NULL;
4693 if (probe_seconds == result_seconds)
4694 fold = 1;
4695 }
4696 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004697 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4698 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004699}
4700
4701/* Internal helper.
4702 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4703 * to control the interpretation of the timestamp. Since a double doesn't
4704 * have enough bits to cover a datetime's full range of precision, it's
4705 * better to call datetime_from_timet_and_us provided you have a way
4706 * to get that much precision (e.g., C time() isn't good enough).
4707 */
4708static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004709datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004710 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004711{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004712 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004713 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004714
Victor Stinnere4a994d2015-03-30 01:10:14 +02004715 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004716 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004717 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004718
Victor Stinner21f58932012-03-14 00:15:40 +01004719 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004720}
4721
4722/* Internal helper.
4723 * Build most accurate possible datetime for current time. Pass localtime or
4724 * gmtime for f as appropriate.
4725 */
4726static PyObject *
4727datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4728{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004729 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004730 time_t secs;
4731 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004732
Victor Stinner1e2b6882015-09-18 13:23:02 +02004733 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004734 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004735 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004736
Victor Stinner1e2b6882015-09-18 13:23:02 +02004737 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004738}
4739
Larry Hastings61272b72014-01-07 12:41:53 -08004740/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004741
4742@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004743datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004744
4745 tz: object = None
4746 Timezone object.
4747
4748Returns new datetime object representing current time local to tz.
4749
4750If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004751[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004752
Larry Hastings31826802013-10-19 00:09:25 -07004753static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004754datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004755/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004757 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004758
Larry Hastings31826802013-10-19 00:09:25 -07004759 /* Return best possible local time -- this isn't constrained by the
4760 * precision of a timestamp.
4761 */
4762 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004763 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004764
Larry Hastings5c661892014-01-24 06:17:25 -08004765 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004766 tz == Py_None ? _PyTime_localtime :
4767 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004768 tz);
4769 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004770 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004771 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004772 }
4773 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004774}
4775
Tim Petersa9bc1682003-01-11 03:39:11 +00004776/* Return best possible UTC time -- this isn't constrained by the
4777 * precision of a timestamp.
4778 */
4779static PyObject *
4780datetime_utcnow(PyObject *cls, PyObject *dummy)
4781{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004782 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004783}
4784
Tim Peters2a799bf2002-12-16 20:18:38 +00004785/* Return new local datetime from timestamp (Python timestamp -- a double). */
4786static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004787datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004789 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004790 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004791 PyObject *tzinfo = Py_None;
4792 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004793
Victor Stinner5d272cc2012-03-13 13:35:55 +01004794 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004795 keywords, &timestamp, &tzinfo))
4796 return NULL;
4797 if (check_tzinfo_subclass(tzinfo) < 0)
4798 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004800 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004801 tzinfo == Py_None ? _PyTime_localtime :
4802 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004803 timestamp,
4804 tzinfo);
4805 if (self != NULL && tzinfo != Py_None) {
4806 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004807 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004808 }
4809 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004810}
4811
Tim Petersa9bc1682003-01-11 03:39:11 +00004812/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4813static PyObject *
4814datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4815{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004816 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004817 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004818
Victor Stinner5d272cc2012-03-13 13:35:55 +01004819 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004820 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004821 Py_None);
4822 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004823}
4824
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004825/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004826static PyObject *
4827datetime_strptime(PyObject *cls, PyObject *args)
4828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004829 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004830 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004831 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004832
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004833 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004834 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004835
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004836 if (module == NULL) {
4837 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004838 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004839 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004840 }
Victor Stinner20401de2016-12-09 15:24:31 +01004841 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4842 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004843}
4844
Tim Petersa9bc1682003-01-11 03:39:11 +00004845/* Return new datetime from date/datetime and time arguments. */
4846static PyObject *
4847datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4848{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004849 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004850 PyObject *date;
4851 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004852 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004853 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004854
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004855 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004856 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004857 &PyDateTime_TimeType, &time, &tzinfo)) {
4858 if (tzinfo == NULL) {
4859 if (HASTZINFO(time))
4860 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4861 else
4862 tzinfo = Py_None;
4863 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004864 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
4865 GET_MONTH(date),
4866 GET_DAY(date),
4867 TIME_GET_HOUR(time),
4868 TIME_GET_MINUTE(time),
4869 TIME_GET_SECOND(time),
4870 TIME_GET_MICROSECOND(time),
4871 tzinfo,
4872 TIME_GET_FOLD(time),
4873 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004874 }
4875 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004876}
Tim Peters2a799bf2002-12-16 20:18:38 +00004877
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004878static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004879_sanitize_isoformat_str(PyObject *dtstr)
4880{
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004881 // `fromisoformat` allows surrogate characters in exactly one position,
4882 // the separator; to allow datetime_fromisoformat to make the simplifying
4883 // assumption that all valid strings can be encoded in UTF-8, this function
4884 // replaces any surrogate character separators with `T`.
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004885 //
4886 // The result of this, if not NULL, returns a new reference
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004887 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004888 if (len < 0) {
4889 return NULL;
4890 }
4891
4892 if (len <= 10 ||
4893 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
4894 Py_INCREF(dtstr);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004895 return dtstr;
4896 }
4897
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004898 PyObject *str_out = _PyUnicode_Copy(dtstr);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004899 if (str_out == NULL) {
4900 return NULL;
4901 }
4902
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004903 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004904 Py_DECREF(str_out);
4905 return NULL;
4906 }
4907
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004908 return str_out;
4909}
4910
4911static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004912datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
4913{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004914 assert(dtstr != NULL);
4915
4916 if (!PyUnicode_Check(dtstr)) {
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004917 PyErr_SetString(PyExc_TypeError,
4918 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004919 return NULL;
4920 }
4921
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004922 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
4923 if (dtstr_clean == NULL) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004924 goto error;
4925 }
4926
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004927 Py_ssize_t len;
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004928 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004929
4930 if (dt_ptr == NULL) {
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004931 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4932 // Encoding errors are invalid string errors at this point
4933 goto invalid_string_error;
4934 }
4935 else {
4936 goto error;
4937 }
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004938 }
4939
4940 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004941
4942 int year = 0, month = 0, day = 0;
4943 int hour = 0, minute = 0, second = 0, microsecond = 0;
4944 int tzoffset = 0, tzusec = 0;
4945
4946 // date has a fixed length of 10
4947 int rv = parse_isoformat_date(p, &year, &month, &day);
4948
4949 if (!rv && len > 10) {
4950 // In UTF-8, the length of multi-byte characters is encoded in the MSB
4951 if ((p[10] & 0x80) == 0) {
4952 p += 11;
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004953 }
4954 else {
4955 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004956 case 0xe0:
4957 p += 13;
4958 break;
4959 case 0xf0:
4960 p += 14;
4961 break;
4962 default:
4963 p += 12;
4964 break;
4965 }
4966 }
4967
4968 len -= (p - dt_ptr);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004969 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
4970 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004971 }
4972 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004973 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004974 }
4975
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004976 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004977 if (tzinfo == NULL) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004978 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004979 }
4980
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004981 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
4982 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004983
4984 Py_DECREF(tzinfo);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004985 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004986 return dt;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004987
4988invalid_string_error:
4989 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
4990
4991error:
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004992 Py_XDECREF(dtstr_clean);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004993
4994 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004995}
4996
Tim Peters2a799bf2002-12-16 20:18:38 +00004997/*
4998 * Destructor.
4999 */
5000
5001static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005002datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005004 if (HASTZINFO(self)) {
5005 Py_XDECREF(self->tzinfo);
5006 }
5007 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005008}
5009
5010/*
5011 * Indirect access to tzinfo methods.
5012 */
5013
Tim Peters2a799bf2002-12-16 20:18:38 +00005014/* These are all METH_NOARGS, so don't need to check the arglist. */
5015static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005016datetime_utcoffset(PyObject *self, PyObject *unused) {
5017 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005018}
5019
5020static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005021datetime_dst(PyObject *self, PyObject *unused) {
5022 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005023}
5024
5025static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005026datetime_tzname(PyObject *self, PyObject *unused) {
5027 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005028}
5029
5030/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005031 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005032 */
5033
Tim Petersa9bc1682003-01-11 03:39:11 +00005034/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5035 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005036 */
5037static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005038add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005039 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005040{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005041 /* Note that the C-level additions can't overflow, because of
5042 * invariant bounds on the member values.
5043 */
5044 int year = GET_YEAR(date);
5045 int month = GET_MONTH(date);
5046 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5047 int hour = DATE_GET_HOUR(date);
5048 int minute = DATE_GET_MINUTE(date);
5049 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5050 int microsecond = DATE_GET_MICROSECOND(date) +
5051 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005053 assert(factor == 1 || factor == -1);
5054 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005055 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005056 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005057 }
5058
5059 return new_datetime(year, month, day,
5060 hour, minute, second, microsecond,
5061 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005062}
5063
5064static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005065datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005067 if (PyDateTime_Check(left)) {
5068 /* datetime + ??? */
5069 if (PyDelta_Check(right))
5070 /* datetime + delta */
5071 return add_datetime_timedelta(
5072 (PyDateTime_DateTime *)left,
5073 (PyDateTime_Delta *)right,
5074 1);
5075 }
5076 else if (PyDelta_Check(left)) {
5077 /* delta + datetime */
5078 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5079 (PyDateTime_Delta *) left,
5080 1);
5081 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005082 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005083}
5084
5085static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005086datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005088 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005090 if (PyDateTime_Check(left)) {
5091 /* datetime - ??? */
5092 if (PyDateTime_Check(right)) {
5093 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005094 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005095 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005096
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005097 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5098 offset2 = offset1 = Py_None;
5099 Py_INCREF(offset1);
5100 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005101 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005102 else {
5103 offset1 = datetime_utcoffset(left, NULL);
5104 if (offset1 == NULL)
5105 return NULL;
5106 offset2 = datetime_utcoffset(right, NULL);
5107 if (offset2 == NULL) {
5108 Py_DECREF(offset1);
5109 return NULL;
5110 }
5111 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5112 PyErr_SetString(PyExc_TypeError,
5113 "can't subtract offset-naive and "
5114 "offset-aware datetimes");
5115 Py_DECREF(offset1);
5116 Py_DECREF(offset2);
5117 return NULL;
5118 }
5119 }
5120 if ((offset1 != offset2) &&
5121 delta_cmp(offset1, offset2) != 0) {
5122 offdiff = delta_subtract(offset1, offset2);
5123 if (offdiff == NULL) {
5124 Py_DECREF(offset1);
5125 Py_DECREF(offset2);
5126 return NULL;
5127 }
5128 }
5129 Py_DECREF(offset1);
5130 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005131 delta_d = ymd_to_ord(GET_YEAR(left),
5132 GET_MONTH(left),
5133 GET_DAY(left)) -
5134 ymd_to_ord(GET_YEAR(right),
5135 GET_MONTH(right),
5136 GET_DAY(right));
5137 /* These can't overflow, since the values are
5138 * normalized. At most this gives the number of
5139 * seconds in one day.
5140 */
5141 delta_s = (DATE_GET_HOUR(left) -
5142 DATE_GET_HOUR(right)) * 3600 +
5143 (DATE_GET_MINUTE(left) -
5144 DATE_GET_MINUTE(right)) * 60 +
5145 (DATE_GET_SECOND(left) -
5146 DATE_GET_SECOND(right));
5147 delta_us = DATE_GET_MICROSECOND(left) -
5148 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005149 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005150 if (result == NULL)
5151 return NULL;
5152
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005153 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005154 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005155 Py_DECREF(offdiff);
5156 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005157 }
5158 else if (PyDelta_Check(right)) {
5159 /* datetime - delta */
5160 result = add_datetime_timedelta(
5161 (PyDateTime_DateTime *)left,
5162 (PyDateTime_Delta *)right,
5163 -1);
5164 }
5165 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005167 if (result == Py_NotImplemented)
5168 Py_INCREF(result);
5169 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005170}
5171
5172/* Various ways to turn a datetime into a string. */
5173
5174static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005175datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005177 const char *type_name = Py_TYPE(self)->tp_name;
5178 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005180 if (DATE_GET_MICROSECOND(self)) {
5181 baserepr = PyUnicode_FromFormat(
5182 "%s(%d, %d, %d, %d, %d, %d, %d)",
5183 type_name,
5184 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5185 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5186 DATE_GET_SECOND(self),
5187 DATE_GET_MICROSECOND(self));
5188 }
5189 else if (DATE_GET_SECOND(self)) {
5190 baserepr = PyUnicode_FromFormat(
5191 "%s(%d, %d, %d, %d, %d, %d)",
5192 type_name,
5193 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5194 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5195 DATE_GET_SECOND(self));
5196 }
5197 else {
5198 baserepr = PyUnicode_FromFormat(
5199 "%s(%d, %d, %d, %d, %d)",
5200 type_name,
5201 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5202 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5203 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005204 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5205 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005206 if (baserepr == NULL || ! HASTZINFO(self))
5207 return baserepr;
5208 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005209}
5210
Tim Petersa9bc1682003-01-11 03:39:11 +00005211static PyObject *
5212datetime_str(PyDateTime_DateTime *self)
5213{
Victor Stinner4c381542016-12-09 00:33:39 +01005214 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005215}
Tim Peters2a799bf2002-12-16 20:18:38 +00005216
5217static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005218datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005220 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005221 char *timespec = NULL;
5222 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005223 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005224 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005225 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005226 static char *specs[][2] = {
5227 {"hours", "%04d-%02d-%02d%c%02d"},
5228 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5229 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5230 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5231 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5232 };
5233 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005234
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005235 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005236 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005237
5238 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5239 if (us == 0) {
5240 /* seconds */
5241 given_spec = 2;
5242 }
5243 else {
5244 /* microseconds */
5245 given_spec = 4;
5246 }
5247 }
5248 else {
5249 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5250 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5251 if (given_spec == 3) {
5252 us = us / 1000;
5253 }
5254 break;
5255 }
5256 }
5257 }
5258
5259 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5260 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5261 return NULL;
5262 }
5263 else {
5264 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005265 GET_YEAR(self), GET_MONTH(self),
5266 GET_DAY(self), (int)sep,
5267 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5268 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005269 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005271 if (!result || !HASTZINFO(self))
5272 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005274 /* We need to append the UTC offset. */
5275 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5276 (PyObject *)self) < 0) {
5277 Py_DECREF(result);
5278 return NULL;
5279 }
5280 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5281 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005282}
5283
Tim Petersa9bc1682003-01-11 03:39:11 +00005284static PyObject *
5285datetime_ctime(PyDateTime_DateTime *self)
5286{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005287 return format_ctime((PyDateTime_Date *)self,
5288 DATE_GET_HOUR(self),
5289 DATE_GET_MINUTE(self),
5290 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005291}
5292
Tim Peters2a799bf2002-12-16 20:18:38 +00005293/* Miscellaneous methods. */
5294
Tim Petersa9bc1682003-01-11 03:39:11 +00005295static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005296flip_fold(PyObject *dt)
5297{
5298 return new_datetime_ex2(GET_YEAR(dt),
5299 GET_MONTH(dt),
5300 GET_DAY(dt),
5301 DATE_GET_HOUR(dt),
5302 DATE_GET_MINUTE(dt),
5303 DATE_GET_SECOND(dt),
5304 DATE_GET_MICROSECOND(dt),
5305 HASTZINFO(dt) ?
5306 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5307 !DATE_GET_FOLD(dt),
5308 Py_TYPE(dt));
5309}
5310
5311static PyObject *
5312get_flip_fold_offset(PyObject *dt)
5313{
5314 PyObject *result, *flip_dt;
5315
5316 flip_dt = flip_fold(dt);
5317 if (flip_dt == NULL)
5318 return NULL;
5319 result = datetime_utcoffset(flip_dt, NULL);
5320 Py_DECREF(flip_dt);
5321 return result;
5322}
5323
5324/* PEP 495 exception: Whenever one or both of the operands in
5325 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakafd936662018-03-28 23:05:24 +03005326 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005327 *
5328 * Return 1 if exception applies, 0 if not, and -1 on error.
5329 */
5330static int
5331pep495_eq_exception(PyObject *self, PyObject *other,
5332 PyObject *offset_self, PyObject *offset_other)
5333{
5334 int result = 0;
5335 PyObject *flip_offset;
5336
5337 flip_offset = get_flip_fold_offset(self);
5338 if (flip_offset == NULL)
5339 return -1;
5340 if (flip_offset != offset_self &&
5341 delta_cmp(flip_offset, offset_self))
5342 {
5343 result = 1;
5344 goto done;
5345 }
5346 Py_DECREF(flip_offset);
5347
5348 flip_offset = get_flip_fold_offset(other);
5349 if (flip_offset == NULL)
5350 return -1;
5351 if (flip_offset != offset_other &&
5352 delta_cmp(flip_offset, offset_other))
5353 result = 1;
5354 done:
5355 Py_DECREF(flip_offset);
5356 return result;
5357}
5358
5359static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005360datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005361{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005362 PyObject *result = NULL;
5363 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005364 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005366 if (! PyDateTime_Check(other)) {
5367 if (PyDate_Check(other)) {
5368 /* Prevent invocation of date_richcompare. We want to
5369 return NotImplemented here to give the other object
5370 a chance. But since DateTime is a subclass of
5371 Date, if the other object is a Date, it would
5372 compute an ordering based on the date part alone,
5373 and we don't want that. So force unequal or
5374 uncomparable here in that case. */
5375 if (op == Py_EQ)
5376 Py_RETURN_FALSE;
5377 if (op == Py_NE)
5378 Py_RETURN_TRUE;
5379 return cmperror(self, other);
5380 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005381 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005382 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005383
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005384 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005385 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5386 ((PyDateTime_DateTime *)other)->data,
5387 _PyDateTime_DATETIME_DATASIZE);
5388 return diff_to_bool(diff, op);
5389 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005390 offset1 = datetime_utcoffset(self, NULL);
5391 if (offset1 == NULL)
5392 return NULL;
5393 offset2 = datetime_utcoffset(other, NULL);
5394 if (offset2 == NULL)
5395 goto done;
5396 /* If they're both naive, or both aware and have the same offsets,
5397 * we get off cheap. Note that if they're both naive, offset1 ==
5398 * offset2 == Py_None at this point.
5399 */
5400 if ((offset1 == offset2) ||
5401 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5402 delta_cmp(offset1, offset2) == 0)) {
5403 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5404 ((PyDateTime_DateTime *)other)->data,
5405 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005406 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5407 int ex = pep495_eq_exception(self, other, offset1, offset2);
5408 if (ex == -1)
5409 goto done;
5410 if (ex)
5411 diff = 1;
5412 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005413 result = diff_to_bool(diff, op);
5414 }
5415 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005416 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005417
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005418 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005419 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5420 other);
5421 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005422 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005423 diff = GET_TD_DAYS(delta);
5424 if (diff == 0)
5425 diff = GET_TD_SECONDS(delta) |
5426 GET_TD_MICROSECONDS(delta);
5427 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005428 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5429 int ex = pep495_eq_exception(self, other, offset1, offset2);
5430 if (ex == -1)
5431 goto done;
5432 if (ex)
5433 diff = 1;
5434 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005435 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005436 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005437 else if (op == Py_EQ) {
5438 result = Py_False;
5439 Py_INCREF(result);
5440 }
5441 else if (op == Py_NE) {
5442 result = Py_True;
5443 Py_INCREF(result);
5444 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005445 else {
5446 PyErr_SetString(PyExc_TypeError,
5447 "can't compare offset-naive and "
5448 "offset-aware datetimes");
5449 }
5450 done:
5451 Py_DECREF(offset1);
5452 Py_XDECREF(offset2);
5453 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005454}
5455
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005456static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005457datetime_hash(PyDateTime_DateTime *self)
5458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005459 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005460 PyObject *offset, *self0;
5461 if (DATE_GET_FOLD(self)) {
5462 self0 = new_datetime_ex2(GET_YEAR(self),
5463 GET_MONTH(self),
5464 GET_DAY(self),
5465 DATE_GET_HOUR(self),
5466 DATE_GET_MINUTE(self),
5467 DATE_GET_SECOND(self),
5468 DATE_GET_MICROSECOND(self),
5469 HASTZINFO(self) ? self->tzinfo : Py_None,
5470 0, Py_TYPE(self));
5471 if (self0 == NULL)
5472 return -1;
5473 }
5474 else {
5475 self0 = (PyObject *)self;
5476 Py_INCREF(self0);
5477 }
5478 offset = datetime_utcoffset(self0, NULL);
5479 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005480
5481 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005482 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005484 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005485 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005486 self->hashcode = generic_hash(
5487 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005488 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005489 PyObject *temp1, *temp2;
5490 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005492 assert(HASTZINFO(self));
5493 days = ymd_to_ord(GET_YEAR(self),
5494 GET_MONTH(self),
5495 GET_DAY(self));
5496 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005497 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005498 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005499 temp1 = new_delta(days, seconds,
5500 DATE_GET_MICROSECOND(self),
5501 1);
5502 if (temp1 == NULL) {
5503 Py_DECREF(offset);
5504 return -1;
5505 }
5506 temp2 = delta_subtract(temp1, offset);
5507 Py_DECREF(temp1);
5508 if (temp2 == NULL) {
5509 Py_DECREF(offset);
5510 return -1;
5511 }
5512 self->hashcode = PyObject_Hash(temp2);
5513 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005514 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005515 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005516 }
5517 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005518}
Tim Peters2a799bf2002-12-16 20:18:38 +00005519
5520static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005521datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005523 PyObject *clone;
5524 PyObject *tuple;
5525 int y = GET_YEAR(self);
5526 int m = GET_MONTH(self);
5527 int d = GET_DAY(self);
5528 int hh = DATE_GET_HOUR(self);
5529 int mm = DATE_GET_MINUTE(self);
5530 int ss = DATE_GET_SECOND(self);
5531 int us = DATE_GET_MICROSECOND(self);
5532 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005533 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005534
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005535 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005536 datetime_kws,
5537 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005538 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005539 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005540 if (fold != 0 && fold != 1) {
5541 PyErr_SetString(PyExc_ValueError,
5542 "fold must be either 0 or 1");
5543 return NULL;
5544 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005545 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5546 if (tuple == NULL)
5547 return NULL;
5548 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005549 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005550 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005551 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005552 Py_DECREF(tuple);
5553 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005554}
5555
5556static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005557local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005558{
5559 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005560 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005561 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005562 PyObject *nameo = NULL;
5563 const char *zone = NULL;
5564
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005565 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005566 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005567#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005568 zone = local_time_tm.tm_zone;
5569 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005570#else /* HAVE_STRUCT_TM_TM_ZONE */
5571 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005572 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005573 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005574 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005575 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005576 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005577 local_time = new_datetime(local_time_tm.tm_year + 1900,
5578 local_time_tm.tm_mon + 1,
5579 local_time_tm.tm_mday,
5580 local_time_tm.tm_hour,
5581 local_time_tm.tm_min,
5582 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005583 if (local_time == NULL) {
5584 return NULL;
5585 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005586 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005587 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005588 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5589 utc_time_tm.tm_mon + 1,
5590 utc_time_tm.tm_mday,
5591 utc_time_tm.tm_hour,
5592 utc_time_tm.tm_min,
5593 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005594 if (utc_time == NULL) {
5595 Py_DECREF(local_time);
5596 return NULL;
5597 }
5598 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005599 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005600 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005601 }
5602#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005603 if (delta == NULL) {
5604 return NULL;
5605 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005606 if (zone != NULL) {
5607 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5608 if (nameo == NULL)
5609 goto error;
5610 }
5611 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005612 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005613 error:
5614 Py_DECREF(delta);
5615 return result;
5616}
5617
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005618static PyObject *
5619local_timezone(PyDateTime_DateTime *utc_time)
5620{
5621 time_t timestamp;
5622 PyObject *delta;
5623 PyObject *one_second;
5624 PyObject *seconds;
5625
5626 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5627 if (delta == NULL)
5628 return NULL;
5629 one_second = new_delta(0, 1, 0, 0);
5630 if (one_second == NULL) {
5631 Py_DECREF(delta);
5632 return NULL;
5633 }
5634 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5635 (PyDateTime_Delta *)one_second);
5636 Py_DECREF(one_second);
5637 Py_DECREF(delta);
5638 if (seconds == NULL)
5639 return NULL;
5640 timestamp = _PyLong_AsTime_t(seconds);
5641 Py_DECREF(seconds);
5642 if (timestamp == -1 && PyErr_Occurred())
5643 return NULL;
5644 return local_timezone_from_timestamp(timestamp);
5645}
5646
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005647static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005648local_to_seconds(int year, int month, int day,
5649 int hour, int minute, int second, int fold);
5650
5651static PyObject *
5652local_timezone_from_local(PyDateTime_DateTime *local_dt)
5653{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005654 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005655 time_t timestamp;
5656 seconds = local_to_seconds(GET_YEAR(local_dt),
5657 GET_MONTH(local_dt),
5658 GET_DAY(local_dt),
5659 DATE_GET_HOUR(local_dt),
5660 DATE_GET_MINUTE(local_dt),
5661 DATE_GET_SECOND(local_dt),
5662 DATE_GET_FOLD(local_dt));
5663 if (seconds == -1)
5664 return NULL;
5665 /* XXX: add bounds check */
5666 timestamp = seconds - epoch;
5667 return local_timezone_from_timestamp(timestamp);
5668}
5669
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005670static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005671datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005672{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005673 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005674 PyObject *offset;
5675 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005676 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005677 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005678 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005679
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005680 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005681 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005682 return NULL;
5683
5684 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005685 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005686
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005687 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005688 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005689 self_tzinfo = local_timezone_from_local(self);
5690 if (self_tzinfo == NULL)
5691 return NULL;
5692 } else {
5693 self_tzinfo = self->tzinfo;
5694 Py_INCREF(self_tzinfo);
5695 }
Tim Peters521fc152002-12-31 17:36:56 +00005696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005697 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005698 if (self_tzinfo == tzinfo) {
5699 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005700 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005701 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005702 }
Tim Peters521fc152002-12-31 17:36:56 +00005703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005704 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005705 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5706 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005707 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005708 return NULL;
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005709 else if(offset == Py_None) {
5710 Py_DECREF(offset);
5711 goto naive;
5712 }
5713 else if (!PyDelta_Check(offset)) {
5714 Py_DECREF(offset);
5715 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5716 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5717 return NULL;
5718 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005719 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005720 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5721 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005722 Py_DECREF(offset);
5723 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005724 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005725
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005726 /* Make sure result is aware and UTC. */
5727 if (!HASTZINFO(result)) {
5728 temp = (PyObject *)result;
5729 result = (PyDateTime_DateTime *)
5730 new_datetime_ex2(GET_YEAR(result),
5731 GET_MONTH(result),
5732 GET_DAY(result),
5733 DATE_GET_HOUR(result),
5734 DATE_GET_MINUTE(result),
5735 DATE_GET_SECOND(result),
5736 DATE_GET_MICROSECOND(result),
5737 PyDateTime_TimeZone_UTC,
5738 DATE_GET_FOLD(result),
5739 Py_TYPE(result));
5740 Py_DECREF(temp);
5741 if (result == NULL)
5742 return NULL;
5743 }
5744 else {
5745 /* Result is already aware - just replace tzinfo. */
5746 temp = result->tzinfo;
5747 result->tzinfo = PyDateTime_TimeZone_UTC;
5748 Py_INCREF(result->tzinfo);
5749 Py_DECREF(temp);
5750 }
5751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005752 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005753 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005754 if (tzinfo == Py_None) {
5755 tzinfo = local_timezone(result);
5756 if (tzinfo == NULL) {
5757 Py_DECREF(result);
5758 return NULL;
5759 }
5760 }
5761 else
5762 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005763 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005764 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005765
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005766 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005767 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005768 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005769 Py_DECREF(temp);
5770
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005771 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005772}
5773
5774static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005775datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005777 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005779 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005780 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005781
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005782 dst = call_dst(self->tzinfo, (PyObject *)self);
5783 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005784 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005785
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005786 if (dst != Py_None)
5787 dstflag = delta_bool((PyDateTime_Delta *)dst);
5788 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005789 }
5790 return build_struct_time(GET_YEAR(self),
5791 GET_MONTH(self),
5792 GET_DAY(self),
5793 DATE_GET_HOUR(self),
5794 DATE_GET_MINUTE(self),
5795 DATE_GET_SECOND(self),
5796 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005797}
5798
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005799static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005800local_to_seconds(int year, int month, int day,
5801 int hour, int minute, int second, int fold)
5802{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005803 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005804 t = utc_to_seconds(year, month, day, hour, minute, second);
5805 /* Our goal is to solve t = local(u) for u. */
5806 lt = local(t);
5807 if (lt == -1)
5808 return -1;
5809 a = lt - t;
5810 u1 = t - a;
5811 t1 = local(u1);
5812 if (t1 == -1)
5813 return -1;
5814 if (t1 == t) {
5815 /* We found one solution, but it may not be the one we need.
5816 * Look for an earlier solution (if `fold` is 0), or a
5817 * later one (if `fold` is 1). */
5818 if (fold)
5819 u2 = u1 + max_fold_seconds;
5820 else
5821 u2 = u1 - max_fold_seconds;
5822 lt = local(u2);
5823 if (lt == -1)
5824 return -1;
5825 b = lt - u2;
5826 if (a == b)
5827 return u1;
5828 }
5829 else {
5830 b = t1 - u1;
5831 assert(a != b);
5832 }
5833 u2 = t - b;
5834 t2 = local(u2);
5835 if (t2 == -1)
5836 return -1;
5837 if (t2 == t)
5838 return u2;
5839 if (t1 == t)
5840 return u1;
5841 /* We have found both offsets a and b, but neither t - a nor t - b is
5842 * a solution. This means t is in the gap. */
5843 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5844}
5845
5846/* date(1970,1,1).toordinal() == 719163 */
5847#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5848
Tim Peters2a799bf2002-12-16 20:18:38 +00005849static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005850datetime_timestamp(PyDateTime_DateTime *self)
5851{
5852 PyObject *result;
5853
5854 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5855 PyObject *delta;
5856 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5857 if (delta == NULL)
5858 return NULL;
5859 result = delta_total_seconds(delta);
5860 Py_DECREF(delta);
5861 }
5862 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005863 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005864 seconds = local_to_seconds(GET_YEAR(self),
5865 GET_MONTH(self),
5866 GET_DAY(self),
5867 DATE_GET_HOUR(self),
5868 DATE_GET_MINUTE(self),
5869 DATE_GET_SECOND(self),
5870 DATE_GET_FOLD(self));
5871 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005872 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005873 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5874 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005875 }
5876 return result;
5877}
5878
5879static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005880datetime_getdate(PyDateTime_DateTime *self)
5881{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005882 return new_date(GET_YEAR(self),
5883 GET_MONTH(self),
5884 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005885}
5886
5887static PyObject *
5888datetime_gettime(PyDateTime_DateTime *self)
5889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005890 return new_time(DATE_GET_HOUR(self),
5891 DATE_GET_MINUTE(self),
5892 DATE_GET_SECOND(self),
5893 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005894 Py_None,
5895 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005896}
5897
5898static PyObject *
5899datetime_gettimetz(PyDateTime_DateTime *self)
5900{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005901 return new_time(DATE_GET_HOUR(self),
5902 DATE_GET_MINUTE(self),
5903 DATE_GET_SECOND(self),
5904 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005905 GET_DT_TZINFO(self),
5906 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005907}
5908
5909static PyObject *
5910datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005911{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005912 int y, m, d, hh, mm, ss;
5913 PyObject *tzinfo;
5914 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005915
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005916 tzinfo = GET_DT_TZINFO(self);
5917 if (tzinfo == Py_None) {
5918 utcself = self;
5919 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005920 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005921 else {
5922 PyObject *offset;
5923 offset = call_utcoffset(tzinfo, (PyObject *)self);
5924 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005925 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005926 if (offset == Py_None) {
5927 Py_DECREF(offset);
5928 utcself = self;
5929 Py_INCREF(utcself);
5930 }
5931 else {
5932 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5933 (PyDateTime_Delta *)offset, -1);
5934 Py_DECREF(offset);
5935 if (utcself == NULL)
5936 return NULL;
5937 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005938 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005939 y = GET_YEAR(utcself);
5940 m = GET_MONTH(utcself);
5941 d = GET_DAY(utcself);
5942 hh = DATE_GET_HOUR(utcself);
5943 mm = DATE_GET_MINUTE(utcself);
5944 ss = DATE_GET_SECOND(utcself);
5945
5946 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005947 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005948}
5949
Tim Peters371935f2003-02-01 01:52:50 +00005950/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005951
Tim Petersa9bc1682003-01-11 03:39:11 +00005952/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005953 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5954 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005955 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005956 */
5957static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005958datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005959{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005960 PyObject *basestate;
5961 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005963 basestate = PyBytes_FromStringAndSize((char *)self->data,
5964 _PyDateTime_DATETIME_DATASIZE);
5965 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005966 if (proto > 3 && DATE_GET_FOLD(self))
5967 /* Set the first bit of the third byte */
5968 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005969 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5970 result = PyTuple_Pack(1, basestate);
5971 else
5972 result = PyTuple_Pack(2, basestate, self->tzinfo);
5973 Py_DECREF(basestate);
5974 }
5975 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005976}
5977
5978static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005979datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005980{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005981 int proto;
5982 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005983 return NULL;
5984
5985 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005986}
5987
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005988static PyObject *
5989datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5990{
5991 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5992}
5993
Tim Petersa9bc1682003-01-11 03:39:11 +00005994static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005996 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005997
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005998 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006000 {"utcnow", (PyCFunction)datetime_utcnow,
6001 METH_NOARGS | METH_CLASS,
6002 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006004 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
6005 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6006 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006008 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6009 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006010 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006012 {"strptime", (PyCFunction)datetime_strptime,
6013 METH_VARARGS | METH_CLASS,
6014 PyDoc_STR("string, format -> new datetime parsed from a string "
6015 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006017 {"combine", (PyCFunction)datetime_combine,
6018 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6019 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006020
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006021 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6022 METH_O | METH_CLASS,
6023 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006025 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006027 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6028 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006030 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6031 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006033 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6034 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006036 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6037 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006039 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6040 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006041
Alexander Belopolskya4415142012-06-08 12:33:09 -04006042 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6043 PyDoc_STR("Return POSIX timestamp as float.")},
6044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006045 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6046 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006048 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
6049 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006050 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006051 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006052 "defaults to 'T'.\n"
6053 "timespec specifies what components of the time to include"
6054 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6055 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006057 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6058 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006060 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6061 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006063 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6064 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006066 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
6067 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006069 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
6070 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006071
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006072 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006073 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006074
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006075 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6076 PyDoc_STR("__reduce__() -> (cls, state)")},
6077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006078 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006079};
6080
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006081static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006082PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6083\n\
6084The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006085instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006086
Tim Petersa9bc1682003-01-11 03:39:11 +00006087static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006088 datetime_add, /* nb_add */
6089 datetime_subtract, /* nb_subtract */
6090 0, /* nb_multiply */
6091 0, /* nb_remainder */
6092 0, /* nb_divmod */
6093 0, /* nb_power */
6094 0, /* nb_negative */
6095 0, /* nb_positive */
6096 0, /* nb_absolute */
6097 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006098};
6099
Neal Norwitz227b5332006-03-22 09:28:35 +00006100static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006101 PyVarObject_HEAD_INIT(NULL, 0)
6102 "datetime.datetime", /* tp_name */
6103 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6104 0, /* tp_itemsize */
6105 (destructor)datetime_dealloc, /* tp_dealloc */
6106 0, /* tp_print */
6107 0, /* tp_getattr */
6108 0, /* tp_setattr */
6109 0, /* tp_reserved */
6110 (reprfunc)datetime_repr, /* tp_repr */
6111 &datetime_as_number, /* tp_as_number */
6112 0, /* tp_as_sequence */
6113 0, /* tp_as_mapping */
6114 (hashfunc)datetime_hash, /* tp_hash */
6115 0, /* tp_call */
6116 (reprfunc)datetime_str, /* tp_str */
6117 PyObject_GenericGetAttr, /* tp_getattro */
6118 0, /* tp_setattro */
6119 0, /* tp_as_buffer */
6120 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6121 datetime_doc, /* tp_doc */
6122 0, /* tp_traverse */
6123 0, /* tp_clear */
6124 datetime_richcompare, /* tp_richcompare */
6125 0, /* tp_weaklistoffset */
6126 0, /* tp_iter */
6127 0, /* tp_iternext */
6128 datetime_methods, /* tp_methods */
6129 0, /* tp_members */
6130 datetime_getset, /* tp_getset */
6131 &PyDateTime_DateType, /* tp_base */
6132 0, /* tp_dict */
6133 0, /* tp_descr_get */
6134 0, /* tp_descr_set */
6135 0, /* tp_dictoffset */
6136 0, /* tp_init */
6137 datetime_alloc, /* tp_alloc */
6138 datetime_new, /* tp_new */
6139 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006140};
6141
6142/* ---------------------------------------------------------------------------
6143 * Module methods and initialization.
6144 */
6145
6146static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006147 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006148};
6149
Tim Peters9ddf40b2004-06-20 22:41:32 +00006150/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6151 * datetime.h.
6152 */
6153static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006154 &PyDateTime_DateType,
6155 &PyDateTime_DateTimeType,
6156 &PyDateTime_TimeType,
6157 &PyDateTime_DeltaType,
6158 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006159 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006160 new_date_ex,
6161 new_datetime_ex,
6162 new_time_ex,
6163 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006164 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006165 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006166 date_fromtimestamp,
6167 new_datetime_ex2,
6168 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006169};
6170
6171
Martin v. Löwis1a214512008-06-11 05:26:20 +00006172
6173static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006174 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006175 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006176 "Fast implementation of the datetime type.",
6177 -1,
6178 module_methods,
6179 NULL,
6180 NULL,
6181 NULL,
6182 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006183};
6184
Tim Peters2a799bf2002-12-16 20:18:38 +00006185PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006186PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006188 PyObject *m; /* a module object */
6189 PyObject *d; /* its dict */
6190 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006191 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006193 m = PyModule_Create(&datetimemodule);
6194 if (m == NULL)
6195 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006197 if (PyType_Ready(&PyDateTime_DateType) < 0)
6198 return NULL;
6199 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6200 return NULL;
6201 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6202 return NULL;
6203 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6204 return NULL;
6205 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6206 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006207 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6208 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006210 /* timedelta values */
6211 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006213 x = new_delta(0, 0, 1, 0);
6214 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6215 return NULL;
6216 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006218 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6219 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6220 return NULL;
6221 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006223 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6224 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6225 return NULL;
6226 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006228 /* date values */
6229 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006231 x = new_date(1, 1, 1);
6232 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6233 return NULL;
6234 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006236 x = new_date(MAXYEAR, 12, 31);
6237 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6238 return NULL;
6239 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006241 x = new_delta(1, 0, 0, 0);
6242 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6243 return NULL;
6244 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006246 /* time values */
6247 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006248
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006249 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006250 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6251 return NULL;
6252 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006253
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006254 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006255 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6256 return NULL;
6257 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006259 x = new_delta(0, 0, 1, 0);
6260 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6261 return NULL;
6262 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006264 /* datetime values */
6265 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006266
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006267 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006268 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6269 return NULL;
6270 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006271
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006272 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006273 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6274 return NULL;
6275 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006277 x = new_delta(0, 0, 1, 0);
6278 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6279 return NULL;
6280 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006281
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006282 /* timezone values */
6283 d = PyDateTime_TimeZoneType.tp_dict;
6284
6285 delta = new_delta(0, 0, 0, 0);
6286 if (delta == NULL)
6287 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006288 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006289 Py_DECREF(delta);
6290 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6291 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006292 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006293 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006294
6295 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6296 if (delta == NULL)
6297 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006298 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006299 Py_DECREF(delta);
6300 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6301 return NULL;
6302 Py_DECREF(x);
6303
6304 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6305 if (delta == NULL)
6306 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006307 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006308 Py_DECREF(delta);
6309 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6310 return NULL;
6311 Py_DECREF(x);
6312
Alexander Belopolskya4415142012-06-08 12:33:09 -04006313 /* Epoch */
6314 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006315 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006316 if (PyDateTime_Epoch == NULL)
6317 return NULL;
6318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006319 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006320 PyModule_AddIntMacro(m, MINYEAR);
6321 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006323 Py_INCREF(&PyDateTime_DateType);
6324 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006326 Py_INCREF(&PyDateTime_DateTimeType);
6327 PyModule_AddObject(m, "datetime",
6328 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006330 Py_INCREF(&PyDateTime_TimeType);
6331 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006333 Py_INCREF(&PyDateTime_DeltaType);
6334 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006336 Py_INCREF(&PyDateTime_TZInfoType);
6337 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006338
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006339 Py_INCREF(&PyDateTime_TimeZoneType);
6340 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006342 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6343 if (x == NULL)
6344 return NULL;
6345 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006347 /* A 4-year cycle has an extra leap day over what we'd get from
6348 * pasting together 4 single years.
6349 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006350 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006351 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006353 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6354 * get from pasting together 4 100-year cycles.
6355 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006356 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006357 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006359 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6360 * pasting together 25 4-year cycles.
6361 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006362 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006363 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006365 us_per_ms = PyLong_FromLong(1000);
6366 us_per_second = PyLong_FromLong(1000000);
6367 us_per_minute = PyLong_FromLong(60000000);
6368 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006369 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006370 us_per_minute == NULL || seconds_per_day == NULL)
6371 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006373 /* The rest are too big for 32-bit ints, but even
6374 * us_per_week fits in 40 bits, so doubles should be exact.
6375 */
6376 us_per_hour = PyLong_FromDouble(3600000000.0);
6377 us_per_day = PyLong_FromDouble(86400000000.0);
6378 us_per_week = PyLong_FromDouble(604800000000.0);
6379 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6380 return NULL;
6381 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006382}
Tim Petersf3615152003-01-01 21:51:37 +00006383
6384/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006385Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006386 x.n = x stripped of its timezone -- its naive time.
6387 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006388 return None
Tim Petersf3615152003-01-01 21:51:37 +00006389 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006390 return None
Tim Petersf3615152003-01-01 21:51:37 +00006391 x.s = x's standard offset, x.o - x.d
6392
6393Now some derived rules, where k is a duration (timedelta).
6394
63951. x.o = x.s + x.d
6396 This follows from the definition of x.s.
6397
Tim Petersc5dc4da2003-01-02 17:55:03 +000063982. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006399 This is actually a requirement, an assumption we need to make about
6400 sane tzinfo classes.
6401
64023. The naive UTC time corresponding to x is x.n - x.o.
6403 This is again a requirement for a sane tzinfo class.
6404
64054. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006406 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006407
Tim Petersc5dc4da2003-01-02 17:55:03 +000064085. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006409 Again follows from how arithmetic is defined.
6410
Tim Peters8bb5ad22003-01-24 02:44:45 +00006411Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006412(meaning that the various tzinfo methods exist, and don't blow up or return
6413None when called).
6414
Tim Petersa9bc1682003-01-11 03:39:11 +00006415The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006416x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006417
6418By #3, we want
6419
Tim Peters8bb5ad22003-01-24 02:44:45 +00006420 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006421
6422The algorithm starts by attaching tz to x.n, and calling that y. So
6423x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6424becomes true; in effect, we want to solve [2] for k:
6425
Tim Peters8bb5ad22003-01-24 02:44:45 +00006426 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006427
6428By #1, this is the same as
6429
Tim Peters8bb5ad22003-01-24 02:44:45 +00006430 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006431
6432By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6433Substituting that into [3],
6434
Tim Peters8bb5ad22003-01-24 02:44:45 +00006435 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6436 k - (y+k).s - (y+k).d = 0; rearranging,
6437 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6438 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006439
Tim Peters8bb5ad22003-01-24 02:44:45 +00006440On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6441approximate k by ignoring the (y+k).d term at first. Note that k can't be
6442very large, since all offset-returning methods return a duration of magnitude
6443less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6444be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006445
6446In any case, the new value is
6447
Tim Peters8bb5ad22003-01-24 02:44:45 +00006448 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006449
Tim Peters8bb5ad22003-01-24 02:44:45 +00006450It's helpful to step back at look at [4] from a higher level: it's simply
6451mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006452
6453At this point, if
6454
Tim Peters8bb5ad22003-01-24 02:44:45 +00006455 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006456
6457we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006458at the start of daylight time. Picture US Eastern for concreteness. The wall
6459time 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 +00006460sense then. The docs ask that an Eastern tzinfo class consider such a time to
6461be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6462on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006463the only spelling that makes sense on the local wall clock.
6464
Tim Petersc5dc4da2003-01-02 17:55:03 +00006465In fact, if [5] holds at this point, we do have the standard-time spelling,
6466but that takes a bit of proof. We first prove a stronger result. What's the
6467difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006468
Tim Peters8bb5ad22003-01-24 02:44:45 +00006469 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006470
Tim Petersc5dc4da2003-01-02 17:55:03 +00006471Now
6472 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006473 (y + y.s).n = by #5
6474 y.n + y.s = since y.n = x.n
6475 x.n + y.s = since z and y are have the same tzinfo member,
6476 y.s = z.s by #2
6477 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006478
Tim Petersc5dc4da2003-01-02 17:55:03 +00006479Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006480
Tim Petersc5dc4da2003-01-02 17:55:03 +00006481 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006482 x.n - ((x.n + z.s) - z.o) = expanding
6483 x.n - x.n - z.s + z.o = cancelling
6484 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006485 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006486
Tim Petersc5dc4da2003-01-02 17:55:03 +00006487So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006488
Tim Petersc5dc4da2003-01-02 17:55:03 +00006489If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006490spelling we wanted in the endcase described above. We're done. Contrarily,
6491if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006492
Tim Petersc5dc4da2003-01-02 17:55:03 +00006493If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6494add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006495local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006496
Tim Petersc5dc4da2003-01-02 17:55:03 +00006497Let
Tim Petersf3615152003-01-01 21:51:37 +00006498
Tim Peters4fede1a2003-01-04 00:26:59 +00006499 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006500
Tim Peters4fede1a2003-01-04 00:26:59 +00006501and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006502
Tim Peters8bb5ad22003-01-24 02:44:45 +00006503 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006504
Tim Peters8bb5ad22003-01-24 02:44:45 +00006505If so, we're done. If not, the tzinfo class is insane, according to the
6506assumptions we've made. This also requires a bit of proof. As before, let's
6507compute the difference between the LHS and RHS of [8] (and skipping some of
6508the justifications for the kinds of substitutions we've done several times
6509already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006510
Tim Peters8bb5ad22003-01-24 02:44:45 +00006511 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006512 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6513 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6514 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6515 - z.n + z.n - z.o + z'.o = cancel z.n
6516 - z.o + z'.o = #1 twice
6517 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6518 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006519
6520So 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 +00006521we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6522return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006523
Tim Peters8bb5ad22003-01-24 02:44:45 +00006524How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6525a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6526would have to change the result dst() returns: we start in DST, and moving
6527a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006528
Tim Peters8bb5ad22003-01-24 02:44:45 +00006529There isn't a sane case where this can happen. The closest it gets is at
6530the end of DST, where there's an hour in UTC with no spelling in a hybrid
6531tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6532that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6533UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6534time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6535clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6536standard time. Since that's what the local clock *does*, we want to map both
6537UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006538in local time, but so it goes -- it's the way the local clock works.
6539
Tim Peters8bb5ad22003-01-24 02:44:45 +00006540When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6541so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6542z' = 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 +00006543(correctly) concludes that z' is not UTC-equivalent to x.
6544
6545Because we know z.d said z was in daylight time (else [5] would have held and
6546we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006547and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006548return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6549but the reasoning doesn't depend on the example -- it depends on there being
6550two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006551z' must be in standard time, and is the spelling we want in this case.
6552
6553Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6554concerned (because it takes z' as being in standard time rather than the
6555daylight time we intend here), but returning it gives the real-life "local
6556clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6557tz.
6558
6559When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6560the 1:MM standard time spelling we want.
6561
6562So how can this break? One of the assumptions must be violated. Two
6563possibilities:
6564
65651) [2] effectively says that y.s is invariant across all y belong to a given
6566 time zone. This isn't true if, for political reasons or continental drift,
6567 a region decides to change its base offset from UTC.
6568
65692) There may be versions of "double daylight" time where the tail end of
6570 the analysis gives up a step too early. I haven't thought about that
6571 enough to say.
6572
6573In any case, it's clear that the default fromutc() is strong enough to handle
6574"almost all" time zones: so long as the standard offset is invariant, it
6575doesn't matter if daylight time transition points change from year to year, or
6576if daylight time is skipped in some years; it doesn't matter how large or
6577small dst() may get within its bounds; and it doesn't even matter if some
6578perverse time zone returns a negative dst()). So a breaking case must be
6579pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006580--------------------------------------------------------------------------- */