blob: 5afeeea4881ddbcabc8a8dc742ea6ee0ae3c7a02 [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 *
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02002778date_from_pickle(PyTypeObject *type, PyObject *state)
2779{
2780 PyDateTime_Date *me;
2781
2782 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2783 if (me != NULL) {
2784 const char *pdata = PyBytes_AS_STRING(state);
2785 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2786 me->hashcode = -1;
2787 }
2788 return (PyObject *)me;
2789}
2790
2791static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002792date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002794 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002795 int year;
2796 int month;
2797 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002799 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02002800 if (PyTuple_GET_SIZE(args) == 1) {
2801 PyObject *state = PyTuple_GET_ITEM(args, 0);
2802 if (PyBytes_Check(state)) {
2803 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2804 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2805 {
2806 return date_from_pickle(type, state);
2807 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002808 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02002809 else if (PyUnicode_Check(state)) {
2810 if (PyUnicode_READY(state)) {
2811 return NULL;
2812 }
2813 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
2814 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
2815 {
2816 state = PyUnicode_AsLatin1String(state);
2817 if (state == NULL) {
2818 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
2819 /* More informative error message. */
2820 PyErr_SetString(PyExc_ValueError,
2821 "Failed to encode latin1 string when unpickling "
2822 "a date object. "
2823 "pickle.load(data, encoding='latin1') is assumed.");
2824 }
2825 return NULL;
2826 }
2827 self = date_from_pickle(type, state);
2828 Py_DECREF(state);
2829 return self;
2830 }
2831 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002832 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002834 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2835 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 self = new_date_ex(year, month, day, type);
2837 }
2838 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002839}
2840
2841/* Return new date from localtime(t). */
2842static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002843date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002844{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002845 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002846 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002847
Victor Stinnere4a994d2015-03-30 01:10:14 +02002848 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002850
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002851 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002852 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002853
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002854 return new_date_subclass_ex(tm.tm_year + 1900,
2855 tm.tm_mon + 1,
2856 tm.tm_mday,
2857 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002858}
2859
2860/* Return new date from current time.
2861 * We say this is equivalent to fromtimestamp(time.time()), and the
2862 * only way to be sure of that is to *call* time.time(). That's not
2863 * generally the same as calling C's time.
2864 */
2865static PyObject *
2866date_today(PyObject *cls, PyObject *dummy)
2867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 PyObject *time;
2869 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002870 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002872 time = time_time();
2873 if (time == NULL)
2874 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002876 /* Note well: today() is a class method, so this may not call
2877 * date.fromtimestamp. For example, it may call
2878 * datetime.fromtimestamp. That's why we need all the accuracy
2879 * time.time() delivers; if someone were gonzo about optimization,
2880 * date.today() could get away with plain C time().
2881 */
Victor Stinner20401de2016-12-09 15:24:31 +01002882 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2883 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 Py_DECREF(time);
2885 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002886}
2887
2888/* Return new date from given timestamp (Python timestamp -- a double). */
2889static PyObject *
2890date_fromtimestamp(PyObject *cls, PyObject *args)
2891{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002892 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002894
Victor Stinner5d272cc2012-03-13 13:35:55 +01002895 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2896 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002897 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002898}
2899
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002900
Tim Peters2a799bf2002-12-16 20:18:38 +00002901/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2902 * the ordinal is out of range.
2903 */
2904static PyObject *
2905date_fromordinal(PyObject *cls, PyObject *args)
2906{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002907 PyObject *result = NULL;
2908 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002910 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2911 int year;
2912 int month;
2913 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002915 if (ordinal < 1)
2916 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2917 ">= 1");
2918 else {
2919 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002920 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002921 }
2922 }
2923 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002924}
2925
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002926/* Return the new date from a string as generated by date.isoformat() */
2927static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002928date_fromisoformat(PyObject *cls, PyObject *dtstr)
2929{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002930 assert(dtstr != NULL);
2931
2932 if (!PyUnicode_Check(dtstr)) {
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002933 PyErr_SetString(PyExc_TypeError,
2934 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002935 return NULL;
2936 }
2937
2938 Py_ssize_t len;
2939
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002940 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002941 if (dt_ptr == NULL) {
2942 goto invalid_string_error;
2943 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002944
2945 int year = 0, month = 0, day = 0;
2946
2947 int rv;
2948 if (len == 10) {
2949 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002950 }
2951 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002952 rv = -1;
2953 }
2954
2955 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002956 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002957 }
2958
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002959 return new_date_subclass_ex(year, month, day, cls);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002960
2961invalid_string_error:
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002962 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002963 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002964}
2965
Tim Peters2a799bf2002-12-16 20:18:38 +00002966/*
2967 * Date arithmetic.
2968 */
2969
2970/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2971 * instead.
2972 */
2973static PyObject *
2974add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002976 PyObject *result = NULL;
2977 int year = GET_YEAR(date);
2978 int month = GET_MONTH(date);
2979 int deltadays = GET_TD_DAYS(delta);
2980 /* C-level overflow is impossible because |deltadays| < 1e9. */
2981 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002983 if (normalize_date(&year, &month, &day) >= 0)
2984 result = new_date(year, month, day);
2985 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002986}
2987
2988static PyObject *
2989date_add(PyObject *left, PyObject *right)
2990{
Brian Curtindfc80e32011-08-10 20:28:54 -05002991 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2992 Py_RETURN_NOTIMPLEMENTED;
2993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002994 if (PyDate_Check(left)) {
2995 /* date + ??? */
2996 if (PyDelta_Check(right))
2997 /* date + delta */
2998 return add_date_timedelta((PyDateTime_Date *) left,
2999 (PyDateTime_Delta *) right,
3000 0);
3001 }
3002 else {
3003 /* ??? + date
3004 * 'right' must be one of us, or we wouldn't have been called
3005 */
3006 if (PyDelta_Check(left))
3007 /* delta + date */
3008 return add_date_timedelta((PyDateTime_Date *) right,
3009 (PyDateTime_Delta *) left,
3010 0);
3011 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003012 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003013}
3014
3015static PyObject *
3016date_subtract(PyObject *left, PyObject *right)
3017{
Brian Curtindfc80e32011-08-10 20:28:54 -05003018 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3019 Py_RETURN_NOTIMPLEMENTED;
3020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003021 if (PyDate_Check(left)) {
3022 if (PyDate_Check(right)) {
3023 /* date - date */
3024 int left_ord = ymd_to_ord(GET_YEAR(left),
3025 GET_MONTH(left),
3026 GET_DAY(left));
3027 int right_ord = ymd_to_ord(GET_YEAR(right),
3028 GET_MONTH(right),
3029 GET_DAY(right));
3030 return new_delta(left_ord - right_ord, 0, 0, 0);
3031 }
3032 if (PyDelta_Check(right)) {
3033 /* date - delta */
3034 return add_date_timedelta((PyDateTime_Date *) left,
3035 (PyDateTime_Delta *) right,
3036 1);
3037 }
3038 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003039 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003040}
3041
3042
3043/* Various ways to turn a date into a string. */
3044
3045static PyObject *
3046date_repr(PyDateTime_Date *self)
3047{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003048 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3049 Py_TYPE(self)->tp_name,
3050 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003051}
3052
3053static PyObject *
3054date_isoformat(PyDateTime_Date *self)
3055{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003056 return PyUnicode_FromFormat("%04d-%02d-%02d",
3057 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003058}
3059
Tim Peterse2df5ff2003-05-02 18:39:55 +00003060/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003061static PyObject *
3062date_str(PyDateTime_Date *self)
3063{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003064 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003065}
3066
3067
3068static PyObject *
3069date_ctime(PyDateTime_Date *self)
3070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003071 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003072}
3073
3074static PyObject *
3075date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003077 /* This method can be inherited, and needs to call the
3078 * timetuple() method appropriate to self's class.
3079 */
3080 PyObject *result;
3081 PyObject *tuple;
3082 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003083 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003084 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003086 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3087 &format))
3088 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003089
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003090 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003091 if (tuple == NULL)
3092 return NULL;
3093 result = wrap_strftime((PyObject *)self, format, tuple,
3094 (PyObject *)self);
3095 Py_DECREF(tuple);
3096 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003097}
3098
Eric Smith1ba31142007-09-11 18:06:02 +00003099static PyObject *
3100date_format(PyDateTime_Date *self, PyObject *args)
3101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003102 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003104 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3105 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003107 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003108 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003109 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003110
Victor Stinner20401de2016-12-09 15:24:31 +01003111 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3112 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003113}
3114
Tim Peters2a799bf2002-12-16 20:18:38 +00003115/* ISO methods. */
3116
3117static PyObject *
3118date_isoweekday(PyDateTime_Date *self)
3119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003120 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003123}
3124
3125static PyObject *
3126date_isocalendar(PyDateTime_Date *self)
3127{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 int year = GET_YEAR(self);
3129 int week1_monday = iso_week1_monday(year);
3130 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3131 int week;
3132 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003134 week = divmod(today - week1_monday, 7, &day);
3135 if (week < 0) {
3136 --year;
3137 week1_monday = iso_week1_monday(year);
3138 week = divmod(today - week1_monday, 7, &day);
3139 }
3140 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3141 ++year;
3142 week = 0;
3143 }
3144 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003145}
3146
3147/* Miscellaneous methods. */
3148
Tim Peters2a799bf2002-12-16 20:18:38 +00003149static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003150date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003152 if (PyDate_Check(other)) {
3153 int diff = memcmp(((PyDateTime_Date *)self)->data,
3154 ((PyDateTime_Date *)other)->data,
3155 _PyDateTime_DATE_DATASIZE);
3156 return diff_to_bool(diff, op);
3157 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003158 else
3159 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003160}
3161
3162static PyObject *
3163date_timetuple(PyDateTime_Date *self)
3164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003165 return build_struct_time(GET_YEAR(self),
3166 GET_MONTH(self),
3167 GET_DAY(self),
3168 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003169}
3170
Tim Peters12bf3392002-12-24 05:41:27 +00003171static PyObject *
3172date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003174 PyObject *clone;
3175 PyObject *tuple;
3176 int year = GET_YEAR(self);
3177 int month = GET_MONTH(self);
3178 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003180 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3181 &year, &month, &day))
3182 return NULL;
3183 tuple = Py_BuildValue("iii", year, month, day);
3184 if (tuple == NULL)
3185 return NULL;
3186 clone = date_new(Py_TYPE(self), tuple, NULL);
3187 Py_DECREF(tuple);
3188 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003189}
3190
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003191static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003192generic_hash(unsigned char *data, int len)
3193{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003194 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003195}
3196
3197
3198static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003199
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003200static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003201date_hash(PyDateTime_Date *self)
3202{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003203 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003204 self->hashcode = generic_hash(
3205 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003206 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003209}
3210
3211static PyObject *
3212date_toordinal(PyDateTime_Date *self)
3213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003214 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3215 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003216}
3217
3218static PyObject *
3219date_weekday(PyDateTime_Date *self)
3220{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003221 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003223 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003224}
3225
Tim Peters371935f2003-02-01 01:52:50 +00003226/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003227
Tim Petersb57f8f02003-02-01 02:54:15 +00003228/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003229static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003230date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003232 PyObject* field;
3233 field = PyBytes_FromStringAndSize((char*)self->data,
3234 _PyDateTime_DATE_DATASIZE);
3235 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003236}
3237
3238static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003239date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003241 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003242}
3243
3244static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003246 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00003247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003248 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
3249 METH_CLASS,
3250 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
3251 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003253 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3254 METH_CLASS,
3255 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3256 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003257
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003258 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3259 METH_CLASS,
3260 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003262 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3263 PyDoc_STR("Current date or datetime: same as "
3264 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003266 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003268 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3269 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003271 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
3272 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003274 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3275 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003277 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3278 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003280 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3281 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3282 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003284 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3285 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003287 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3288 PyDoc_STR("Return the day of the week represented by the date.\n"
3289 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003291 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3292 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3293 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003295 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3296 PyDoc_STR("Return the day of the week represented by the date.\n"
3297 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003299 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3300 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003302 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3303 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003305 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003306};
3307
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003308static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003309PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003310
3311static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003312 date_add, /* nb_add */
3313 date_subtract, /* nb_subtract */
3314 0, /* nb_multiply */
3315 0, /* nb_remainder */
3316 0, /* nb_divmod */
3317 0, /* nb_power */
3318 0, /* nb_negative */
3319 0, /* nb_positive */
3320 0, /* nb_absolute */
3321 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003322};
3323
3324static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003325 PyVarObject_HEAD_INIT(NULL, 0)
3326 "datetime.date", /* tp_name */
3327 sizeof(PyDateTime_Date), /* tp_basicsize */
3328 0, /* tp_itemsize */
3329 0, /* tp_dealloc */
3330 0, /* tp_print */
3331 0, /* tp_getattr */
3332 0, /* tp_setattr */
3333 0, /* tp_reserved */
3334 (reprfunc)date_repr, /* tp_repr */
3335 &date_as_number, /* tp_as_number */
3336 0, /* tp_as_sequence */
3337 0, /* tp_as_mapping */
3338 (hashfunc)date_hash, /* tp_hash */
3339 0, /* tp_call */
3340 (reprfunc)date_str, /* tp_str */
3341 PyObject_GenericGetAttr, /* tp_getattro */
3342 0, /* tp_setattro */
3343 0, /* tp_as_buffer */
3344 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3345 date_doc, /* tp_doc */
3346 0, /* tp_traverse */
3347 0, /* tp_clear */
3348 date_richcompare, /* tp_richcompare */
3349 0, /* tp_weaklistoffset */
3350 0, /* tp_iter */
3351 0, /* tp_iternext */
3352 date_methods, /* tp_methods */
3353 0, /* tp_members */
3354 date_getset, /* tp_getset */
3355 0, /* tp_base */
3356 0, /* tp_dict */
3357 0, /* tp_descr_get */
3358 0, /* tp_descr_set */
3359 0, /* tp_dictoffset */
3360 0, /* tp_init */
3361 0, /* tp_alloc */
3362 date_new, /* tp_new */
3363 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003364};
3365
3366/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003367 * PyDateTime_TZInfo implementation.
3368 */
3369
3370/* This is a pure abstract base class, so doesn't do anything beyond
3371 * raising NotImplemented exceptions. Real tzinfo classes need
3372 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003373 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003374 * be subclasses of this tzinfo class, which is easy and quick to check).
3375 *
3376 * Note: For reasons having to do with pickling of subclasses, we have
3377 * to allow tzinfo objects to be instantiated. This wasn't an issue
3378 * in the Python implementation (__init__() could raise NotImplementedError
3379 * there without ill effect), but doing so in the C implementation hit a
3380 * brick wall.
3381 */
3382
3383static PyObject *
3384tzinfo_nogo(const char* methodname)
3385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003386 PyErr_Format(PyExc_NotImplementedError,
3387 "a tzinfo subclass must implement %s()",
3388 methodname);
3389 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003390}
3391
3392/* Methods. A subclass must implement these. */
3393
Tim Peters52dcce22003-01-23 16:36:11 +00003394static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003395tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003397 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003398}
3399
Tim Peters52dcce22003-01-23 16:36:11 +00003400static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003401tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003403 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003404}
3405
Tim Peters52dcce22003-01-23 16:36:11 +00003406static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003407tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003409 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003410}
3411
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003412
3413static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3414 PyDateTime_Delta *delta,
3415 int factor);
3416static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3417static PyObject *datetime_dst(PyObject *self, PyObject *);
3418
Tim Peters52dcce22003-01-23 16:36:11 +00003419static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003420tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003421{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003422 PyObject *result = NULL;
3423 PyObject *off = NULL, *dst = NULL;
3424 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003425
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003426 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003427 PyErr_SetString(PyExc_TypeError,
3428 "fromutc: argument must be a datetime");
3429 return NULL;
3430 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003431 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003432 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3433 "is not self");
3434 return NULL;
3435 }
Tim Peters52dcce22003-01-23 16:36:11 +00003436
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003437 off = datetime_utcoffset(dt, NULL);
3438 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003439 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003440 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003441 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3442 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003443 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003444 }
Tim Peters52dcce22003-01-23 16:36:11 +00003445
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003446 dst = datetime_dst(dt, NULL);
3447 if (dst == NULL)
3448 goto Fail;
3449 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003450 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3451 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003452 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003453 }
Tim Peters52dcce22003-01-23 16:36:11 +00003454
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003455 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3456 if (delta == NULL)
3457 goto Fail;
3458 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003459 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003460 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003461
3462 Py_DECREF(dst);
3463 dst = call_dst(GET_DT_TZINFO(dt), result);
3464 if (dst == NULL)
3465 goto Fail;
3466 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003467 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003468 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003469 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003470 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003471 if (result == NULL)
3472 goto Fail;
3473 }
3474 Py_DECREF(delta);
3475 Py_DECREF(dst);
3476 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003477 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003478
3479Inconsistent:
Miss Islington (bot)7beb8c52018-11-05 06:52:58 -08003480 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003481 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003482
Miss Islington (bot)e86db342018-02-03 17:41:43 -08003483 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003484Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003485 Py_XDECREF(off);
3486 Py_XDECREF(dst);
3487 Py_XDECREF(delta);
3488 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003490}
3491
Tim Peters2a799bf2002-12-16 20:18:38 +00003492/*
3493 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003494 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003495 */
3496
Guido van Rossum177e41a2003-01-30 22:06:23 +00003497static PyObject *
3498tzinfo_reduce(PyObject *self)
3499{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003500 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003501 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003502 _Py_IDENTIFIER(__getinitargs__);
3503 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003504
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003505 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003506 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003507 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 Py_DECREF(getinitargs);
3509 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003510 return NULL;
3511 }
3512 }
3513 else {
3514 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003515
3516 args = PyTuple_New(0);
3517 if (args == NULL) {
3518 return NULL;
3519 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003520 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003521
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003522 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003523 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003524 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003525 Py_DECREF(getstate);
3526 if (state == NULL) {
3527 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003528 return NULL;
3529 }
3530 }
3531 else {
3532 PyObject **dictptr;
3533 PyErr_Clear();
3534 state = Py_None;
3535 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003536 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003537 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003538 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003539 Py_INCREF(state);
3540 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003542 if (state == Py_None) {
3543 Py_DECREF(state);
3544 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3545 }
3546 else
3547 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003548}
Tim Peters2a799bf2002-12-16 20:18:38 +00003549
3550static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003552 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3553 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003556 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3557 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003559 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003560 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003562 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003563 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003565 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3566 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003569};
3570
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003571static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003572PyDoc_STR("Abstract base class for time zone info objects.");
3573
Neal Norwitz227b5332006-03-22 09:28:35 +00003574static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003575 PyVarObject_HEAD_INIT(NULL, 0)
3576 "datetime.tzinfo", /* tp_name */
3577 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3578 0, /* tp_itemsize */
3579 0, /* tp_dealloc */
3580 0, /* tp_print */
3581 0, /* tp_getattr */
3582 0, /* tp_setattr */
3583 0, /* tp_reserved */
3584 0, /* tp_repr */
3585 0, /* tp_as_number */
3586 0, /* tp_as_sequence */
3587 0, /* tp_as_mapping */
3588 0, /* tp_hash */
3589 0, /* tp_call */
3590 0, /* tp_str */
3591 PyObject_GenericGetAttr, /* tp_getattro */
3592 0, /* tp_setattro */
3593 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003594 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003595 tzinfo_doc, /* tp_doc */
3596 0, /* tp_traverse */
3597 0, /* tp_clear */
3598 0, /* tp_richcompare */
3599 0, /* tp_weaklistoffset */
3600 0, /* tp_iter */
3601 0, /* tp_iternext */
3602 tzinfo_methods, /* tp_methods */
3603 0, /* tp_members */
3604 0, /* tp_getset */
3605 0, /* tp_base */
3606 0, /* tp_dict */
3607 0, /* tp_descr_get */
3608 0, /* tp_descr_set */
3609 0, /* tp_dictoffset */
3610 0, /* tp_init */
3611 0, /* tp_alloc */
3612 PyType_GenericNew, /* tp_new */
3613 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003614};
3615
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003616static char *timezone_kws[] = {"offset", "name", NULL};
3617
3618static PyObject *
3619timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3620{
3621 PyObject *offset;
3622 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003623 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3624 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003625 return new_timezone(offset, name);
3626
3627 return NULL;
3628}
3629
3630static void
3631timezone_dealloc(PyDateTime_TimeZone *self)
3632{
3633 Py_CLEAR(self->offset);
3634 Py_CLEAR(self->name);
3635 Py_TYPE(self)->tp_free((PyObject *)self);
3636}
3637
3638static PyObject *
3639timezone_richcompare(PyDateTime_TimeZone *self,
3640 PyDateTime_TimeZone *other, int op)
3641{
Brian Curtindfc80e32011-08-10 20:28:54 -05003642 if (op != Py_EQ && op != Py_NE)
3643 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003644 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003645 if (op == Py_EQ)
3646 Py_RETURN_FALSE;
3647 else
3648 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003649 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003650 return delta_richcompare(self->offset, other->offset, op);
3651}
3652
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003653static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003654timezone_hash(PyDateTime_TimeZone *self)
3655{
3656 return delta_hash((PyDateTime_Delta *)self->offset);
3657}
3658
3659/* Check argument type passed to tzname, utcoffset, or dst methods.
3660 Returns 0 for good argument. Returns -1 and sets exception info
3661 otherwise.
3662 */
3663static int
3664_timezone_check_argument(PyObject *dt, const char *meth)
3665{
3666 if (dt == Py_None || PyDateTime_Check(dt))
3667 return 0;
3668 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3669 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3670 return -1;
3671}
3672
3673static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003674timezone_repr(PyDateTime_TimeZone *self)
3675{
3676 /* Note that although timezone is not subclassable, it is convenient
3677 to use Py_TYPE(self)->tp_name here. */
3678 const char *type_name = Py_TYPE(self)->tp_name;
3679
3680 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3681 return PyUnicode_FromFormat("%s.utc", type_name);
3682
3683 if (self->name == NULL)
3684 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3685
3686 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3687 self->name);
3688}
3689
3690
3691static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003692timezone_str(PyDateTime_TimeZone *self)
3693{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003694 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003695 PyObject *offset;
3696 char sign;
3697
3698 if (self->name != NULL) {
3699 Py_INCREF(self->name);
3700 return self->name;
3701 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003702 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003703 (GET_TD_DAYS(self->offset) == 0 &&
3704 GET_TD_SECONDS(self->offset) == 0 &&
3705 GET_TD_MICROSECONDS(self->offset) == 0))
3706 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003707 /* Offset is normalized, so it is negative if days < 0 */
3708 if (GET_TD_DAYS(self->offset) < 0) {
3709 sign = '-';
3710 offset = delta_negative((PyDateTime_Delta *)self->offset);
3711 if (offset == NULL)
3712 return NULL;
3713 }
3714 else {
3715 sign = '+';
3716 offset = self->offset;
3717 Py_INCREF(offset);
3718 }
3719 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003720 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003721 seconds = GET_TD_SECONDS(offset);
3722 Py_DECREF(offset);
3723 minutes = divmod(seconds, 60, &seconds);
3724 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003725 if (microseconds != 0) {
3726 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3727 sign, hours, minutes,
3728 seconds, microseconds);
3729 }
3730 if (seconds != 0) {
3731 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3732 sign, hours, minutes, seconds);
3733 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003734 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003735}
3736
3737static PyObject *
3738timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3739{
3740 if (_timezone_check_argument(dt, "tzname") == -1)
3741 return NULL;
3742
3743 return timezone_str(self);
3744}
3745
3746static PyObject *
3747timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3748{
3749 if (_timezone_check_argument(dt, "utcoffset") == -1)
3750 return NULL;
3751
3752 Py_INCREF(self->offset);
3753 return self->offset;
3754}
3755
3756static PyObject *
3757timezone_dst(PyObject *self, PyObject *dt)
3758{
3759 if (_timezone_check_argument(dt, "dst") == -1)
3760 return NULL;
3761
3762 Py_RETURN_NONE;
3763}
3764
3765static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003766timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3767{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003768 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003769 PyErr_SetString(PyExc_TypeError,
3770 "fromutc: argument must be a datetime");
3771 return NULL;
3772 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003773 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003774 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3775 "is not self");
3776 return NULL;
3777 }
3778
3779 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3780}
3781
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003782static PyObject *
3783timezone_getinitargs(PyDateTime_TimeZone *self)
3784{
3785 if (self->name == NULL)
3786 return Py_BuildValue("(O)", self->offset);
3787 return Py_BuildValue("(OO)", self->offset, self->name);
3788}
3789
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003790static PyMethodDef timezone_methods[] = {
3791 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3792 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003793 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003794
3795 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003796 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003797
3798 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003799 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003800
3801 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3802 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3803
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003804 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3805 PyDoc_STR("pickle support")},
3806
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003807 {NULL, NULL}
3808};
3809
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003810static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003811PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3812
3813static PyTypeObject PyDateTime_TimeZoneType = {
3814 PyVarObject_HEAD_INIT(NULL, 0)
3815 "datetime.timezone", /* tp_name */
3816 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3817 0, /* tp_itemsize */
3818 (destructor)timezone_dealloc, /* tp_dealloc */
3819 0, /* tp_print */
3820 0, /* tp_getattr */
3821 0, /* tp_setattr */
3822 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003823 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003824 0, /* tp_as_number */
3825 0, /* tp_as_sequence */
3826 0, /* tp_as_mapping */
3827 (hashfunc)timezone_hash, /* tp_hash */
3828 0, /* tp_call */
3829 (reprfunc)timezone_str, /* tp_str */
3830 0, /* tp_getattro */
3831 0, /* tp_setattro */
3832 0, /* tp_as_buffer */
3833 Py_TPFLAGS_DEFAULT, /* tp_flags */
3834 timezone_doc, /* tp_doc */
3835 0, /* tp_traverse */
3836 0, /* tp_clear */
3837 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3838 0, /* tp_weaklistoffset */
3839 0, /* tp_iter */
3840 0, /* tp_iternext */
3841 timezone_methods, /* tp_methods */
3842 0, /* tp_members */
3843 0, /* tp_getset */
3844 &PyDateTime_TZInfoType, /* tp_base */
3845 0, /* tp_dict */
3846 0, /* tp_descr_get */
3847 0, /* tp_descr_set */
3848 0, /* tp_dictoffset */
3849 0, /* tp_init */
3850 0, /* tp_alloc */
3851 timezone_new, /* tp_new */
3852};
3853
Tim Peters2a799bf2002-12-16 20:18:38 +00003854/*
Tim Peters37f39822003-01-10 03:49:02 +00003855 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003856 */
3857
Tim Peters37f39822003-01-10 03:49:02 +00003858/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003859 */
3860
3861static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003862time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003864 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003865}
3866
Tim Peters37f39822003-01-10 03:49:02 +00003867static PyObject *
3868time_minute(PyDateTime_Time *self, void *unused)
3869{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003870 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003871}
3872
3873/* The name time_second conflicted with some platform header file. */
3874static PyObject *
3875py_time_second(PyDateTime_Time *self, void *unused)
3876{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003877 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003878}
3879
3880static PyObject *
3881time_microsecond(PyDateTime_Time *self, void *unused)
3882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003884}
3885
3886static PyObject *
3887time_tzinfo(PyDateTime_Time *self, void *unused)
3888{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003889 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3890 Py_INCREF(result);
3891 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003892}
3893
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003894static PyObject *
3895time_fold(PyDateTime_Time *self, void *unused)
3896{
3897 return PyLong_FromLong(TIME_GET_FOLD(self));
3898}
3899
Tim Peters37f39822003-01-10 03:49:02 +00003900static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003901 {"hour", (getter)time_hour},
3902 {"minute", (getter)time_minute},
3903 {"second", (getter)py_time_second},
3904 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003905 {"tzinfo", (getter)time_tzinfo},
3906 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003907 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003908};
3909
3910/*
3911 * Constructors.
3912 */
3913
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003914static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003915 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003916
Tim Peters2a799bf2002-12-16 20:18:38 +00003917static PyObject *
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02003918time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
3919{
3920 PyDateTime_Time *me;
3921 char aware = (char)(tzinfo != Py_None);
3922
3923 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
3924 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
3925 return NULL;
3926 }
3927
3928 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3929 if (me != NULL) {
3930 const char *pdata = PyBytes_AS_STRING(state);
3931
3932 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3933 me->hashcode = -1;
3934 me->hastzinfo = aware;
3935 if (aware) {
3936 Py_INCREF(tzinfo);
3937 me->tzinfo = tzinfo;
3938 }
3939 if (pdata[0] & (1 << 7)) {
3940 me->data[0] -= 128;
3941 me->fold = 1;
3942 }
3943 else {
3944 me->fold = 0;
3945 }
3946 }
3947 return (PyObject *)me;
3948}
3949
3950static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003951time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003953 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003954 int hour = 0;
3955 int minute = 0;
3956 int second = 0;
3957 int usecond = 0;
3958 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003959 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003961 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02003962 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
3963 PyObject *state = PyTuple_GET_ITEM(args, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003964 if (PyTuple_GET_SIZE(args) == 2) {
3965 tzinfo = PyTuple_GET_ITEM(args, 1);
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02003966 }
3967 if (PyBytes_Check(state)) {
3968 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3969 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
3970 {
3971 return time_from_pickle(type, state, tzinfo);
3972 }
3973 }
3974 else if (PyUnicode_Check(state)) {
3975 if (PyUnicode_READY(state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003976 return NULL;
3977 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02003978 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
3979 (0x7F & PyUnicode_READ_CHAR(state, 2)) < 24)
3980 {
3981 state = PyUnicode_AsLatin1String(state);
3982 if (state == NULL) {
3983 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
3984 /* More informative error message. */
3985 PyErr_SetString(PyExc_ValueError,
3986 "Failed to encode latin1 string when unpickling "
3987 "a time object. "
3988 "pickle.load(data, encoding='latin1') is assumed.");
3989 }
3990 return NULL;
3991 }
3992 self = time_from_pickle(type, state, tzinfo);
3993 Py_DECREF(state);
3994 return self;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003995 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003996 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02003997 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003998 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003999
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004000 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004002 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004003 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4004 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004005 }
4006 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004007}
4008
4009/*
4010 * Destructor.
4011 */
4012
4013static void
Tim Peters37f39822003-01-10 03:49:02 +00004014time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004015{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004016 if (HASTZINFO(self)) {
4017 Py_XDECREF(self->tzinfo);
4018 }
4019 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004020}
4021
4022/*
Tim Peters855fe882002-12-22 03:43:39 +00004023 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004024 */
4025
Tim Peters2a799bf2002-12-16 20:18:38 +00004026/* These are all METH_NOARGS, so don't need to check the arglist. */
4027static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004028time_utcoffset(PyObject *self, PyObject *unused) {
4029 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004030}
4031
4032static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004033time_dst(PyObject *self, PyObject *unused) {
4034 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004035}
4036
4037static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004038time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004039 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004040}
4041
4042/*
Tim Peters37f39822003-01-10 03:49:02 +00004043 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004044 */
4045
4046static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004047time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004048{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004049 const char *type_name = Py_TYPE(self)->tp_name;
4050 int h = TIME_GET_HOUR(self);
4051 int m = TIME_GET_MINUTE(self);
4052 int s = TIME_GET_SECOND(self);
4053 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004054 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004055 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004057 if (us)
4058 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4059 type_name, h, m, s, us);
4060 else if (s)
4061 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4062 type_name, h, m, s);
4063 else
4064 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4065 if (result != NULL && HASTZINFO(self))
4066 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004067 if (result != NULL && fold)
4068 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004069 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004070}
4071
Tim Peters37f39822003-01-10 03:49:02 +00004072static PyObject *
4073time_str(PyDateTime_Time *self)
4074{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07004075 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00004076}
Tim Peters2a799bf2002-12-16 20:18:38 +00004077
4078static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004079time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004081 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004082 char *timespec = NULL;
4083 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004084 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004085 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004086 static char *specs[][2] = {
4087 {"hours", "%02d"},
4088 {"minutes", "%02d:%02d"},
4089 {"seconds", "%02d:%02d:%02d"},
4090 {"milliseconds", "%02d:%02d:%02d.%03d"},
4091 {"microseconds", "%02d:%02d:%02d.%06d"},
4092 };
4093 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004094
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004095 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4096 return NULL;
4097
4098 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4099 if (us == 0) {
4100 /* seconds */
4101 given_spec = 2;
4102 }
4103 else {
4104 /* microseconds */
4105 given_spec = 4;
4106 }
4107 }
4108 else {
4109 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4110 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4111 if (given_spec == 3) {
4112 /* milliseconds */
4113 us = us / 1000;
4114 }
4115 break;
4116 }
4117 }
4118 }
4119
4120 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4121 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4122 return NULL;
4123 }
4124 else {
4125 result = PyUnicode_FromFormat(specs[given_spec][1],
4126 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4127 TIME_GET_SECOND(self), us);
4128 }
Tim Peters37f39822003-01-10 03:49:02 +00004129
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004130 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004131 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004133 /* We need to append the UTC offset. */
4134 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4135 Py_None) < 0) {
4136 Py_DECREF(result);
4137 return NULL;
4138 }
4139 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4140 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004141}
4142
Tim Peters37f39822003-01-10 03:49:02 +00004143static PyObject *
4144time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004146 PyObject *result;
4147 PyObject *tuple;
4148 PyObject *format;
4149 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004151 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4152 &format))
4153 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004155 /* Python's strftime does insane things with the year part of the
4156 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004157 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004158 */
4159 tuple = Py_BuildValue("iiiiiiiii",
4160 1900, 1, 1, /* year, month, day */
4161 TIME_GET_HOUR(self),
4162 TIME_GET_MINUTE(self),
4163 TIME_GET_SECOND(self),
4164 0, 1, -1); /* weekday, daynum, dst */
4165 if (tuple == NULL)
4166 return NULL;
4167 assert(PyTuple_Size(tuple) == 9);
4168 result = wrap_strftime((PyObject *)self, format, tuple,
4169 Py_None);
4170 Py_DECREF(tuple);
4171 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004172}
Tim Peters2a799bf2002-12-16 20:18:38 +00004173
4174/*
4175 * Miscellaneous methods.
4176 */
4177
Tim Peters37f39822003-01-10 03:49:02 +00004178static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004179time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004180{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004181 PyObject *result = NULL;
4182 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004184
Brian Curtindfc80e32011-08-10 20:28:54 -05004185 if (! PyTime_Check(other))
4186 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004187
4188 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004189 diff = memcmp(((PyDateTime_Time *)self)->data,
4190 ((PyDateTime_Time *)other)->data,
4191 _PyDateTime_TIME_DATASIZE);
4192 return diff_to_bool(diff, op);
4193 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004194 offset1 = time_utcoffset(self, NULL);
4195 if (offset1 == NULL)
4196 return NULL;
4197 offset2 = time_utcoffset(other, NULL);
4198 if (offset2 == NULL)
4199 goto done;
4200 /* If they're both naive, or both aware and have the same offsets,
4201 * we get off cheap. Note that if they're both naive, offset1 ==
4202 * offset2 == Py_None at this point.
4203 */
4204 if ((offset1 == offset2) ||
4205 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4206 delta_cmp(offset1, offset2) == 0)) {
4207 diff = memcmp(((PyDateTime_Time *)self)->data,
4208 ((PyDateTime_Time *)other)->data,
4209 _PyDateTime_TIME_DATASIZE);
4210 result = diff_to_bool(diff, op);
4211 }
4212 /* The hard case: both aware with different UTC offsets */
4213 else if (offset1 != Py_None && offset2 != Py_None) {
4214 int offsecs1, offsecs2;
4215 assert(offset1 != offset2); /* else last "if" handled it */
4216 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4217 TIME_GET_MINUTE(self) * 60 +
4218 TIME_GET_SECOND(self) -
4219 GET_TD_DAYS(offset1) * 86400 -
4220 GET_TD_SECONDS(offset1);
4221 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4222 TIME_GET_MINUTE(other) * 60 +
4223 TIME_GET_SECOND(other) -
4224 GET_TD_DAYS(offset2) * 86400 -
4225 GET_TD_SECONDS(offset2);
4226 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004227 if (diff == 0)
4228 diff = TIME_GET_MICROSECOND(self) -
4229 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004230 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004231 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004232 else if (op == Py_EQ) {
4233 result = Py_False;
4234 Py_INCREF(result);
4235 }
4236 else if (op == Py_NE) {
4237 result = Py_True;
4238 Py_INCREF(result);
4239 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004240 else {
4241 PyErr_SetString(PyExc_TypeError,
4242 "can't compare offset-naive and "
4243 "offset-aware times");
4244 }
4245 done:
4246 Py_DECREF(offset1);
4247 Py_XDECREF(offset2);
4248 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004249}
4250
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004251static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004252time_hash(PyDateTime_Time *self)
4253{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004254 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004255 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004256 if (TIME_GET_FOLD(self)) {
4257 self0 = new_time_ex2(TIME_GET_HOUR(self),
4258 TIME_GET_MINUTE(self),
4259 TIME_GET_SECOND(self),
4260 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004261 HASTZINFO(self) ? self->tzinfo : Py_None,
4262 0, Py_TYPE(self));
4263 if (self0 == NULL)
4264 return -1;
4265 }
4266 else {
4267 self0 = (PyObject *)self;
4268 Py_INCREF(self0);
4269 }
4270 offset = time_utcoffset(self0, NULL);
4271 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004272
4273 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004274 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004276 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004277 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004278 self->hashcode = generic_hash(
4279 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004280 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004281 PyObject *temp1, *temp2;
4282 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004283 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004284 seconds = TIME_GET_HOUR(self) * 3600 +
4285 TIME_GET_MINUTE(self) * 60 +
4286 TIME_GET_SECOND(self);
4287 microseconds = TIME_GET_MICROSECOND(self);
4288 temp1 = new_delta(0, seconds, microseconds, 1);
4289 if (temp1 == NULL) {
4290 Py_DECREF(offset);
4291 return -1;
4292 }
4293 temp2 = delta_subtract(temp1, offset);
4294 Py_DECREF(temp1);
4295 if (temp2 == NULL) {
4296 Py_DECREF(offset);
4297 return -1;
4298 }
4299 self->hashcode = PyObject_Hash(temp2);
4300 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004301 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004302 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 }
4304 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004305}
Tim Peters2a799bf2002-12-16 20:18:38 +00004306
Tim Peters12bf3392002-12-24 05:41:27 +00004307static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004308time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004310 PyObject *clone;
4311 PyObject *tuple;
4312 int hh = TIME_GET_HOUR(self);
4313 int mm = TIME_GET_MINUTE(self);
4314 int ss = TIME_GET_SECOND(self);
4315 int us = TIME_GET_MICROSECOND(self);
4316 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004317 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004318
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004319 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004320 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004321 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004322 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004323 if (fold != 0 && fold != 1) {
4324 PyErr_SetString(PyExc_ValueError,
4325 "fold must be either 0 or 1");
4326 return NULL;
4327 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004328 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4329 if (tuple == NULL)
4330 return NULL;
4331 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004332 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004333 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004334 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004335 Py_DECREF(tuple);
4336 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004337}
4338
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004339static PyObject *
4340time_fromisoformat(PyObject *cls, PyObject *tstr) {
4341 assert(tstr != NULL);
4342
4343 if (!PyUnicode_Check(tstr)) {
4344 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4345 return NULL;
4346 }
4347
4348 Py_ssize_t len;
4349 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4350
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004351 if (p == NULL) {
4352 goto invalid_string_error;
4353 }
4354
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004355 int hour = 0, minute = 0, second = 0, microsecond = 0;
4356 int tzoffset, tzimicrosecond = 0;
4357 int rv = parse_isoformat_time(p, len,
4358 &hour, &minute, &second, &microsecond,
4359 &tzoffset, &tzimicrosecond);
4360
4361 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004362 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004363 }
4364
4365 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4366 tzimicrosecond);
4367
4368 if (tzinfo == NULL) {
4369 return NULL;
4370 }
4371
4372 PyObject *t;
4373 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4374 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4375 } else {
4376 t = PyObject_CallFunction(cls, "iiiiO",
4377 hour, minute, second, microsecond, tzinfo);
4378 }
4379
4380 Py_DECREF(tzinfo);
4381 return t;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004382
4383invalid_string_error:
4384 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4385 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004386}
4387
4388
Tim Peters371935f2003-02-01 01:52:50 +00004389/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004390
Tim Peters33e0f382003-01-10 02:05:14 +00004391/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004392 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4393 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004394 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004395 */
4396static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004397time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004399 PyObject *basestate;
4400 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004402 basestate = PyBytes_FromStringAndSize((char *)self->data,
4403 _PyDateTime_TIME_DATASIZE);
4404 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004405 if (proto > 3 && TIME_GET_FOLD(self))
4406 /* Set the first bit of the first byte */
4407 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004408 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4409 result = PyTuple_Pack(1, basestate);
4410 else
4411 result = PyTuple_Pack(2, basestate, self->tzinfo);
4412 Py_DECREF(basestate);
4413 }
4414 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004415}
4416
4417static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004418time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004419{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004420 int proto;
4421 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004422 return NULL;
4423
4424 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004425}
4426
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004427static PyObject *
4428time_reduce(PyDateTime_Time *self, PyObject *arg)
4429{
4430 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4431}
4432
Tim Peters37f39822003-01-10 03:49:02 +00004433static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004434
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004435 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4436 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4437 "[+HH:MM].\n\n"
4438 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004440 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4441 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004443 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4444 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004446 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4447 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004449 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4450 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004452 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4453 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004455 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4456 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004457
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004458 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4459 PyDoc_STR("string -> time from time.isoformat() output")},
4460
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004461 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004462 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004463
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004464 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4465 PyDoc_STR("__reduce__() -> (cls, state)")},
4466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004467 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004468};
4469
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004470static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004471PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4472\n\
4473All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004474a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004475
Neal Norwitz227b5332006-03-22 09:28:35 +00004476static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004477 PyVarObject_HEAD_INIT(NULL, 0)
4478 "datetime.time", /* tp_name */
4479 sizeof(PyDateTime_Time), /* tp_basicsize */
4480 0, /* tp_itemsize */
4481 (destructor)time_dealloc, /* tp_dealloc */
4482 0, /* tp_print */
4483 0, /* tp_getattr */
4484 0, /* tp_setattr */
4485 0, /* tp_reserved */
4486 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004487 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004488 0, /* tp_as_sequence */
4489 0, /* tp_as_mapping */
4490 (hashfunc)time_hash, /* tp_hash */
4491 0, /* tp_call */
4492 (reprfunc)time_str, /* tp_str */
4493 PyObject_GenericGetAttr, /* tp_getattro */
4494 0, /* tp_setattro */
4495 0, /* tp_as_buffer */
4496 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4497 time_doc, /* tp_doc */
4498 0, /* tp_traverse */
4499 0, /* tp_clear */
4500 time_richcompare, /* tp_richcompare */
4501 0, /* tp_weaklistoffset */
4502 0, /* tp_iter */
4503 0, /* tp_iternext */
4504 time_methods, /* tp_methods */
4505 0, /* tp_members */
4506 time_getset, /* tp_getset */
4507 0, /* tp_base */
4508 0, /* tp_dict */
4509 0, /* tp_descr_get */
4510 0, /* tp_descr_set */
4511 0, /* tp_dictoffset */
4512 0, /* tp_init */
4513 time_alloc, /* tp_alloc */
4514 time_new, /* tp_new */
4515 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004516};
4517
4518/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004519 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004520 */
4521
Tim Petersa9bc1682003-01-11 03:39:11 +00004522/* Accessor properties. Properties for day, month, and year are inherited
4523 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004524 */
4525
4526static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004527datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004529 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004530}
4531
Tim Petersa9bc1682003-01-11 03:39:11 +00004532static PyObject *
4533datetime_minute(PyDateTime_DateTime *self, void *unused)
4534{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004535 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004536}
4537
4538static PyObject *
4539datetime_second(PyDateTime_DateTime *self, void *unused)
4540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004541 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004542}
4543
4544static PyObject *
4545datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004547 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004548}
4549
4550static PyObject *
4551datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4552{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004553 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4554 Py_INCREF(result);
4555 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004556}
4557
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004558static PyObject *
4559datetime_fold(PyDateTime_DateTime *self, void *unused)
4560{
4561 return PyLong_FromLong(DATE_GET_FOLD(self));
4562}
4563
Tim Petersa9bc1682003-01-11 03:39:11 +00004564static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004565 {"hour", (getter)datetime_hour},
4566 {"minute", (getter)datetime_minute},
4567 {"second", (getter)datetime_second},
4568 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004569 {"tzinfo", (getter)datetime_tzinfo},
4570 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004571 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004572};
4573
4574/*
4575 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004576 */
4577
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004578static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004579 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004580 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004581};
4582
Tim Peters2a799bf2002-12-16 20:18:38 +00004583static PyObject *
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004584datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4585{
4586 PyDateTime_DateTime *me;
4587 char aware = (char)(tzinfo != Py_None);
4588
4589 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4590 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4591 return NULL;
4592 }
4593
4594 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4595 if (me != NULL) {
4596 const char *pdata = PyBytes_AS_STRING(state);
4597
4598 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4599 me->hashcode = -1;
4600 me->hastzinfo = aware;
4601 if (aware) {
4602 Py_INCREF(tzinfo);
4603 me->tzinfo = tzinfo;
4604 }
4605 if (pdata[2] & (1 << 7)) {
4606 me->data[2] -= 128;
4607 me->fold = 1;
4608 }
4609 else {
4610 me->fold = 0;
4611 }
4612 }
4613 return (PyObject *)me;
4614}
4615
4616static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004617datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004619 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004620 int year;
4621 int month;
4622 int day;
4623 int hour = 0;
4624 int minute = 0;
4625 int second = 0;
4626 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004627 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004628 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004630 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004631 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4632 PyObject *state = PyTuple_GET_ITEM(args, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004633 if (PyTuple_GET_SIZE(args) == 2) {
4634 tzinfo = PyTuple_GET_ITEM(args, 1);
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004635 }
4636 if (PyBytes_Check(state)) {
4637 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4638 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4639 {
4640 return datetime_from_pickle(type, state, tzinfo);
4641 }
4642 }
4643 else if (PyUnicode_Check(state)) {
4644 if (PyUnicode_READY(state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004645 return NULL;
4646 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004647 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4648 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4649 {
4650 state = PyUnicode_AsLatin1String(state);
4651 if (state == NULL) {
4652 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4653 /* More informative error message. */
4654 PyErr_SetString(PyExc_ValueError,
4655 "Failed to encode latin1 string when unpickling "
4656 "a datetime object. "
4657 "pickle.load(data, encoding='latin1') is assumed.");
4658 }
4659 return NULL;
4660 }
4661 self = datetime_from_pickle(type, state, tzinfo);
4662 Py_DECREF(state);
4663 return self;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004664 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004665 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004666 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004667 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004668
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004669 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004670 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004671 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004672 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004673 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004674 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004675 }
4676 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004677}
4678
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004679/* TM_FUNC is the shared type of _PyTime_localtime() and
4680 * _PyTime_gmtime(). */
4681typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004682
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004683/* As of version 2015f max fold in IANA database is
4684 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004685static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004686/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004687static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004688
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004689static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004690utc_to_seconds(int year, int month, int day,
4691 int hour, int minute, int second)
4692{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004693 long long ordinal;
4694
4695 /* ymd_to_ord() doesn't support year <= 0 */
4696 if (year < MINYEAR || year > MAXYEAR) {
4697 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4698 return -1;
4699 }
4700
4701 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004702 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4703}
4704
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004705static long long
4706local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004707{
4708 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004709 time_t t;
4710 u -= epoch;
4711 t = u;
4712 if (t != u) {
4713 PyErr_SetString(PyExc_OverflowError,
4714 "timestamp out of range for platform time_t");
4715 return -1;
4716 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004717 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004718 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004719 return utc_to_seconds(local_time.tm_year + 1900,
4720 local_time.tm_mon + 1,
4721 local_time.tm_mday,
4722 local_time.tm_hour,
4723 local_time.tm_min,
4724 local_time.tm_sec);
4725}
4726
Tim Petersa9bc1682003-01-11 03:39:11 +00004727/* Internal helper.
4728 * Build datetime from a time_t and a distinct count of microseconds.
4729 * Pass localtime or gmtime for f, to control the interpretation of timet.
4730 */
4731static PyObject *
4732datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004733 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004734{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004735 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004736 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004737
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004738 if (f(timet, &tm) != 0)
4739 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004740
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004741 year = tm.tm_year + 1900;
4742 month = tm.tm_mon + 1;
4743 day = tm.tm_mday;
4744 hour = tm.tm_hour;
4745 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004746 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004747 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004748 * except to the extent that passing them on to the datetime
4749 * constructor would raise ValueError for a reason that
4750 * made no sense to the user.
4751 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004752 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004753
Victor Stinnerb67f0962017-02-10 10:34:02 +01004754 /* local timezone requires to compute fold */
Miss Islington (bot)97364932018-07-25 13:34:09 -07004755 if (tzinfo == Py_None && f == _PyTime_localtime
4756 /* On Windows, passing a negative value to local results
4757 * in an OSError because localtime_s on Windows does
4758 * not support negative timestamps. Unfortunately this
4759 * means that fold detection for time values between
4760 * 0 and max_fold_seconds will result in an identical
4761 * error since we subtract max_fold_seconds to detect a
4762 * fold. However, since we know there haven't been any
4763 * folds in the interval [0, max_fold_seconds) in any
4764 * timezone, we can hackily just forego fold detection
4765 * for this time range.
4766 */
4767#ifdef MS_WINDOWS
4768 && (timet - max_fold_seconds > 0)
4769#endif
4770 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004771 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004772
4773 result_seconds = utc_to_seconds(year, month, day,
4774 hour, minute, second);
4775 /* Probe max_fold_seconds to detect a fold. */
4776 probe_seconds = local(epoch + timet - max_fold_seconds);
4777 if (probe_seconds == -1)
4778 return NULL;
4779 transition = result_seconds - probe_seconds - max_fold_seconds;
4780 if (transition < 0) {
4781 probe_seconds = local(epoch + timet + transition);
4782 if (probe_seconds == -1)
4783 return NULL;
4784 if (probe_seconds == result_seconds)
4785 fold = 1;
4786 }
4787 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004788 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4789 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004790}
4791
4792/* Internal helper.
4793 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4794 * to control the interpretation of the timestamp. Since a double doesn't
4795 * have enough bits to cover a datetime's full range of precision, it's
4796 * better to call datetime_from_timet_and_us provided you have a way
4797 * to get that much precision (e.g., C time() isn't good enough).
4798 */
4799static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004800datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004801 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004803 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004804 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004805
Victor Stinnere4a994d2015-03-30 01:10:14 +02004806 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004807 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004808 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004809
Victor Stinner21f58932012-03-14 00:15:40 +01004810 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004811}
4812
4813/* Internal helper.
4814 * Build most accurate possible datetime for current time. Pass localtime or
4815 * gmtime for f as appropriate.
4816 */
4817static PyObject *
4818datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4819{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004820 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004821 time_t secs;
4822 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004823
Victor Stinner1e2b6882015-09-18 13:23:02 +02004824 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004825 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004826 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004827
Victor Stinner1e2b6882015-09-18 13:23:02 +02004828 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004829}
4830
Larry Hastings61272b72014-01-07 12:41:53 -08004831/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004832
4833@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004834datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004835
4836 tz: object = None
4837 Timezone object.
4838
4839Returns new datetime object representing current time local to tz.
4840
4841If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004842[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004843
Larry Hastings31826802013-10-19 00:09:25 -07004844static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004845datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004846/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004848 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004849
Larry Hastings31826802013-10-19 00:09:25 -07004850 /* Return best possible local time -- this isn't constrained by the
4851 * precision of a timestamp.
4852 */
4853 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004854 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004855
Larry Hastings5c661892014-01-24 06:17:25 -08004856 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004857 tz == Py_None ? _PyTime_localtime :
4858 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004859 tz);
4860 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004861 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004862 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004863 }
4864 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004865}
4866
Tim Petersa9bc1682003-01-11 03:39:11 +00004867/* Return best possible UTC time -- this isn't constrained by the
4868 * precision of a timestamp.
4869 */
4870static PyObject *
4871datetime_utcnow(PyObject *cls, PyObject *dummy)
4872{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004873 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004874}
4875
Tim Peters2a799bf2002-12-16 20:18:38 +00004876/* Return new local datetime from timestamp (Python timestamp -- a double). */
4877static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004878datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004879{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004880 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004881 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 PyObject *tzinfo = Py_None;
4883 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004884
Victor Stinner5d272cc2012-03-13 13:35:55 +01004885 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004886 keywords, &timestamp, &tzinfo))
4887 return NULL;
4888 if (check_tzinfo_subclass(tzinfo) < 0)
4889 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004891 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004892 tzinfo == Py_None ? _PyTime_localtime :
4893 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004894 timestamp,
4895 tzinfo);
4896 if (self != NULL && tzinfo != Py_None) {
4897 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004898 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004899 }
4900 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004901}
4902
Tim Petersa9bc1682003-01-11 03:39:11 +00004903/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4904static PyObject *
4905datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4906{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004907 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004908 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004909
Victor Stinner5d272cc2012-03-13 13:35:55 +01004910 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004911 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004912 Py_None);
4913 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004914}
4915
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004916/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004917static PyObject *
4918datetime_strptime(PyObject *cls, PyObject *args)
4919{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004920 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004921 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004922 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004923
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004924 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004925 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004926
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004927 if (module == NULL) {
4928 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004929 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004930 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004931 }
Victor Stinner20401de2016-12-09 15:24:31 +01004932 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4933 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004934}
4935
Tim Petersa9bc1682003-01-11 03:39:11 +00004936/* Return new datetime from date/datetime and time arguments. */
4937static PyObject *
4938datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4939{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004940 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004941 PyObject *date;
4942 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004943 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004944 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004945
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004946 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004947 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004948 &PyDateTime_TimeType, &time, &tzinfo)) {
4949 if (tzinfo == NULL) {
4950 if (HASTZINFO(time))
4951 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4952 else
4953 tzinfo = Py_None;
4954 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004955 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
4956 GET_MONTH(date),
4957 GET_DAY(date),
4958 TIME_GET_HOUR(time),
4959 TIME_GET_MINUTE(time),
4960 TIME_GET_SECOND(time),
4961 TIME_GET_MICROSECOND(time),
4962 tzinfo,
4963 TIME_GET_FOLD(time),
4964 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004965 }
4966 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004967}
Tim Peters2a799bf2002-12-16 20:18:38 +00004968
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004969static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004970_sanitize_isoformat_str(PyObject *dtstr)
4971{
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004972 // `fromisoformat` allows surrogate characters in exactly one position,
4973 // the separator; to allow datetime_fromisoformat to make the simplifying
4974 // assumption that all valid strings can be encoded in UTF-8, this function
4975 // replaces any surrogate character separators with `T`.
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004976 //
4977 // The result of this, if not NULL, returns a new reference
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004978 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004979 if (len < 0) {
4980 return NULL;
4981 }
4982
4983 if (len <= 10 ||
4984 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
4985 Py_INCREF(dtstr);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004986 return dtstr;
4987 }
4988
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004989 PyObject *str_out = _PyUnicode_Copy(dtstr);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004990 if (str_out == NULL) {
4991 return NULL;
4992 }
4993
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004994 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004995 Py_DECREF(str_out);
4996 return NULL;
4997 }
4998
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004999 return str_out;
5000}
5001
5002static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005003datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5004{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005005 assert(dtstr != NULL);
5006
5007 if (!PyUnicode_Check(dtstr)) {
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005008 PyErr_SetString(PyExc_TypeError,
5009 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005010 return NULL;
5011 }
5012
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005013 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5014 if (dtstr_clean == NULL) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005015 goto error;
5016 }
5017
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005018 Py_ssize_t len;
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005019 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005020
5021 if (dt_ptr == NULL) {
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005022 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5023 // Encoding errors are invalid string errors at this point
5024 goto invalid_string_error;
5025 }
5026 else {
5027 goto error;
5028 }
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005029 }
5030
5031 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005032
5033 int year = 0, month = 0, day = 0;
5034 int hour = 0, minute = 0, second = 0, microsecond = 0;
5035 int tzoffset = 0, tzusec = 0;
5036
5037 // date has a fixed length of 10
5038 int rv = parse_isoformat_date(p, &year, &month, &day);
5039
5040 if (!rv && len > 10) {
5041 // In UTF-8, the length of multi-byte characters is encoded in the MSB
5042 if ((p[10] & 0x80) == 0) {
5043 p += 11;
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005044 }
5045 else {
5046 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005047 case 0xe0:
5048 p += 13;
5049 break;
5050 case 0xf0:
5051 p += 14;
5052 break;
5053 default:
5054 p += 12;
5055 break;
5056 }
5057 }
5058
5059 len -= (p - dt_ptr);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005060 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5061 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005062 }
5063 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005064 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005065 }
5066
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005067 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005068 if (tzinfo == NULL) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005069 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005070 }
5071
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005072 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5073 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005074
5075 Py_DECREF(tzinfo);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005076 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005077 return dt;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005078
5079invalid_string_error:
5080 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5081
5082error:
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005083 Py_XDECREF(dtstr_clean);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005084
5085 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005086}
5087
Tim Peters2a799bf2002-12-16 20:18:38 +00005088/*
5089 * Destructor.
5090 */
5091
5092static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005093datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005095 if (HASTZINFO(self)) {
5096 Py_XDECREF(self->tzinfo);
5097 }
5098 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005099}
5100
5101/*
5102 * Indirect access to tzinfo methods.
5103 */
5104
Tim Peters2a799bf2002-12-16 20:18:38 +00005105/* These are all METH_NOARGS, so don't need to check the arglist. */
5106static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005107datetime_utcoffset(PyObject *self, PyObject *unused) {
5108 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005109}
5110
5111static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005112datetime_dst(PyObject *self, PyObject *unused) {
5113 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005114}
5115
5116static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005117datetime_tzname(PyObject *self, PyObject *unused) {
5118 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005119}
5120
5121/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005122 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005123 */
5124
Tim Petersa9bc1682003-01-11 03:39:11 +00005125/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5126 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005127 */
5128static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005129add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005130 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005132 /* Note that the C-level additions can't overflow, because of
5133 * invariant bounds on the member values.
5134 */
5135 int year = GET_YEAR(date);
5136 int month = GET_MONTH(date);
5137 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5138 int hour = DATE_GET_HOUR(date);
5139 int minute = DATE_GET_MINUTE(date);
5140 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5141 int microsecond = DATE_GET_MICROSECOND(date) +
5142 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005144 assert(factor == 1 || factor == -1);
5145 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005146 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005147 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005148 }
5149
5150 return new_datetime(year, month, day,
5151 hour, minute, second, microsecond,
5152 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005153}
5154
5155static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005156datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005158 if (PyDateTime_Check(left)) {
5159 /* datetime + ??? */
5160 if (PyDelta_Check(right))
5161 /* datetime + delta */
5162 return add_datetime_timedelta(
5163 (PyDateTime_DateTime *)left,
5164 (PyDateTime_Delta *)right,
5165 1);
5166 }
5167 else if (PyDelta_Check(left)) {
5168 /* delta + datetime */
5169 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5170 (PyDateTime_Delta *) left,
5171 1);
5172 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005173 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005174}
5175
5176static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005177datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005179 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005181 if (PyDateTime_Check(left)) {
5182 /* datetime - ??? */
5183 if (PyDateTime_Check(right)) {
5184 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005185 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005186 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005187
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005188 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5189 offset2 = offset1 = Py_None;
5190 Py_INCREF(offset1);
5191 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005192 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005193 else {
5194 offset1 = datetime_utcoffset(left, NULL);
5195 if (offset1 == NULL)
5196 return NULL;
5197 offset2 = datetime_utcoffset(right, NULL);
5198 if (offset2 == NULL) {
5199 Py_DECREF(offset1);
5200 return NULL;
5201 }
5202 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5203 PyErr_SetString(PyExc_TypeError,
5204 "can't subtract offset-naive and "
5205 "offset-aware datetimes");
5206 Py_DECREF(offset1);
5207 Py_DECREF(offset2);
5208 return NULL;
5209 }
5210 }
5211 if ((offset1 != offset2) &&
5212 delta_cmp(offset1, offset2) != 0) {
5213 offdiff = delta_subtract(offset1, offset2);
5214 if (offdiff == NULL) {
5215 Py_DECREF(offset1);
5216 Py_DECREF(offset2);
5217 return NULL;
5218 }
5219 }
5220 Py_DECREF(offset1);
5221 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005222 delta_d = ymd_to_ord(GET_YEAR(left),
5223 GET_MONTH(left),
5224 GET_DAY(left)) -
5225 ymd_to_ord(GET_YEAR(right),
5226 GET_MONTH(right),
5227 GET_DAY(right));
5228 /* These can't overflow, since the values are
5229 * normalized. At most this gives the number of
5230 * seconds in one day.
5231 */
5232 delta_s = (DATE_GET_HOUR(left) -
5233 DATE_GET_HOUR(right)) * 3600 +
5234 (DATE_GET_MINUTE(left) -
5235 DATE_GET_MINUTE(right)) * 60 +
5236 (DATE_GET_SECOND(left) -
5237 DATE_GET_SECOND(right));
5238 delta_us = DATE_GET_MICROSECOND(left) -
5239 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005240 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005241 if (result == NULL)
5242 return NULL;
5243
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005244 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005245 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005246 Py_DECREF(offdiff);
5247 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005248 }
5249 else if (PyDelta_Check(right)) {
5250 /* datetime - delta */
5251 result = add_datetime_timedelta(
5252 (PyDateTime_DateTime *)left,
5253 (PyDateTime_Delta *)right,
5254 -1);
5255 }
5256 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005258 if (result == Py_NotImplemented)
5259 Py_INCREF(result);
5260 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005261}
5262
5263/* Various ways to turn a datetime into a string. */
5264
5265static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005266datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005268 const char *type_name = Py_TYPE(self)->tp_name;
5269 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005271 if (DATE_GET_MICROSECOND(self)) {
5272 baserepr = PyUnicode_FromFormat(
5273 "%s(%d, %d, %d, %d, %d, %d, %d)",
5274 type_name,
5275 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5276 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5277 DATE_GET_SECOND(self),
5278 DATE_GET_MICROSECOND(self));
5279 }
5280 else if (DATE_GET_SECOND(self)) {
5281 baserepr = PyUnicode_FromFormat(
5282 "%s(%d, %d, %d, %d, %d, %d)",
5283 type_name,
5284 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5285 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5286 DATE_GET_SECOND(self));
5287 }
5288 else {
5289 baserepr = PyUnicode_FromFormat(
5290 "%s(%d, %d, %d, %d, %d)",
5291 type_name,
5292 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5293 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5294 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005295 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5296 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005297 if (baserepr == NULL || ! HASTZINFO(self))
5298 return baserepr;
5299 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005300}
5301
Tim Petersa9bc1682003-01-11 03:39:11 +00005302static PyObject *
5303datetime_str(PyDateTime_DateTime *self)
5304{
Victor Stinner4c381542016-12-09 00:33:39 +01005305 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005306}
Tim Peters2a799bf2002-12-16 20:18:38 +00005307
5308static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005309datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005310{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005311 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005312 char *timespec = NULL;
5313 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005314 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005315 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005316 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005317 static char *specs[][2] = {
5318 {"hours", "%04d-%02d-%02d%c%02d"},
5319 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5320 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5321 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5322 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5323 };
5324 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005325
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005326 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005327 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005328
5329 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5330 if (us == 0) {
5331 /* seconds */
5332 given_spec = 2;
5333 }
5334 else {
5335 /* microseconds */
5336 given_spec = 4;
5337 }
5338 }
5339 else {
5340 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5341 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5342 if (given_spec == 3) {
5343 us = us / 1000;
5344 }
5345 break;
5346 }
5347 }
5348 }
5349
5350 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5351 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5352 return NULL;
5353 }
5354 else {
5355 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005356 GET_YEAR(self), GET_MONTH(self),
5357 GET_DAY(self), (int)sep,
5358 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5359 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005360 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005362 if (!result || !HASTZINFO(self))
5363 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005365 /* We need to append the UTC offset. */
5366 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5367 (PyObject *)self) < 0) {
5368 Py_DECREF(result);
5369 return NULL;
5370 }
5371 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5372 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005373}
5374
Tim Petersa9bc1682003-01-11 03:39:11 +00005375static PyObject *
5376datetime_ctime(PyDateTime_DateTime *self)
5377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005378 return format_ctime((PyDateTime_Date *)self,
5379 DATE_GET_HOUR(self),
5380 DATE_GET_MINUTE(self),
5381 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005382}
5383
Tim Peters2a799bf2002-12-16 20:18:38 +00005384/* Miscellaneous methods. */
5385
Tim Petersa9bc1682003-01-11 03:39:11 +00005386static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005387flip_fold(PyObject *dt)
5388{
5389 return new_datetime_ex2(GET_YEAR(dt),
5390 GET_MONTH(dt),
5391 GET_DAY(dt),
5392 DATE_GET_HOUR(dt),
5393 DATE_GET_MINUTE(dt),
5394 DATE_GET_SECOND(dt),
5395 DATE_GET_MICROSECOND(dt),
5396 HASTZINFO(dt) ?
5397 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5398 !DATE_GET_FOLD(dt),
5399 Py_TYPE(dt));
5400}
5401
5402static PyObject *
5403get_flip_fold_offset(PyObject *dt)
5404{
5405 PyObject *result, *flip_dt;
5406
5407 flip_dt = flip_fold(dt);
5408 if (flip_dt == NULL)
5409 return NULL;
5410 result = datetime_utcoffset(flip_dt, NULL);
5411 Py_DECREF(flip_dt);
5412 return result;
5413}
5414
5415/* PEP 495 exception: Whenever one or both of the operands in
5416 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakafd936662018-03-28 23:05:24 +03005417 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005418 *
5419 * Return 1 if exception applies, 0 if not, and -1 on error.
5420 */
5421static int
5422pep495_eq_exception(PyObject *self, PyObject *other,
5423 PyObject *offset_self, PyObject *offset_other)
5424{
5425 int result = 0;
5426 PyObject *flip_offset;
5427
5428 flip_offset = get_flip_fold_offset(self);
5429 if (flip_offset == NULL)
5430 return -1;
5431 if (flip_offset != offset_self &&
5432 delta_cmp(flip_offset, offset_self))
5433 {
5434 result = 1;
5435 goto done;
5436 }
5437 Py_DECREF(flip_offset);
5438
5439 flip_offset = get_flip_fold_offset(other);
5440 if (flip_offset == NULL)
5441 return -1;
5442 if (flip_offset != offset_other &&
5443 delta_cmp(flip_offset, offset_other))
5444 result = 1;
5445 done:
5446 Py_DECREF(flip_offset);
5447 return result;
5448}
5449
5450static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005451datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005452{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005453 PyObject *result = NULL;
5454 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005455 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005457 if (! PyDateTime_Check(other)) {
5458 if (PyDate_Check(other)) {
5459 /* Prevent invocation of date_richcompare. We want to
5460 return NotImplemented here to give the other object
5461 a chance. But since DateTime is a subclass of
5462 Date, if the other object is a Date, it would
5463 compute an ordering based on the date part alone,
5464 and we don't want that. So force unequal or
5465 uncomparable here in that case. */
5466 if (op == Py_EQ)
5467 Py_RETURN_FALSE;
5468 if (op == Py_NE)
5469 Py_RETURN_TRUE;
5470 return cmperror(self, other);
5471 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005472 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005473 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005474
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005475 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005476 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5477 ((PyDateTime_DateTime *)other)->data,
5478 _PyDateTime_DATETIME_DATASIZE);
5479 return diff_to_bool(diff, op);
5480 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005481 offset1 = datetime_utcoffset(self, NULL);
5482 if (offset1 == NULL)
5483 return NULL;
5484 offset2 = datetime_utcoffset(other, NULL);
5485 if (offset2 == NULL)
5486 goto done;
5487 /* If they're both naive, or both aware and have the same offsets,
5488 * we get off cheap. Note that if they're both naive, offset1 ==
5489 * offset2 == Py_None at this point.
5490 */
5491 if ((offset1 == offset2) ||
5492 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5493 delta_cmp(offset1, offset2) == 0)) {
5494 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5495 ((PyDateTime_DateTime *)other)->data,
5496 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005497 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5498 int ex = pep495_eq_exception(self, other, offset1, offset2);
5499 if (ex == -1)
5500 goto done;
5501 if (ex)
5502 diff = 1;
5503 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005504 result = diff_to_bool(diff, op);
5505 }
5506 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005507 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005508
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005509 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005510 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5511 other);
5512 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005513 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005514 diff = GET_TD_DAYS(delta);
5515 if (diff == 0)
5516 diff = GET_TD_SECONDS(delta) |
5517 GET_TD_MICROSECONDS(delta);
5518 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005519 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5520 int ex = pep495_eq_exception(self, other, offset1, offset2);
5521 if (ex == -1)
5522 goto done;
5523 if (ex)
5524 diff = 1;
5525 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005526 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005527 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005528 else if (op == Py_EQ) {
5529 result = Py_False;
5530 Py_INCREF(result);
5531 }
5532 else if (op == Py_NE) {
5533 result = Py_True;
5534 Py_INCREF(result);
5535 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005536 else {
5537 PyErr_SetString(PyExc_TypeError,
5538 "can't compare offset-naive and "
5539 "offset-aware datetimes");
5540 }
5541 done:
5542 Py_DECREF(offset1);
5543 Py_XDECREF(offset2);
5544 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005545}
5546
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005547static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005548datetime_hash(PyDateTime_DateTime *self)
5549{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005550 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005551 PyObject *offset, *self0;
5552 if (DATE_GET_FOLD(self)) {
5553 self0 = new_datetime_ex2(GET_YEAR(self),
5554 GET_MONTH(self),
5555 GET_DAY(self),
5556 DATE_GET_HOUR(self),
5557 DATE_GET_MINUTE(self),
5558 DATE_GET_SECOND(self),
5559 DATE_GET_MICROSECOND(self),
5560 HASTZINFO(self) ? self->tzinfo : Py_None,
5561 0, Py_TYPE(self));
5562 if (self0 == NULL)
5563 return -1;
5564 }
5565 else {
5566 self0 = (PyObject *)self;
5567 Py_INCREF(self0);
5568 }
5569 offset = datetime_utcoffset(self0, NULL);
5570 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005571
5572 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005573 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005575 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005576 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005577 self->hashcode = generic_hash(
5578 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005579 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005580 PyObject *temp1, *temp2;
5581 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005583 assert(HASTZINFO(self));
5584 days = ymd_to_ord(GET_YEAR(self),
5585 GET_MONTH(self),
5586 GET_DAY(self));
5587 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005588 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005589 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005590 temp1 = new_delta(days, seconds,
5591 DATE_GET_MICROSECOND(self),
5592 1);
5593 if (temp1 == NULL) {
5594 Py_DECREF(offset);
5595 return -1;
5596 }
5597 temp2 = delta_subtract(temp1, offset);
5598 Py_DECREF(temp1);
5599 if (temp2 == NULL) {
5600 Py_DECREF(offset);
5601 return -1;
5602 }
5603 self->hashcode = PyObject_Hash(temp2);
5604 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005605 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005606 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005607 }
5608 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005609}
Tim Peters2a799bf2002-12-16 20:18:38 +00005610
5611static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005612datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005614 PyObject *clone;
5615 PyObject *tuple;
5616 int y = GET_YEAR(self);
5617 int m = GET_MONTH(self);
5618 int d = GET_DAY(self);
5619 int hh = DATE_GET_HOUR(self);
5620 int mm = DATE_GET_MINUTE(self);
5621 int ss = DATE_GET_SECOND(self);
5622 int us = DATE_GET_MICROSECOND(self);
5623 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005624 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005625
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005626 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005627 datetime_kws,
5628 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005629 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005630 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005631 if (fold != 0 && fold != 1) {
5632 PyErr_SetString(PyExc_ValueError,
5633 "fold must be either 0 or 1");
5634 return NULL;
5635 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005636 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5637 if (tuple == NULL)
5638 return NULL;
5639 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005640 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005641 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005642 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005643 Py_DECREF(tuple);
5644 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005645}
5646
5647static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005648local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005649{
5650 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005651 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005652 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005653 PyObject *nameo = NULL;
5654 const char *zone = NULL;
5655
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005656 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005657 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005658#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005659 zone = local_time_tm.tm_zone;
5660 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005661#else /* HAVE_STRUCT_TM_TM_ZONE */
5662 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005663 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005664 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005665 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005666 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005667 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005668 local_time = new_datetime(local_time_tm.tm_year + 1900,
5669 local_time_tm.tm_mon + 1,
5670 local_time_tm.tm_mday,
5671 local_time_tm.tm_hour,
5672 local_time_tm.tm_min,
5673 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005674 if (local_time == NULL) {
5675 return NULL;
5676 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005677 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005678 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005679 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5680 utc_time_tm.tm_mon + 1,
5681 utc_time_tm.tm_mday,
5682 utc_time_tm.tm_hour,
5683 utc_time_tm.tm_min,
5684 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005685 if (utc_time == NULL) {
5686 Py_DECREF(local_time);
5687 return NULL;
5688 }
5689 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005690 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005691 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005692 }
5693#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005694 if (delta == NULL) {
5695 return NULL;
5696 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005697 if (zone != NULL) {
5698 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5699 if (nameo == NULL)
5700 goto error;
5701 }
5702 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005703 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005704 error:
5705 Py_DECREF(delta);
5706 return result;
5707}
5708
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005709static PyObject *
5710local_timezone(PyDateTime_DateTime *utc_time)
5711{
5712 time_t timestamp;
5713 PyObject *delta;
5714 PyObject *one_second;
5715 PyObject *seconds;
5716
5717 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5718 if (delta == NULL)
5719 return NULL;
5720 one_second = new_delta(0, 1, 0, 0);
5721 if (one_second == NULL) {
5722 Py_DECREF(delta);
5723 return NULL;
5724 }
5725 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5726 (PyDateTime_Delta *)one_second);
5727 Py_DECREF(one_second);
5728 Py_DECREF(delta);
5729 if (seconds == NULL)
5730 return NULL;
5731 timestamp = _PyLong_AsTime_t(seconds);
5732 Py_DECREF(seconds);
5733 if (timestamp == -1 && PyErr_Occurred())
5734 return NULL;
5735 return local_timezone_from_timestamp(timestamp);
5736}
5737
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005738static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005739local_to_seconds(int year, int month, int day,
5740 int hour, int minute, int second, int fold);
5741
5742static PyObject *
5743local_timezone_from_local(PyDateTime_DateTime *local_dt)
5744{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005745 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005746 time_t timestamp;
5747 seconds = local_to_seconds(GET_YEAR(local_dt),
5748 GET_MONTH(local_dt),
5749 GET_DAY(local_dt),
5750 DATE_GET_HOUR(local_dt),
5751 DATE_GET_MINUTE(local_dt),
5752 DATE_GET_SECOND(local_dt),
5753 DATE_GET_FOLD(local_dt));
5754 if (seconds == -1)
5755 return NULL;
5756 /* XXX: add bounds check */
5757 timestamp = seconds - epoch;
5758 return local_timezone_from_timestamp(timestamp);
5759}
5760
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005761static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005762datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005763{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005764 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005765 PyObject *offset;
5766 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005767 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005768 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005769 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005770
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005771 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005772 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005773 return NULL;
5774
5775 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005776 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005777
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005778 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005779 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005780 self_tzinfo = local_timezone_from_local(self);
5781 if (self_tzinfo == NULL)
5782 return NULL;
5783 } else {
5784 self_tzinfo = self->tzinfo;
5785 Py_INCREF(self_tzinfo);
5786 }
Tim Peters521fc152002-12-31 17:36:56 +00005787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005788 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005789 if (self_tzinfo == tzinfo) {
5790 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005791 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005792 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005793 }
Tim Peters521fc152002-12-31 17:36:56 +00005794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005795 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005796 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5797 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005798 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005799 return NULL;
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005800 else if(offset == Py_None) {
5801 Py_DECREF(offset);
5802 goto naive;
5803 }
5804 else if (!PyDelta_Check(offset)) {
5805 Py_DECREF(offset);
5806 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5807 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5808 return NULL;
5809 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005810 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005811 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5812 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005813 Py_DECREF(offset);
5814 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005815 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005816
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005817 /* Make sure result is aware and UTC. */
5818 if (!HASTZINFO(result)) {
5819 temp = (PyObject *)result;
5820 result = (PyDateTime_DateTime *)
5821 new_datetime_ex2(GET_YEAR(result),
5822 GET_MONTH(result),
5823 GET_DAY(result),
5824 DATE_GET_HOUR(result),
5825 DATE_GET_MINUTE(result),
5826 DATE_GET_SECOND(result),
5827 DATE_GET_MICROSECOND(result),
5828 PyDateTime_TimeZone_UTC,
5829 DATE_GET_FOLD(result),
5830 Py_TYPE(result));
5831 Py_DECREF(temp);
5832 if (result == NULL)
5833 return NULL;
5834 }
5835 else {
5836 /* Result is already aware - just replace tzinfo. */
5837 temp = result->tzinfo;
5838 result->tzinfo = PyDateTime_TimeZone_UTC;
5839 Py_INCREF(result->tzinfo);
5840 Py_DECREF(temp);
5841 }
5842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005843 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005844 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005845 if (tzinfo == Py_None) {
5846 tzinfo = local_timezone(result);
5847 if (tzinfo == NULL) {
5848 Py_DECREF(result);
5849 return NULL;
5850 }
5851 }
5852 else
5853 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005854 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005855 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005856
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005857 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005858 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005859 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005860 Py_DECREF(temp);
5861
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005862 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005863}
5864
5865static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005866datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005868 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005870 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005871 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005872
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005873 dst = call_dst(self->tzinfo, (PyObject *)self);
5874 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005875 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005876
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005877 if (dst != Py_None)
5878 dstflag = delta_bool((PyDateTime_Delta *)dst);
5879 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005880 }
5881 return build_struct_time(GET_YEAR(self),
5882 GET_MONTH(self),
5883 GET_DAY(self),
5884 DATE_GET_HOUR(self),
5885 DATE_GET_MINUTE(self),
5886 DATE_GET_SECOND(self),
5887 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005888}
5889
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005890static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005891local_to_seconds(int year, int month, int day,
5892 int hour, int minute, int second, int fold)
5893{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005894 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005895 t = utc_to_seconds(year, month, day, hour, minute, second);
5896 /* Our goal is to solve t = local(u) for u. */
5897 lt = local(t);
5898 if (lt == -1)
5899 return -1;
5900 a = lt - t;
5901 u1 = t - a;
5902 t1 = local(u1);
5903 if (t1 == -1)
5904 return -1;
5905 if (t1 == t) {
5906 /* We found one solution, but it may not be the one we need.
5907 * Look for an earlier solution (if `fold` is 0), or a
5908 * later one (if `fold` is 1). */
5909 if (fold)
5910 u2 = u1 + max_fold_seconds;
5911 else
5912 u2 = u1 - max_fold_seconds;
5913 lt = local(u2);
5914 if (lt == -1)
5915 return -1;
5916 b = lt - u2;
5917 if (a == b)
5918 return u1;
5919 }
5920 else {
5921 b = t1 - u1;
5922 assert(a != b);
5923 }
5924 u2 = t - b;
5925 t2 = local(u2);
5926 if (t2 == -1)
5927 return -1;
5928 if (t2 == t)
5929 return u2;
5930 if (t1 == t)
5931 return u1;
5932 /* We have found both offsets a and b, but neither t - a nor t - b is
5933 * a solution. This means t is in the gap. */
5934 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5935}
5936
5937/* date(1970,1,1).toordinal() == 719163 */
5938#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5939
Tim Peters2a799bf2002-12-16 20:18:38 +00005940static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005941datetime_timestamp(PyDateTime_DateTime *self)
5942{
5943 PyObject *result;
5944
5945 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5946 PyObject *delta;
5947 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5948 if (delta == NULL)
5949 return NULL;
5950 result = delta_total_seconds(delta);
5951 Py_DECREF(delta);
5952 }
5953 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005954 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005955 seconds = local_to_seconds(GET_YEAR(self),
5956 GET_MONTH(self),
5957 GET_DAY(self),
5958 DATE_GET_HOUR(self),
5959 DATE_GET_MINUTE(self),
5960 DATE_GET_SECOND(self),
5961 DATE_GET_FOLD(self));
5962 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005963 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005964 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5965 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005966 }
5967 return result;
5968}
5969
5970static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005971datetime_getdate(PyDateTime_DateTime *self)
5972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005973 return new_date(GET_YEAR(self),
5974 GET_MONTH(self),
5975 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005976}
5977
5978static PyObject *
5979datetime_gettime(PyDateTime_DateTime *self)
5980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005981 return new_time(DATE_GET_HOUR(self),
5982 DATE_GET_MINUTE(self),
5983 DATE_GET_SECOND(self),
5984 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005985 Py_None,
5986 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005987}
5988
5989static PyObject *
5990datetime_gettimetz(PyDateTime_DateTime *self)
5991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005992 return new_time(DATE_GET_HOUR(self),
5993 DATE_GET_MINUTE(self),
5994 DATE_GET_SECOND(self),
5995 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005996 GET_DT_TZINFO(self),
5997 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005998}
5999
6000static PyObject *
6001datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00006002{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006003 int y, m, d, hh, mm, ss;
6004 PyObject *tzinfo;
6005 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006006
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006007 tzinfo = GET_DT_TZINFO(self);
6008 if (tzinfo == Py_None) {
6009 utcself = self;
6010 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006011 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006012 else {
6013 PyObject *offset;
6014 offset = call_utcoffset(tzinfo, (PyObject *)self);
6015 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006016 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006017 if (offset == Py_None) {
6018 Py_DECREF(offset);
6019 utcself = self;
6020 Py_INCREF(utcself);
6021 }
6022 else {
6023 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6024 (PyDateTime_Delta *)offset, -1);
6025 Py_DECREF(offset);
6026 if (utcself == NULL)
6027 return NULL;
6028 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006029 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006030 y = GET_YEAR(utcself);
6031 m = GET_MONTH(utcself);
6032 d = GET_DAY(utcself);
6033 hh = DATE_GET_HOUR(utcself);
6034 mm = DATE_GET_MINUTE(utcself);
6035 ss = DATE_GET_SECOND(utcself);
6036
6037 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006038 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006039}
6040
Tim Peters371935f2003-02-01 01:52:50 +00006041/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006042
Tim Petersa9bc1682003-01-11 03:39:11 +00006043/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006044 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6045 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006046 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006047 */
6048static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006049datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006051 PyObject *basestate;
6052 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006054 basestate = PyBytes_FromStringAndSize((char *)self->data,
6055 _PyDateTime_DATETIME_DATASIZE);
6056 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006057 if (proto > 3 && DATE_GET_FOLD(self))
6058 /* Set the first bit of the third byte */
6059 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006060 if (! HASTZINFO(self) || self->tzinfo == Py_None)
6061 result = PyTuple_Pack(1, basestate);
6062 else
6063 result = PyTuple_Pack(2, basestate, self->tzinfo);
6064 Py_DECREF(basestate);
6065 }
6066 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00006067}
6068
6069static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006070datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006071{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006072 int proto;
6073 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006074 return NULL;
6075
6076 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006077}
6078
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006079static PyObject *
6080datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6081{
6082 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6083}
6084
Tim Petersa9bc1682003-01-11 03:39:11 +00006085static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006087 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006088
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006089 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006091 {"utcnow", (PyCFunction)datetime_utcnow,
6092 METH_NOARGS | METH_CLASS,
6093 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006095 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
6096 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6097 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006099 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6100 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006101 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006103 {"strptime", (PyCFunction)datetime_strptime,
6104 METH_VARARGS | METH_CLASS,
6105 PyDoc_STR("string, format -> new datetime parsed from a string "
6106 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006108 {"combine", (PyCFunction)datetime_combine,
6109 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6110 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006111
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006112 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6113 METH_O | METH_CLASS,
6114 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006116 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006118 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6119 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006121 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6122 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006124 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6125 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006127 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6128 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006130 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6131 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006132
Alexander Belopolskya4415142012-06-08 12:33:09 -04006133 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6134 PyDoc_STR("Return POSIX timestamp as float.")},
6135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006136 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6137 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006139 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
6140 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006141 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006142 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006143 "defaults to 'T'.\n"
6144 "timespec specifies what components of the time to include"
6145 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6146 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006148 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6149 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006151 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6152 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006154 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6155 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006157 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
6158 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006160 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
6161 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006162
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006163 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006164 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006165
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006166 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6167 PyDoc_STR("__reduce__() -> (cls, state)")},
6168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006169 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006170};
6171
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006172static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006173PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6174\n\
6175The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006176instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006177
Tim Petersa9bc1682003-01-11 03:39:11 +00006178static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006179 datetime_add, /* nb_add */
6180 datetime_subtract, /* nb_subtract */
6181 0, /* nb_multiply */
6182 0, /* nb_remainder */
6183 0, /* nb_divmod */
6184 0, /* nb_power */
6185 0, /* nb_negative */
6186 0, /* nb_positive */
6187 0, /* nb_absolute */
6188 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006189};
6190
Neal Norwitz227b5332006-03-22 09:28:35 +00006191static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006192 PyVarObject_HEAD_INIT(NULL, 0)
6193 "datetime.datetime", /* tp_name */
6194 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6195 0, /* tp_itemsize */
6196 (destructor)datetime_dealloc, /* tp_dealloc */
6197 0, /* tp_print */
6198 0, /* tp_getattr */
6199 0, /* tp_setattr */
6200 0, /* tp_reserved */
6201 (reprfunc)datetime_repr, /* tp_repr */
6202 &datetime_as_number, /* tp_as_number */
6203 0, /* tp_as_sequence */
6204 0, /* tp_as_mapping */
6205 (hashfunc)datetime_hash, /* tp_hash */
6206 0, /* tp_call */
6207 (reprfunc)datetime_str, /* tp_str */
6208 PyObject_GenericGetAttr, /* tp_getattro */
6209 0, /* tp_setattro */
6210 0, /* tp_as_buffer */
6211 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6212 datetime_doc, /* tp_doc */
6213 0, /* tp_traverse */
6214 0, /* tp_clear */
6215 datetime_richcompare, /* tp_richcompare */
6216 0, /* tp_weaklistoffset */
6217 0, /* tp_iter */
6218 0, /* tp_iternext */
6219 datetime_methods, /* tp_methods */
6220 0, /* tp_members */
6221 datetime_getset, /* tp_getset */
6222 &PyDateTime_DateType, /* tp_base */
6223 0, /* tp_dict */
6224 0, /* tp_descr_get */
6225 0, /* tp_descr_set */
6226 0, /* tp_dictoffset */
6227 0, /* tp_init */
6228 datetime_alloc, /* tp_alloc */
6229 datetime_new, /* tp_new */
6230 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006231};
6232
6233/* ---------------------------------------------------------------------------
6234 * Module methods and initialization.
6235 */
6236
6237static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006238 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006239};
6240
Tim Peters9ddf40b2004-06-20 22:41:32 +00006241/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6242 * datetime.h.
6243 */
6244static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006245 &PyDateTime_DateType,
6246 &PyDateTime_DateTimeType,
6247 &PyDateTime_TimeType,
6248 &PyDateTime_DeltaType,
6249 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006250 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006251 new_date_ex,
6252 new_datetime_ex,
6253 new_time_ex,
6254 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006255 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006256 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006257 date_fromtimestamp,
6258 new_datetime_ex2,
6259 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006260};
6261
6262
Martin v. Löwis1a214512008-06-11 05:26:20 +00006263
6264static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006265 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006266 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006267 "Fast implementation of the datetime type.",
6268 -1,
6269 module_methods,
6270 NULL,
6271 NULL,
6272 NULL,
6273 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006274};
6275
Tim Peters2a799bf2002-12-16 20:18:38 +00006276PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006277PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006278{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006279 PyObject *m; /* a module object */
6280 PyObject *d; /* its dict */
6281 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006282 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006284 m = PyModule_Create(&datetimemodule);
6285 if (m == NULL)
6286 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006288 if (PyType_Ready(&PyDateTime_DateType) < 0)
6289 return NULL;
6290 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6291 return NULL;
6292 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6293 return NULL;
6294 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6295 return NULL;
6296 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6297 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006298 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6299 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006301 /* timedelta values */
6302 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006304 x = new_delta(0, 0, 1, 0);
6305 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6306 return NULL;
6307 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006309 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6310 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6311 return NULL;
6312 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006314 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6315 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6316 return NULL;
6317 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006319 /* date values */
6320 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006322 x = new_date(1, 1, 1);
6323 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6324 return NULL;
6325 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006327 x = new_date(MAXYEAR, 12, 31);
6328 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6329 return NULL;
6330 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006332 x = new_delta(1, 0, 0, 0);
6333 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6334 return NULL;
6335 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006337 /* time values */
6338 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006339
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006340 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006341 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6342 return NULL;
6343 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006344
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006345 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006346 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6347 return NULL;
6348 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006350 x = new_delta(0, 0, 1, 0);
6351 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6352 return NULL;
6353 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006355 /* datetime values */
6356 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006357
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006358 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006359 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6360 return NULL;
6361 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006362
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006363 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006364 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6365 return NULL;
6366 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006368 x = new_delta(0, 0, 1, 0);
6369 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6370 return NULL;
6371 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006372
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006373 /* timezone values */
6374 d = PyDateTime_TimeZoneType.tp_dict;
6375
6376 delta = new_delta(0, 0, 0, 0);
6377 if (delta == NULL)
6378 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006379 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006380 Py_DECREF(delta);
6381 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6382 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006383 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006384 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006385
6386 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6387 if (delta == NULL)
6388 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006389 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006390 Py_DECREF(delta);
6391 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6392 return NULL;
6393 Py_DECREF(x);
6394
6395 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6396 if (delta == NULL)
6397 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006398 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006399 Py_DECREF(delta);
6400 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6401 return NULL;
6402 Py_DECREF(x);
6403
Alexander Belopolskya4415142012-06-08 12:33:09 -04006404 /* Epoch */
6405 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006406 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006407 if (PyDateTime_Epoch == NULL)
6408 return NULL;
6409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006410 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006411 PyModule_AddIntMacro(m, MINYEAR);
6412 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006414 Py_INCREF(&PyDateTime_DateType);
6415 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006417 Py_INCREF(&PyDateTime_DateTimeType);
6418 PyModule_AddObject(m, "datetime",
6419 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006421 Py_INCREF(&PyDateTime_TimeType);
6422 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006424 Py_INCREF(&PyDateTime_DeltaType);
6425 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006427 Py_INCREF(&PyDateTime_TZInfoType);
6428 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006429
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006430 Py_INCREF(&PyDateTime_TimeZoneType);
6431 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006433 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6434 if (x == NULL)
6435 return NULL;
6436 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006438 /* A 4-year cycle has an extra leap day over what we'd get from
6439 * pasting together 4 single years.
6440 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006441 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006442 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006444 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6445 * get from pasting together 4 100-year cycles.
6446 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006447 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006448 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006450 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6451 * pasting together 25 4-year cycles.
6452 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006453 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006454 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006456 us_per_ms = PyLong_FromLong(1000);
6457 us_per_second = PyLong_FromLong(1000000);
6458 us_per_minute = PyLong_FromLong(60000000);
6459 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006460 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006461 us_per_minute == NULL || seconds_per_day == NULL)
6462 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006464 /* The rest are too big for 32-bit ints, but even
6465 * us_per_week fits in 40 bits, so doubles should be exact.
6466 */
6467 us_per_hour = PyLong_FromDouble(3600000000.0);
6468 us_per_day = PyLong_FromDouble(86400000000.0);
6469 us_per_week = PyLong_FromDouble(604800000000.0);
6470 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6471 return NULL;
6472 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006473}
Tim Petersf3615152003-01-01 21:51:37 +00006474
6475/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006476Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006477 x.n = x stripped of its timezone -- its naive time.
6478 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006479 return None
Tim Petersf3615152003-01-01 21:51:37 +00006480 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006481 return None
Tim Petersf3615152003-01-01 21:51:37 +00006482 x.s = x's standard offset, x.o - x.d
6483
6484Now some derived rules, where k is a duration (timedelta).
6485
64861. x.o = x.s + x.d
6487 This follows from the definition of x.s.
6488
Tim Petersc5dc4da2003-01-02 17:55:03 +000064892. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006490 This is actually a requirement, an assumption we need to make about
6491 sane tzinfo classes.
6492
64933. The naive UTC time corresponding to x is x.n - x.o.
6494 This is again a requirement for a sane tzinfo class.
6495
64964. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006497 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006498
Tim Petersc5dc4da2003-01-02 17:55:03 +000064995. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006500 Again follows from how arithmetic is defined.
6501
Tim Peters8bb5ad22003-01-24 02:44:45 +00006502Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006503(meaning that the various tzinfo methods exist, and don't blow up or return
6504None when called).
6505
Tim Petersa9bc1682003-01-11 03:39:11 +00006506The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006507x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006508
6509By #3, we want
6510
Tim Peters8bb5ad22003-01-24 02:44:45 +00006511 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006512
6513The algorithm starts by attaching tz to x.n, and calling that y. So
6514x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6515becomes true; in effect, we want to solve [2] for k:
6516
Tim Peters8bb5ad22003-01-24 02:44:45 +00006517 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006518
6519By #1, this is the same as
6520
Tim Peters8bb5ad22003-01-24 02:44:45 +00006521 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006522
6523By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6524Substituting that into [3],
6525
Tim Peters8bb5ad22003-01-24 02:44:45 +00006526 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6527 k - (y+k).s - (y+k).d = 0; rearranging,
6528 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6529 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006530
Tim Peters8bb5ad22003-01-24 02:44:45 +00006531On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6532approximate k by ignoring the (y+k).d term at first. Note that k can't be
6533very large, since all offset-returning methods return a duration of magnitude
6534less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6535be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006536
6537In any case, the new value is
6538
Tim Peters8bb5ad22003-01-24 02:44:45 +00006539 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006540
Tim Peters8bb5ad22003-01-24 02:44:45 +00006541It's helpful to step back at look at [4] from a higher level: it's simply
6542mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006543
6544At this point, if
6545
Tim Peters8bb5ad22003-01-24 02:44:45 +00006546 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006547
6548we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006549at the start of daylight time. Picture US Eastern for concreteness. The wall
6550time 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 +00006551sense then. The docs ask that an Eastern tzinfo class consider such a time to
6552be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6553on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006554the only spelling that makes sense on the local wall clock.
6555
Tim Petersc5dc4da2003-01-02 17:55:03 +00006556In fact, if [5] holds at this point, we do have the standard-time spelling,
6557but that takes a bit of proof. We first prove a stronger result. What's the
6558difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006559
Tim Peters8bb5ad22003-01-24 02:44:45 +00006560 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006561
Tim Petersc5dc4da2003-01-02 17:55:03 +00006562Now
6563 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006564 (y + y.s).n = by #5
6565 y.n + y.s = since y.n = x.n
6566 x.n + y.s = since z and y are have the same tzinfo member,
6567 y.s = z.s by #2
6568 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006569
Tim Petersc5dc4da2003-01-02 17:55:03 +00006570Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006571
Tim Petersc5dc4da2003-01-02 17:55:03 +00006572 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006573 x.n - ((x.n + z.s) - z.o) = expanding
6574 x.n - x.n - z.s + z.o = cancelling
6575 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006576 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006577
Tim Petersc5dc4da2003-01-02 17:55:03 +00006578So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006579
Tim Petersc5dc4da2003-01-02 17:55:03 +00006580If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006581spelling we wanted in the endcase described above. We're done. Contrarily,
6582if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006583
Tim Petersc5dc4da2003-01-02 17:55:03 +00006584If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6585add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006586local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006587
Tim Petersc5dc4da2003-01-02 17:55:03 +00006588Let
Tim Petersf3615152003-01-01 21:51:37 +00006589
Tim Peters4fede1a2003-01-04 00:26:59 +00006590 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006591
Tim Peters4fede1a2003-01-04 00:26:59 +00006592and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006593
Tim Peters8bb5ad22003-01-24 02:44:45 +00006594 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006595
Tim Peters8bb5ad22003-01-24 02:44:45 +00006596If so, we're done. If not, the tzinfo class is insane, according to the
6597assumptions we've made. This also requires a bit of proof. As before, let's
6598compute the difference between the LHS and RHS of [8] (and skipping some of
6599the justifications for the kinds of substitutions we've done several times
6600already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006601
Tim Peters8bb5ad22003-01-24 02:44:45 +00006602 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006603 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6604 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6605 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6606 - z.n + z.n - z.o + z'.o = cancel z.n
6607 - z.o + z'.o = #1 twice
6608 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6609 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006610
6611So 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 +00006612we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6613return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006614
Tim Peters8bb5ad22003-01-24 02:44:45 +00006615How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6616a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6617would have to change the result dst() returns: we start in DST, and moving
6618a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006619
Tim Peters8bb5ad22003-01-24 02:44:45 +00006620There isn't a sane case where this can happen. The closest it gets is at
6621the end of DST, where there's an hour in UTC with no spelling in a hybrid
6622tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6623that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6624UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6625time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6626clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6627standard time. Since that's what the local clock *does*, we want to map both
6628UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006629in local time, but so it goes -- it's the way the local clock works.
6630
Tim Peters8bb5ad22003-01-24 02:44:45 +00006631When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6632so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6633z' = 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 +00006634(correctly) concludes that z' is not UTC-equivalent to x.
6635
6636Because we know z.d said z was in daylight time (else [5] would have held and
6637we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006638and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006639return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6640but the reasoning doesn't depend on the example -- it depends on there being
6641two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006642z' must be in standard time, and is the spelling we want in this case.
6643
6644Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6645concerned (because it takes z' as being in standard time rather than the
6646daylight time we intend here), but returning it gives the real-life "local
6647clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6648tz.
6649
6650When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6651the 1:MM standard time spelling we want.
6652
6653So how can this break? One of the assumptions must be violated. Two
6654possibilities:
6655
66561) [2] effectively says that y.s is invariant across all y belong to a given
6657 time zone. This isn't true if, for political reasons or continental drift,
6658 a region decides to change its base offset from UTC.
6659
66602) There may be versions of "double daylight" time where the tail end of
6661 the analysis gives up a step too early. I haven't thought about that
6662 enough to say.
6663
6664In any case, it's clear that the default fromutc() is strong enough to handle
6665"almost all" time zones: so long as the standard offset is invariant, it
6666doesn't matter if daylight time transition points change from year to year, or
6667if daylight time is skipped in some years; it doesn't matter how large or
6668small dst() may get within its bounds; and it doesn't even matter if some
6669perverse time zone returns a negative dst()). So a breaking case must be
6670pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006671--------------------------------------------------------------------------- */