blob: 9405b4610dfcdb037ea4ca8595c38100ceeef7c1 [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') {
Miss Islington (bot)26122de2019-01-14 02:41:33 -08001517 /* Null byte follows %, copy only '%'.
1518 *
1519 * Back the pin up one char so that we catch the null check
1520 * the next time through the loop.*/
1521 pin--;
1522 ptoappend = pin - 1;
1523 ntoappend = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 }
1525 /* A % has been seen and ch is the character after it. */
1526 else if (ch == 'z') {
1527 if (zreplacement == NULL) {
1528 /* format utcoffset */
1529 char buf[100];
1530 PyObject *tzinfo = get_tzinfo_member(object);
1531 zreplacement = PyBytes_FromStringAndSize("", 0);
1532 if (zreplacement == NULL) goto Done;
1533 if (tzinfo != Py_None && tzinfo != NULL) {
1534 assert(tzinfoarg != NULL);
1535 if (format_utcoffset(buf,
1536 sizeof(buf),
1537 "",
1538 tzinfo,
1539 tzinfoarg) < 0)
1540 goto Done;
1541 Py_DECREF(zreplacement);
1542 zreplacement =
1543 PyBytes_FromStringAndSize(buf,
1544 strlen(buf));
1545 if (zreplacement == NULL)
1546 goto Done;
1547 }
1548 }
1549 assert(zreplacement != NULL);
1550 ptoappend = PyBytes_AS_STRING(zreplacement);
1551 ntoappend = PyBytes_GET_SIZE(zreplacement);
1552 }
1553 else if (ch == 'Z') {
1554 /* format tzname */
1555 if (Zreplacement == NULL) {
1556 Zreplacement = make_Zreplacement(object,
1557 tzinfoarg);
1558 if (Zreplacement == NULL)
1559 goto Done;
1560 }
1561 assert(Zreplacement != NULL);
1562 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001563 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001565 if (ptoappend == NULL)
1566 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 }
1568 else if (ch == 'f') {
1569 /* format microseconds */
1570 if (freplacement == NULL) {
1571 freplacement = make_freplacement(object);
1572 if (freplacement == NULL)
1573 goto Done;
1574 }
1575 assert(freplacement != NULL);
1576 assert(PyBytes_Check(freplacement));
1577 ptoappend = PyBytes_AS_STRING(freplacement);
1578 ntoappend = PyBytes_GET_SIZE(freplacement);
1579 }
1580 else {
1581 /* percent followed by neither z nor Z */
1582 ptoappend = pin - 2;
1583 ntoappend = 2;
1584 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 /* Append the ntoappend chars starting at ptoappend to
1587 * the new format.
1588 */
1589 if (ntoappend == 0)
1590 continue;
1591 assert(ptoappend != NULL);
1592 assert(ntoappend > 0);
1593 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001594 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 PyErr_NoMemory();
1596 goto Done;
1597 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001598 totalnew <<= 1;
1599 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 pnew = PyBytes_AsString(newfmt) + usednew;
1602 }
1603 memcpy(pnew, ptoappend, ntoappend);
1604 pnew += ntoappend;
1605 usednew += ntoappend;
1606 assert(usednew <= totalnew);
1607 } /* end while() */
Miss Islington (bot)26122de2019-01-14 02:41:33 -08001608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1610 goto Done;
1611 {
1612 PyObject *format;
1613 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 if (time == NULL)
1616 goto Done;
1617 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1618 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001619 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1620 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 Py_DECREF(format);
1622 }
1623 Py_DECREF(time);
1624 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001625 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 Py_XDECREF(freplacement);
1627 Py_XDECREF(zreplacement);
1628 Py_XDECREF(Zreplacement);
1629 Py_XDECREF(newfmt);
1630 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001631}
1632
Tim Peters2a799bf2002-12-16 20:18:38 +00001633/* ---------------------------------------------------------------------------
1634 * Wrap functions from the time module. These aren't directly available
1635 * from C. Perhaps they should be.
1636 */
1637
1638/* Call time.time() and return its result (a Python float). */
1639static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001640time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 PyObject *result = NULL;
1643 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001646 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001647
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001648 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649 Py_DECREF(time);
1650 }
1651 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001652}
1653
1654/* Build a time.struct_time. The weekday and day number are automatically
1655 * computed from the y,m,d args.
1656 */
1657static PyObject *
1658build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001661 PyObject *result;
1662 _Py_IDENTIFIER(struct_time);
1663 PyObject *args;
1664
Tim Peters2a799bf2002-12-16 20:18:38 +00001665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001667 if (time == NULL) {
1668 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 }
Victor Stinner2b635972016-12-09 00:38:16 +01001670
1671 args = Py_BuildValue("iiiiiiiii",
1672 y, m, d,
1673 hh, mm, ss,
1674 weekday(y, m, d),
1675 days_before_month(y, m) + d,
1676 dstflag);
1677 if (args == NULL) {
1678 Py_DECREF(time);
1679 return NULL;
1680 }
1681
1682 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1683 args, NULL);
1684 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001685 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001687}
1688
1689/* ---------------------------------------------------------------------------
1690 * Miscellaneous helpers.
1691 */
1692
Mark Dickinsone94c6792009-02-02 20:36:42 +00001693/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001694 * The comparisons here all most naturally compute a cmp()-like result.
1695 * This little helper turns that into a bool result for rich comparisons.
1696 */
1697static PyObject *
1698diff_to_bool(int diff, int op)
1699{
stratakise8b19652017-11-02 11:32:54 +01001700 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001701}
1702
Tim Peters07534a62003-02-07 22:50:28 +00001703/* Raises a "can't compare" TypeError and returns NULL. */
1704static PyObject *
1705cmperror(PyObject *a, PyObject *b)
1706{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 PyErr_Format(PyExc_TypeError,
1708 "can't compare %s to %s",
1709 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1710 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001711}
1712
Tim Peters2a799bf2002-12-16 20:18:38 +00001713/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001714 * Cached Python objects; these are set by the module init function.
1715 */
1716
1717/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718static PyObject *us_per_ms = NULL; /* 1000 */
1719static PyObject *us_per_second = NULL; /* 1000000 */
1720static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001721static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1722static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1723static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001724static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1725
Tim Peters2a799bf2002-12-16 20:18:38 +00001726/* ---------------------------------------------------------------------------
1727 * Class implementations.
1728 */
1729
1730/*
1731 * PyDateTime_Delta implementation.
1732 */
1733
1734/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001736 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001737 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1738 * due to ubiquitous overflow possibilities.
1739 */
1740static PyObject *
1741delta_to_microseconds(PyDateTime_Delta *self)
1742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 PyObject *x1 = NULL;
1744 PyObject *x2 = NULL;
1745 PyObject *x3 = NULL;
1746 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1749 if (x1 == NULL)
1750 goto Done;
1751 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1752 if (x2 == NULL)
1753 goto Done;
1754 Py_DECREF(x1);
1755 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 /* x2 has days in seconds */
1758 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1759 if (x1 == NULL)
1760 goto Done;
1761 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1762 if (x3 == NULL)
1763 goto Done;
1764 Py_DECREF(x1);
1765 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001766 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 /* x3 has days+seconds in seconds */
1769 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1770 if (x1 == NULL)
1771 goto Done;
1772 Py_DECREF(x3);
1773 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 /* x1 has days+seconds in us */
1776 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1777 if (x2 == NULL)
1778 goto Done;
1779 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001780 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001781
1782Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 Py_XDECREF(x1);
1784 Py_XDECREF(x2);
1785 Py_XDECREF(x3);
1786 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001787}
1788
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001789static PyObject *
1790checked_divmod(PyObject *a, PyObject *b)
1791{
1792 PyObject *result = PyNumber_Divmod(a, b);
1793 if (result != NULL) {
1794 if (!PyTuple_Check(result)) {
1795 PyErr_Format(PyExc_TypeError,
1796 "divmod() returned non-tuple (type %.200s)",
1797 result->ob_type->tp_name);
1798 Py_DECREF(result);
1799 return NULL;
1800 }
1801 if (PyTuple_GET_SIZE(result) != 2) {
1802 PyErr_Format(PyExc_TypeError,
1803 "divmod() returned a tuple of size %zd",
1804 PyTuple_GET_SIZE(result));
1805 Py_DECREF(result);
1806 return NULL;
1807 }
1808 }
1809 return result;
1810}
1811
Serhiy Storchaka95949422013-08-27 19:40:23 +03001812/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001813 */
1814static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001815microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 int us;
1818 int s;
1819 int d;
Tim Peters2a799bf2002-12-16 20:18:38 +00001820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 PyObject *tuple = NULL;
1822 PyObject *num = NULL;
1823 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001824
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001825 tuple = checked_divmod(pyus, us_per_second);
1826 if (tuple == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 goto Done;
1828 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001829
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001830 num = PyTuple_GET_ITEM(tuple, 1); /* us */
1831 us = _PyLong_AsInt(num);
1832 num = NULL;
1833 if (us == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 goto Done;
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001835 }
1836 if (!(0 <= us && us < 1000000)) {
1837 goto BadDivmod;
1838 }
1839
1840 num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 Py_INCREF(num);
1842 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001843
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001844 tuple = checked_divmod(num, seconds_per_day);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 if (tuple == NULL)
1846 goto Done;
1847 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001848
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001849 num = PyTuple_GET_ITEM(tuple, 1); /* seconds */
1850 s = _PyLong_AsInt(num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 num = NULL;
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001852 if (s == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 goto Done;
1854 }
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001855 if (!(0 <= s && s < 24*3600)) {
1856 goto BadDivmod;
1857 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001858
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001859 num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 Py_INCREF(num);
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001861 d = _PyLong_AsInt(num);
1862 if (d == -1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 goto Done;
1864 }
1865 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001866
1867Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 Py_XDECREF(tuple);
1869 Py_XDECREF(num);
1870 return result;
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001871
1872BadDivmod:
1873 PyErr_SetString(PyExc_TypeError,
1874 "divmod() returned a value out of range");
1875 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001876}
1877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878#define microseconds_to_delta(pymicros) \
1879 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001880
Tim Peters2a799bf2002-12-16 20:18:38 +00001881static PyObject *
1882multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 PyObject *pyus_in;
1885 PyObject *pyus_out;
1886 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 pyus_in = delta_to_microseconds(delta);
1889 if (pyus_in == NULL)
1890 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001891
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08001892 pyus_out = PyNumber_Multiply(intobj, pyus_in);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 Py_DECREF(pyus_in);
1894 if (pyus_out == NULL)
1895 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 result = microseconds_to_delta(pyus_out);
1898 Py_DECREF(pyus_out);
1899 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001900}
1901
1902static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001903get_float_as_integer_ratio(PyObject *floatobj)
1904{
1905 PyObject *ratio;
1906
1907 assert(floatobj && PyFloat_Check(floatobj));
1908 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1909 if (ratio == NULL) {
1910 return NULL;
1911 }
1912 if (!PyTuple_Check(ratio)) {
1913 PyErr_Format(PyExc_TypeError,
1914 "unexpected return type from as_integer_ratio(): "
1915 "expected tuple, got '%.200s'",
1916 Py_TYPE(ratio)->tp_name);
1917 Py_DECREF(ratio);
1918 return NULL;
1919 }
1920 if (PyTuple_Size(ratio) != 2) {
1921 PyErr_SetString(PyExc_ValueError,
1922 "as_integer_ratio() must return a 2-tuple");
1923 Py_DECREF(ratio);
1924 return NULL;
1925 }
1926 return ratio;
1927}
1928
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001929/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001930static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001931multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001932{
1933 PyObject *result = NULL;
1934 PyObject *pyus_in = NULL, *temp, *pyus_out;
1935 PyObject *ratio = NULL;
1936
1937 pyus_in = delta_to_microseconds(delta);
1938 if (pyus_in == NULL)
1939 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001940 ratio = get_float_as_integer_ratio(floatobj);
1941 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001942 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001943 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001944 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001945 Py_DECREF(pyus_in);
1946 pyus_in = NULL;
1947 if (temp == NULL)
1948 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001949 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001950 Py_DECREF(temp);
1951 if (pyus_out == NULL)
1952 goto error;
1953 result = microseconds_to_delta(pyus_out);
1954 Py_DECREF(pyus_out);
1955 error:
1956 Py_XDECREF(pyus_in);
1957 Py_XDECREF(ratio);
1958
1959 return result;
1960}
1961
1962static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001963divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1964{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 PyObject *pyus_in;
1966 PyObject *pyus_out;
1967 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 pyus_in = delta_to_microseconds(delta);
1970 if (pyus_in == NULL)
1971 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1974 Py_DECREF(pyus_in);
1975 if (pyus_out == NULL)
1976 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 result = microseconds_to_delta(pyus_out);
1979 Py_DECREF(pyus_out);
1980 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001981}
1982
1983static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001984divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1985{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 PyObject *pyus_left;
1987 PyObject *pyus_right;
1988 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 pyus_left = delta_to_microseconds(left);
1991 if (pyus_left == NULL)
1992 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 pyus_right = delta_to_microseconds(right);
1995 if (pyus_right == NULL) {
1996 Py_DECREF(pyus_left);
1997 return NULL;
1998 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002000 result = PyNumber_FloorDivide(pyus_left, pyus_right);
2001 Py_DECREF(pyus_left);
2002 Py_DECREF(pyus_right);
2003 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002004}
2005
2006static PyObject *
2007truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
2008{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 PyObject *pyus_left;
2010 PyObject *pyus_right;
2011 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 pyus_left = delta_to_microseconds(left);
2014 if (pyus_left == NULL)
2015 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 pyus_right = delta_to_microseconds(right);
2018 if (pyus_right == NULL) {
2019 Py_DECREF(pyus_left);
2020 return NULL;
2021 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2024 Py_DECREF(pyus_left);
2025 Py_DECREF(pyus_right);
2026 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002027}
2028
2029static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002030truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2031{
2032 PyObject *result;
2033 PyObject *pyus_in, *pyus_out;
2034 pyus_in = delta_to_microseconds(delta);
2035 if (pyus_in == NULL)
2036 return NULL;
2037 pyus_out = divide_nearest(pyus_in, i);
2038 Py_DECREF(pyus_in);
2039 if (pyus_out == NULL)
2040 return NULL;
2041 result = microseconds_to_delta(pyus_out);
2042 Py_DECREF(pyus_out);
2043
2044 return result;
2045}
2046
2047static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002048delta_add(PyObject *left, PyObject *right)
2049{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002052 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2053 /* delta + delta */
2054 /* The C-level additions can't overflow because of the
2055 * invariant bounds.
2056 */
2057 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2058 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2059 int microseconds = GET_TD_MICROSECONDS(left) +
2060 GET_TD_MICROSECONDS(right);
2061 result = new_delta(days, seconds, microseconds, 1);
2062 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 if (result == Py_NotImplemented)
2065 Py_INCREF(result);
2066 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002067}
2068
2069static PyObject *
2070delta_negative(PyDateTime_Delta *self)
2071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002072 return new_delta(-GET_TD_DAYS(self),
2073 -GET_TD_SECONDS(self),
2074 -GET_TD_MICROSECONDS(self),
2075 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002076}
2077
2078static PyObject *
2079delta_positive(PyDateTime_Delta *self)
2080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 /* Could optimize this (by returning self) if this isn't a
2082 * subclass -- but who uses unary + ? Approximately nobody.
2083 */
2084 return new_delta(GET_TD_DAYS(self),
2085 GET_TD_SECONDS(self),
2086 GET_TD_MICROSECONDS(self),
2087 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002088}
2089
2090static PyObject *
2091delta_abs(PyDateTime_Delta *self)
2092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 assert(GET_TD_MICROSECONDS(self) >= 0);
2096 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 if (GET_TD_DAYS(self) < 0)
2099 result = delta_negative(self);
2100 else
2101 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002104}
2105
2106static PyObject *
2107delta_subtract(PyObject *left, PyObject *right)
2108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2112 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002113 /* The C-level additions can't overflow because of the
2114 * invariant bounds.
2115 */
2116 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2117 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2118 int microseconds = GET_TD_MICROSECONDS(left) -
2119 GET_TD_MICROSECONDS(right);
2120 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 if (result == Py_NotImplemented)
2124 Py_INCREF(result);
2125 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002126}
2127
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002128static int
2129delta_cmp(PyObject *self, PyObject *other)
2130{
2131 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2132 if (diff == 0) {
2133 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2134 if (diff == 0)
2135 diff = GET_TD_MICROSECONDS(self) -
2136 GET_TD_MICROSECONDS(other);
2137 }
2138 return diff;
2139}
2140
Tim Peters2a799bf2002-12-16 20:18:38 +00002141static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002142delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002145 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 return diff_to_bool(diff, op);
2147 }
2148 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002149 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002150 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002151}
2152
2153static PyObject *delta_getstate(PyDateTime_Delta *self);
2154
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002155static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002156delta_hash(PyDateTime_Delta *self)
2157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 if (self->hashcode == -1) {
2159 PyObject *temp = delta_getstate(self);
2160 if (temp != NULL) {
2161 self->hashcode = PyObject_Hash(temp);
2162 Py_DECREF(temp);
2163 }
2164 }
2165 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002166}
2167
2168static PyObject *
2169delta_multiply(PyObject *left, PyObject *right)
2170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 if (PyDelta_Check(left)) {
2174 /* delta * ??? */
2175 if (PyLong_Check(right))
2176 result = multiply_int_timedelta(right,
2177 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002178 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002179 result = multiply_truedivide_timedelta_float(
2180 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 }
2182 else if (PyLong_Check(left))
2183 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002184 (PyDateTime_Delta *) right);
2185 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002186 result = multiply_truedivide_timedelta_float(
2187 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 if (result == Py_NotImplemented)
2190 Py_INCREF(result);
2191 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002192}
2193
2194static PyObject *
2195delta_divide(PyObject *left, PyObject *right)
2196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 if (PyDelta_Check(left)) {
2200 /* delta * ??? */
2201 if (PyLong_Check(right))
2202 result = divide_timedelta_int(
2203 (PyDateTime_Delta *)left,
2204 right);
2205 else if (PyDelta_Check(right))
2206 result = divide_timedelta_timedelta(
2207 (PyDateTime_Delta *)left,
2208 (PyDateTime_Delta *)right);
2209 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002211 if (result == Py_NotImplemented)
2212 Py_INCREF(result);
2213 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002214}
2215
Mark Dickinson7c186e22010-04-20 22:32:49 +00002216static PyObject *
2217delta_truedivide(PyObject *left, PyObject *right)
2218{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002221 if (PyDelta_Check(left)) {
2222 if (PyDelta_Check(right))
2223 result = truedivide_timedelta_timedelta(
2224 (PyDateTime_Delta *)left,
2225 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002226 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002227 result = multiply_truedivide_timedelta_float(
2228 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002229 else if (PyLong_Check(right))
2230 result = truedivide_timedelta_int(
2231 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 if (result == Py_NotImplemented)
2235 Py_INCREF(result);
2236 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002237}
2238
2239static PyObject *
2240delta_remainder(PyObject *left, PyObject *right)
2241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002242 PyObject *pyus_left;
2243 PyObject *pyus_right;
2244 PyObject *pyus_remainder;
2245 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002246
Brian Curtindfc80e32011-08-10 20:28:54 -05002247 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2248 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2251 if (pyus_left == NULL)
2252 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2255 if (pyus_right == NULL) {
2256 Py_DECREF(pyus_left);
2257 return NULL;
2258 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2261 Py_DECREF(pyus_left);
2262 Py_DECREF(pyus_right);
2263 if (pyus_remainder == NULL)
2264 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 remainder = microseconds_to_delta(pyus_remainder);
2267 Py_DECREF(pyus_remainder);
2268 if (remainder == NULL)
2269 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002272}
2273
2274static PyObject *
2275delta_divmod(PyObject *left, PyObject *right)
2276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 PyObject *pyus_left;
2278 PyObject *pyus_right;
2279 PyObject *divmod;
2280 PyObject *delta;
2281 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002282
Brian Curtindfc80e32011-08-10 20:28:54 -05002283 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2284 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2287 if (pyus_left == NULL)
2288 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2291 if (pyus_right == NULL) {
2292 Py_DECREF(pyus_left);
2293 return NULL;
2294 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002295
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08002296 divmod = checked_divmod(pyus_left, pyus_right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002297 Py_DECREF(pyus_left);
2298 Py_DECREF(pyus_right);
2299 if (divmod == NULL)
2300 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2303 if (delta == NULL) {
2304 Py_DECREF(divmod);
2305 return NULL;
2306 }
2307 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2308 Py_DECREF(delta);
2309 Py_DECREF(divmod);
2310 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002311}
2312
Tim Peters2a799bf2002-12-16 20:18:38 +00002313/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2314 * timedelta constructor. sofar is the # of microseconds accounted for
2315 * so far, and there are factor microseconds per current unit, the number
2316 * of which is given by num. num * factor is added to sofar in a
2317 * numerically careful way, and that's the result. Any fractional
2318 * microseconds left over (this can happen if num is a float type) are
2319 * added into *leftover.
2320 * Note that there are many ways this can give an error (NULL) return.
2321 */
2322static PyObject *
2323accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2324 double *leftover)
2325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002326 PyObject *prod;
2327 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002329 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002331 if (PyLong_Check(num)) {
Miss Islington (bot)d57ab8a2018-11-20 10:59:12 -08002332 prod = PyNumber_Multiply(num, factor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002333 if (prod == NULL)
2334 return NULL;
2335 sum = PyNumber_Add(sofar, prod);
2336 Py_DECREF(prod);
2337 return sum;
2338 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002340 if (PyFloat_Check(num)) {
2341 double dnum;
2342 double fracpart;
2343 double intpart;
2344 PyObject *x;
2345 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 /* The Plan: decompose num into an integer part and a
2348 * fractional part, num = intpart + fracpart.
2349 * Then num * factor ==
2350 * intpart * factor + fracpart * factor
2351 * and the LHS can be computed exactly in long arithmetic.
2352 * The RHS is again broken into an int part and frac part.
2353 * and the frac part is added into *leftover.
2354 */
2355 dnum = PyFloat_AsDouble(num);
2356 if (dnum == -1.0 && PyErr_Occurred())
2357 return NULL;
2358 fracpart = modf(dnum, &intpart);
2359 x = PyLong_FromDouble(intpart);
2360 if (x == NULL)
2361 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 prod = PyNumber_Multiply(x, factor);
2364 Py_DECREF(x);
2365 if (prod == NULL)
2366 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 sum = PyNumber_Add(sofar, prod);
2369 Py_DECREF(prod);
2370 if (sum == NULL)
2371 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 if (fracpart == 0.0)
2374 return sum;
2375 /* So far we've lost no information. Dealing with the
2376 * fractional part requires float arithmetic, and may
2377 * lose a little info.
2378 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002379 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 dnum *= fracpart;
2383 fracpart = modf(dnum, &intpart);
2384 x = PyLong_FromDouble(intpart);
2385 if (x == NULL) {
2386 Py_DECREF(sum);
2387 return NULL;
2388 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 y = PyNumber_Add(sum, x);
2391 Py_DECREF(sum);
2392 Py_DECREF(x);
2393 *leftover += fracpart;
2394 return y;
2395 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 PyErr_Format(PyExc_TypeError,
2398 "unsupported type for timedelta %s component: %s",
2399 tag, Py_TYPE(num)->tp_name);
2400 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002401}
2402
2403static PyObject *
2404delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 /* Argument objects. */
2409 PyObject *day = NULL;
2410 PyObject *second = NULL;
2411 PyObject *us = NULL;
2412 PyObject *ms = NULL;
2413 PyObject *minute = NULL;
2414 PyObject *hour = NULL;
2415 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 PyObject *x = NULL; /* running sum of microseconds */
2418 PyObject *y = NULL; /* temp sum of microseconds */
2419 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 static char *keywords[] = {
2422 "days", "seconds", "microseconds", "milliseconds",
2423 "minutes", "hours", "weeks", NULL
2424 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2427 keywords,
2428 &day, &second, &us,
2429 &ms, &minute, &hour, &week) == 0)
2430 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 x = PyLong_FromLong(0);
2433 if (x == NULL)
2434 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436#define CLEANUP \
2437 Py_DECREF(x); \
2438 x = y; \
2439 if (x == NULL) \
2440 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002443 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 CLEANUP;
2445 }
2446 if (ms) {
2447 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2448 CLEANUP;
2449 }
2450 if (second) {
2451 y = accum("seconds", x, second, us_per_second, &leftover_us);
2452 CLEANUP;
2453 }
2454 if (minute) {
2455 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2456 CLEANUP;
2457 }
2458 if (hour) {
2459 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2460 CLEANUP;
2461 }
2462 if (day) {
2463 y = accum("days", x, day, us_per_day, &leftover_us);
2464 CLEANUP;
2465 }
2466 if (week) {
2467 y = accum("weeks", x, week, us_per_week, &leftover_us);
2468 CLEANUP;
2469 }
2470 if (leftover_us) {
2471 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002472 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002473 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002474 PyObject *temp;
2475
Victor Stinner69cc4872015-09-08 23:58:54 +02002476 whole_us = round(leftover_us);
2477 if (fabs(whole_us - leftover_us) == 0.5) {
2478 /* We're exactly halfway between two integers. In order
2479 * to do round-half-to-even, we must determine whether x
2480 * is odd. Note that x is odd when it's last bit is 1. The
2481 * code below uses bitwise and operation to check the last
2482 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002483 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002484 if (temp == NULL) {
2485 Py_DECREF(x);
2486 goto Done;
2487 }
2488 x_is_odd = PyObject_IsTrue(temp);
2489 Py_DECREF(temp);
2490 if (x_is_odd == -1) {
2491 Py_DECREF(x);
2492 goto Done;
2493 }
2494 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2495 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002496
Victor Stinner36a5a062013-08-28 01:53:39 +02002497 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 if (temp == NULL) {
2500 Py_DECREF(x);
2501 goto Done;
2502 }
2503 y = PyNumber_Add(x, temp);
2504 Py_DECREF(temp);
2505 CLEANUP;
2506 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002508 self = microseconds_to_delta_ex(x, type);
2509 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002510Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002512
2513#undef CLEANUP
2514}
2515
2516static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002517delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 return (GET_TD_DAYS(self) != 0
2520 || GET_TD_SECONDS(self) != 0
2521 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002522}
2523
2524static PyObject *
2525delta_repr(PyDateTime_Delta *self)
2526{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002527 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002528
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002529 if (args == NULL) {
2530 return NULL;
2531 }
2532
2533 const char *sep = "";
2534
2535 if (GET_TD_DAYS(self) != 0) {
2536 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2537 if (args == NULL) {
2538 return NULL;
2539 }
2540 sep = ", ";
2541 }
2542
2543 if (GET_TD_SECONDS(self) != 0) {
2544 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2545 GET_TD_SECONDS(self)));
2546 if (args == NULL) {
2547 return NULL;
2548 }
2549 sep = ", ";
2550 }
2551
2552 if (GET_TD_MICROSECONDS(self) != 0) {
2553 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2554 GET_TD_MICROSECONDS(self)));
2555 if (args == NULL) {
2556 return NULL;
2557 }
2558 }
2559
2560 if (PyUnicode_GET_LENGTH(args) == 0) {
2561 Py_SETREF(args, PyUnicode_FromString("0"));
2562 if (args == NULL) {
2563 return NULL;
2564 }
2565 }
2566
2567 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2568 args);
2569 Py_DECREF(args);
2570 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002571}
2572
2573static PyObject *
2574delta_str(PyDateTime_Delta *self)
2575{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002576 int us = GET_TD_MICROSECONDS(self);
2577 int seconds = GET_TD_SECONDS(self);
2578 int minutes = divmod(seconds, 60, &seconds);
2579 int hours = divmod(minutes, 60, &minutes);
2580 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002582 if (days) {
2583 if (us)
2584 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2585 days, (days == 1 || days == -1) ? "" : "s",
2586 hours, minutes, seconds, us);
2587 else
2588 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2589 days, (days == 1 || days == -1) ? "" : "s",
2590 hours, minutes, seconds);
2591 } else {
2592 if (us)
2593 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2594 hours, minutes, seconds, us);
2595 else
2596 return PyUnicode_FromFormat("%d:%02d:%02d",
2597 hours, minutes, seconds);
2598 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002599
Tim Peters2a799bf2002-12-16 20:18:38 +00002600}
2601
Tim Peters371935f2003-02-01 01:52:50 +00002602/* Pickle support, a simple use of __reduce__. */
2603
Tim Petersb57f8f02003-02-01 02:54:15 +00002604/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002605static PyObject *
2606delta_getstate(PyDateTime_Delta *self)
2607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 return Py_BuildValue("iii", GET_TD_DAYS(self),
2609 GET_TD_SECONDS(self),
2610 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002611}
2612
Tim Peters2a799bf2002-12-16 20:18:38 +00002613static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002614delta_total_seconds(PyObject *self)
2615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 PyObject *total_seconds;
2617 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002619 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2620 if (total_microseconds == NULL)
2621 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002622
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002623 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002626 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002627}
2628
2629static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002630delta_reduce(PyDateTime_Delta* self)
2631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002632 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002633}
2634
2635#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2636
2637static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 {"days", T_INT, OFFSET(days), READONLY,
2640 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 {"seconds", T_INT, OFFSET(seconds), READONLY,
2643 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002645 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2646 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2647 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002648};
2649
2650static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002651 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2652 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2655 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002657 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002658};
2659
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002660static const char delta_doc[] =
Miss Islington (bot)ef7f29f2018-10-19 16:02:13 -07002661PyDoc_STR("Difference between two datetime values.\n\n"
2662 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2663 "minutes=0, hours=0, weeks=0)\n\n"
2664 "All arguments are optional and default to 0.\n"
2665 "Arguments may be integers or floats, and may be positive or negative.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002666
2667static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002668 delta_add, /* nb_add */
2669 delta_subtract, /* nb_subtract */
2670 delta_multiply, /* nb_multiply */
2671 delta_remainder, /* nb_remainder */
2672 delta_divmod, /* nb_divmod */
2673 0, /* nb_power */
2674 (unaryfunc)delta_negative, /* nb_negative */
2675 (unaryfunc)delta_positive, /* nb_positive */
2676 (unaryfunc)delta_abs, /* nb_absolute */
2677 (inquiry)delta_bool, /* nb_bool */
2678 0, /*nb_invert*/
2679 0, /*nb_lshift*/
2680 0, /*nb_rshift*/
2681 0, /*nb_and*/
2682 0, /*nb_xor*/
2683 0, /*nb_or*/
2684 0, /*nb_int*/
2685 0, /*nb_reserved*/
2686 0, /*nb_float*/
2687 0, /*nb_inplace_add*/
2688 0, /*nb_inplace_subtract*/
2689 0, /*nb_inplace_multiply*/
2690 0, /*nb_inplace_remainder*/
2691 0, /*nb_inplace_power*/
2692 0, /*nb_inplace_lshift*/
2693 0, /*nb_inplace_rshift*/
2694 0, /*nb_inplace_and*/
2695 0, /*nb_inplace_xor*/
2696 0, /*nb_inplace_or*/
2697 delta_divide, /* nb_floor_divide */
2698 delta_truedivide, /* nb_true_divide */
2699 0, /* nb_inplace_floor_divide */
2700 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002701};
2702
2703static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002704 PyVarObject_HEAD_INIT(NULL, 0)
2705 "datetime.timedelta", /* tp_name */
2706 sizeof(PyDateTime_Delta), /* tp_basicsize */
2707 0, /* tp_itemsize */
2708 0, /* tp_dealloc */
2709 0, /* tp_print */
2710 0, /* tp_getattr */
2711 0, /* tp_setattr */
2712 0, /* tp_reserved */
2713 (reprfunc)delta_repr, /* tp_repr */
2714 &delta_as_number, /* tp_as_number */
2715 0, /* tp_as_sequence */
2716 0, /* tp_as_mapping */
2717 (hashfunc)delta_hash, /* tp_hash */
2718 0, /* tp_call */
2719 (reprfunc)delta_str, /* tp_str */
2720 PyObject_GenericGetAttr, /* tp_getattro */
2721 0, /* tp_setattro */
2722 0, /* tp_as_buffer */
2723 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2724 delta_doc, /* tp_doc */
2725 0, /* tp_traverse */
2726 0, /* tp_clear */
2727 delta_richcompare, /* tp_richcompare */
2728 0, /* tp_weaklistoffset */
2729 0, /* tp_iter */
2730 0, /* tp_iternext */
2731 delta_methods, /* tp_methods */
2732 delta_members, /* tp_members */
2733 0, /* tp_getset */
2734 0, /* tp_base */
2735 0, /* tp_dict */
2736 0, /* tp_descr_get */
2737 0, /* tp_descr_set */
2738 0, /* tp_dictoffset */
2739 0, /* tp_init */
2740 0, /* tp_alloc */
2741 delta_new, /* tp_new */
2742 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002743};
2744
2745/*
2746 * PyDateTime_Date implementation.
2747 */
2748
2749/* Accessor properties. */
2750
2751static PyObject *
2752date_year(PyDateTime_Date *self, void *unused)
2753{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002754 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002755}
2756
2757static PyObject *
2758date_month(PyDateTime_Date *self, void *unused)
2759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002760 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002761}
2762
2763static PyObject *
2764date_day(PyDateTime_Date *self, void *unused)
2765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002766 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002767}
2768
2769static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002770 {"year", (getter)date_year},
2771 {"month", (getter)date_month},
2772 {"day", (getter)date_day},
2773 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002774};
2775
2776/* Constructors. */
2777
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002778static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002779
Tim Peters2a799bf2002-12-16 20:18:38 +00002780static PyObject *
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02002781date_from_pickle(PyTypeObject *type, PyObject *state)
2782{
2783 PyDateTime_Date *me;
2784
2785 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2786 if (me != NULL) {
2787 const char *pdata = PyBytes_AS_STRING(state);
2788 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2789 me->hashcode = -1;
2790 }
2791 return (PyObject *)me;
2792}
2793
2794static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002795date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2796{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002797 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002798 int year;
2799 int month;
2800 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002802 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02002803 if (PyTuple_GET_SIZE(args) == 1) {
2804 PyObject *state = PyTuple_GET_ITEM(args, 0);
2805 if (PyBytes_Check(state)) {
2806 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2807 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2808 {
2809 return date_from_pickle(type, state);
2810 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002811 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02002812 else if (PyUnicode_Check(state)) {
2813 if (PyUnicode_READY(state)) {
2814 return NULL;
2815 }
2816 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE &&
2817 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2)))
2818 {
2819 state = PyUnicode_AsLatin1String(state);
2820 if (state == NULL) {
2821 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
2822 /* More informative error message. */
2823 PyErr_SetString(PyExc_ValueError,
2824 "Failed to encode latin1 string when unpickling "
2825 "a date object. "
2826 "pickle.load(data, encoding='latin1') is assumed.");
2827 }
2828 return NULL;
2829 }
2830 self = date_from_pickle(type, state);
2831 Py_DECREF(state);
2832 return self;
2833 }
2834 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002835 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2838 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002839 self = new_date_ex(year, month, day, type);
2840 }
2841 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002842}
2843
2844/* Return new date from localtime(t). */
2845static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002846date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002847{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002848 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002850
Victor Stinnere4a994d2015-03-30 01:10:14 +02002851 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002852 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002853
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002854 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002855 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002856
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002857 return new_date_subclass_ex(tm.tm_year + 1900,
2858 tm.tm_mon + 1,
2859 tm.tm_mday,
2860 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002861}
2862
2863/* Return new date from current time.
2864 * We say this is equivalent to fromtimestamp(time.time()), and the
2865 * only way to be sure of that is to *call* time.time(). That's not
2866 * generally the same as calling C's time.
2867 */
2868static PyObject *
2869date_today(PyObject *cls, PyObject *dummy)
2870{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002871 PyObject *time;
2872 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002873 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 time = time_time();
2876 if (time == NULL)
2877 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002879 /* Note well: today() is a class method, so this may not call
2880 * date.fromtimestamp. For example, it may call
2881 * datetime.fromtimestamp. That's why we need all the accuracy
2882 * time.time() delivers; if someone were gonzo about optimization,
2883 * date.today() could get away with plain C time().
2884 */
Victor Stinner20401de2016-12-09 15:24:31 +01002885 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2886 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002887 Py_DECREF(time);
2888 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002889}
2890
2891/* Return new date from given timestamp (Python timestamp -- a double). */
2892static PyObject *
2893date_fromtimestamp(PyObject *cls, PyObject *args)
2894{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002895 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002896 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002897
Victor Stinner5d272cc2012-03-13 13:35:55 +01002898 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2899 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002900 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002901}
2902
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002903
Tim Peters2a799bf2002-12-16 20:18:38 +00002904/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2905 * the ordinal is out of range.
2906 */
2907static PyObject *
2908date_fromordinal(PyObject *cls, PyObject *args)
2909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002910 PyObject *result = NULL;
2911 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002913 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2914 int year;
2915 int month;
2916 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002918 if (ordinal < 1)
2919 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2920 ">= 1");
2921 else {
2922 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002923 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002924 }
2925 }
2926 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002927}
2928
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002929/* Return the new date from a string as generated by date.isoformat() */
2930static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002931date_fromisoformat(PyObject *cls, PyObject *dtstr)
2932{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002933 assert(dtstr != NULL);
2934
2935 if (!PyUnicode_Check(dtstr)) {
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002936 PyErr_SetString(PyExc_TypeError,
2937 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002938 return NULL;
2939 }
2940
2941 Py_ssize_t len;
2942
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002943 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002944 if (dt_ptr == NULL) {
2945 goto invalid_string_error;
2946 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002947
2948 int year = 0, month = 0, day = 0;
2949
2950 int rv;
2951 if (len == 10) {
2952 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002953 }
2954 else {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002955 rv = -1;
2956 }
2957
2958 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002959 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002960 }
2961
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002962 return new_date_subclass_ex(year, month, day, cls);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002963
2964invalid_string_error:
Miss Islington (bot)18450be2018-10-22 15:35:15 -07002965 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002966 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002967}
2968
Tim Peters2a799bf2002-12-16 20:18:38 +00002969/*
2970 * Date arithmetic.
2971 */
2972
2973/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2974 * instead.
2975 */
2976static PyObject *
2977add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2978{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002979 PyObject *result = NULL;
2980 int year = GET_YEAR(date);
2981 int month = GET_MONTH(date);
2982 int deltadays = GET_TD_DAYS(delta);
2983 /* C-level overflow is impossible because |deltadays| < 1e9. */
2984 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002986 if (normalize_date(&year, &month, &day) >= 0)
2987 result = new_date(year, month, day);
2988 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002989}
2990
2991static PyObject *
2992date_add(PyObject *left, PyObject *right)
2993{
Brian Curtindfc80e32011-08-10 20:28:54 -05002994 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2995 Py_RETURN_NOTIMPLEMENTED;
2996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002997 if (PyDate_Check(left)) {
2998 /* date + ??? */
2999 if (PyDelta_Check(right))
3000 /* date + delta */
3001 return add_date_timedelta((PyDateTime_Date *) left,
3002 (PyDateTime_Delta *) right,
3003 0);
3004 }
3005 else {
3006 /* ??? + date
3007 * 'right' must be one of us, or we wouldn't have been called
3008 */
3009 if (PyDelta_Check(left))
3010 /* delta + date */
3011 return add_date_timedelta((PyDateTime_Date *) right,
3012 (PyDateTime_Delta *) left,
3013 0);
3014 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003015 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003016}
3017
3018static PyObject *
3019date_subtract(PyObject *left, PyObject *right)
3020{
Brian Curtindfc80e32011-08-10 20:28:54 -05003021 if (PyDateTime_Check(left) || PyDateTime_Check(right))
3022 Py_RETURN_NOTIMPLEMENTED;
3023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003024 if (PyDate_Check(left)) {
3025 if (PyDate_Check(right)) {
3026 /* date - date */
3027 int left_ord = ymd_to_ord(GET_YEAR(left),
3028 GET_MONTH(left),
3029 GET_DAY(left));
3030 int right_ord = ymd_to_ord(GET_YEAR(right),
3031 GET_MONTH(right),
3032 GET_DAY(right));
3033 return new_delta(left_ord - right_ord, 0, 0, 0);
3034 }
3035 if (PyDelta_Check(right)) {
3036 /* date - delta */
3037 return add_date_timedelta((PyDateTime_Date *) left,
3038 (PyDateTime_Delta *) right,
3039 1);
3040 }
3041 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003042 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003043}
3044
3045
3046/* Various ways to turn a date into a string. */
3047
3048static PyObject *
3049date_repr(PyDateTime_Date *self)
3050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003051 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3052 Py_TYPE(self)->tp_name,
3053 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003054}
3055
3056static PyObject *
3057date_isoformat(PyDateTime_Date *self)
3058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003059 return PyUnicode_FromFormat("%04d-%02d-%02d",
3060 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003061}
3062
Tim Peterse2df5ff2003-05-02 18:39:55 +00003063/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003064static PyObject *
3065date_str(PyDateTime_Date *self)
3066{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003067 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003068}
3069
3070
3071static PyObject *
3072date_ctime(PyDateTime_Date *self)
3073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003074 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003075}
3076
3077static PyObject *
3078date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003080 /* This method can be inherited, and needs to call the
3081 * timetuple() method appropriate to self's class.
3082 */
3083 PyObject *result;
3084 PyObject *tuple;
3085 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003086 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003087 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003089 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3090 &format))
3091 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003092
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003093 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003094 if (tuple == NULL)
3095 return NULL;
3096 result = wrap_strftime((PyObject *)self, format, tuple,
3097 (PyObject *)self);
3098 Py_DECREF(tuple);
3099 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003100}
3101
Eric Smith1ba31142007-09-11 18:06:02 +00003102static PyObject *
3103date_format(PyDateTime_Date *self, PyObject *args)
3104{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003105 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003107 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3108 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003111 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003112 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003113
Victor Stinner20401de2016-12-09 15:24:31 +01003114 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3115 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003116}
3117
Tim Peters2a799bf2002-12-16 20:18:38 +00003118/* ISO methods. */
3119
3120static PyObject *
3121date_isoweekday(PyDateTime_Date *self)
3122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003123 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003126}
3127
3128static PyObject *
3129date_isocalendar(PyDateTime_Date *self)
3130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003131 int year = GET_YEAR(self);
3132 int week1_monday = iso_week1_monday(year);
3133 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3134 int week;
3135 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003137 week = divmod(today - week1_monday, 7, &day);
3138 if (week < 0) {
3139 --year;
3140 week1_monday = iso_week1_monday(year);
3141 week = divmod(today - week1_monday, 7, &day);
3142 }
3143 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3144 ++year;
3145 week = 0;
3146 }
3147 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003148}
3149
3150/* Miscellaneous methods. */
3151
Tim Peters2a799bf2002-12-16 20:18:38 +00003152static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003153date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003155 if (PyDate_Check(other)) {
3156 int diff = memcmp(((PyDateTime_Date *)self)->data,
3157 ((PyDateTime_Date *)other)->data,
3158 _PyDateTime_DATE_DATASIZE);
3159 return diff_to_bool(diff, op);
3160 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003161 else
3162 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003163}
3164
3165static PyObject *
3166date_timetuple(PyDateTime_Date *self)
3167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003168 return build_struct_time(GET_YEAR(self),
3169 GET_MONTH(self),
3170 GET_DAY(self),
3171 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003172}
3173
Tim Peters12bf3392002-12-24 05:41:27 +00003174static PyObject *
3175date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003177 PyObject *clone;
3178 PyObject *tuple;
3179 int year = GET_YEAR(self);
3180 int month = GET_MONTH(self);
3181 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003183 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3184 &year, &month, &day))
3185 return NULL;
3186 tuple = Py_BuildValue("iii", year, month, day);
3187 if (tuple == NULL)
3188 return NULL;
3189 clone = date_new(Py_TYPE(self), tuple, NULL);
3190 Py_DECREF(tuple);
3191 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003192}
3193
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003194static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003195generic_hash(unsigned char *data, int len)
3196{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003197 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003198}
3199
3200
3201static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003202
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003203static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003204date_hash(PyDateTime_Date *self)
3205{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003206 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003207 self->hashcode = generic_hash(
3208 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003209 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003211 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003212}
3213
3214static PyObject *
3215date_toordinal(PyDateTime_Date *self)
3216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3218 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003219}
3220
3221static PyObject *
3222date_weekday(PyDateTime_Date *self)
3223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003224 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003226 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003227}
3228
Tim Peters371935f2003-02-01 01:52:50 +00003229/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003230
Tim Petersb57f8f02003-02-01 02:54:15 +00003231/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003232static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003233date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003235 PyObject* field;
3236 field = PyBytes_FromStringAndSize((char*)self->data,
3237 _PyDateTime_DATE_DATASIZE);
3238 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003239}
3240
3241static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003242date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003244 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003245}
3246
3247static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003249 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00003250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003251 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
3252 METH_CLASS,
3253 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
3254 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003256 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3257 METH_CLASS,
3258 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3259 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003260
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003261 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3262 METH_CLASS,
3263 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003265 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3266 PyDoc_STR("Current date or datetime: same as "
3267 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003269 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003271 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3272 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003274 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
3275 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003277 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3278 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003280 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3281 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003283 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3284 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3285 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003287 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3288 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003290 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3291 PyDoc_STR("Return the day of the week represented by the date.\n"
3292 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003294 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3295 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3296 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003298 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3299 PyDoc_STR("Return the day of the week represented by the date.\n"
3300 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003302 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3303 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003305 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3306 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003308 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003309};
3310
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003311static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003312PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003313
3314static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003315 date_add, /* nb_add */
3316 date_subtract, /* nb_subtract */
3317 0, /* nb_multiply */
3318 0, /* nb_remainder */
3319 0, /* nb_divmod */
3320 0, /* nb_power */
3321 0, /* nb_negative */
3322 0, /* nb_positive */
3323 0, /* nb_absolute */
3324 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003325};
3326
3327static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003328 PyVarObject_HEAD_INIT(NULL, 0)
3329 "datetime.date", /* tp_name */
3330 sizeof(PyDateTime_Date), /* tp_basicsize */
3331 0, /* tp_itemsize */
3332 0, /* tp_dealloc */
3333 0, /* tp_print */
3334 0, /* tp_getattr */
3335 0, /* tp_setattr */
3336 0, /* tp_reserved */
3337 (reprfunc)date_repr, /* tp_repr */
3338 &date_as_number, /* tp_as_number */
3339 0, /* tp_as_sequence */
3340 0, /* tp_as_mapping */
3341 (hashfunc)date_hash, /* tp_hash */
3342 0, /* tp_call */
3343 (reprfunc)date_str, /* tp_str */
3344 PyObject_GenericGetAttr, /* tp_getattro */
3345 0, /* tp_setattro */
3346 0, /* tp_as_buffer */
3347 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3348 date_doc, /* tp_doc */
3349 0, /* tp_traverse */
3350 0, /* tp_clear */
3351 date_richcompare, /* tp_richcompare */
3352 0, /* tp_weaklistoffset */
3353 0, /* tp_iter */
3354 0, /* tp_iternext */
3355 date_methods, /* tp_methods */
3356 0, /* tp_members */
3357 date_getset, /* tp_getset */
3358 0, /* tp_base */
3359 0, /* tp_dict */
3360 0, /* tp_descr_get */
3361 0, /* tp_descr_set */
3362 0, /* tp_dictoffset */
3363 0, /* tp_init */
3364 0, /* tp_alloc */
3365 date_new, /* tp_new */
3366 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003367};
3368
3369/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003370 * PyDateTime_TZInfo implementation.
3371 */
3372
3373/* This is a pure abstract base class, so doesn't do anything beyond
3374 * raising NotImplemented exceptions. Real tzinfo classes need
3375 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003376 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003377 * be subclasses of this tzinfo class, which is easy and quick to check).
3378 *
3379 * Note: For reasons having to do with pickling of subclasses, we have
3380 * to allow tzinfo objects to be instantiated. This wasn't an issue
3381 * in the Python implementation (__init__() could raise NotImplementedError
3382 * there without ill effect), but doing so in the C implementation hit a
3383 * brick wall.
3384 */
3385
3386static PyObject *
3387tzinfo_nogo(const char* methodname)
3388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003389 PyErr_Format(PyExc_NotImplementedError,
3390 "a tzinfo subclass must implement %s()",
3391 methodname);
3392 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003393}
3394
3395/* Methods. A subclass must implement these. */
3396
Tim Peters52dcce22003-01-23 16:36:11 +00003397static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003398tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003400 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003401}
3402
Tim Peters52dcce22003-01-23 16:36:11 +00003403static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003404tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003406 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003407}
3408
Tim Peters52dcce22003-01-23 16:36:11 +00003409static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003410tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003412 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003413}
3414
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003415
3416static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3417 PyDateTime_Delta *delta,
3418 int factor);
3419static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3420static PyObject *datetime_dst(PyObject *self, PyObject *);
3421
Tim Peters52dcce22003-01-23 16:36:11 +00003422static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003423tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003424{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003425 PyObject *result = NULL;
3426 PyObject *off = NULL, *dst = NULL;
3427 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003428
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003429 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003430 PyErr_SetString(PyExc_TypeError,
3431 "fromutc: argument must be a datetime");
3432 return NULL;
3433 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003434 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003435 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3436 "is not self");
3437 return NULL;
3438 }
Tim Peters52dcce22003-01-23 16:36:11 +00003439
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003440 off = datetime_utcoffset(dt, NULL);
3441 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003442 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003443 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003444 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3445 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003446 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003447 }
Tim Peters52dcce22003-01-23 16:36:11 +00003448
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003449 dst = datetime_dst(dt, NULL);
3450 if (dst == NULL)
3451 goto Fail;
3452 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003453 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3454 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003455 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003456 }
Tim Peters52dcce22003-01-23 16:36:11 +00003457
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003458 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3459 if (delta == NULL)
3460 goto Fail;
3461 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003462 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003463 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003464
3465 Py_DECREF(dst);
3466 dst = call_dst(GET_DT_TZINFO(dt), result);
3467 if (dst == NULL)
3468 goto Fail;
3469 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003470 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003471 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003472 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003473 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003474 if (result == NULL)
3475 goto Fail;
3476 }
3477 Py_DECREF(delta);
3478 Py_DECREF(dst);
3479 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003480 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003481
3482Inconsistent:
Miss Islington (bot)7beb8c52018-11-05 06:52:58 -08003483 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave "
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003484 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003485
Miss Islington (bot)e86db342018-02-03 17:41:43 -08003486 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003487Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003488 Py_XDECREF(off);
3489 Py_XDECREF(dst);
3490 Py_XDECREF(delta);
3491 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003492 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003493}
3494
Tim Peters2a799bf2002-12-16 20:18:38 +00003495/*
3496 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003497 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003498 */
3499
Guido van Rossum177e41a2003-01-30 22:06:23 +00003500static PyObject *
3501tzinfo_reduce(PyObject *self)
3502{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003503 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003504 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003505 _Py_IDENTIFIER(__getinitargs__);
3506 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003507
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003508 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003509 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003510 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003511 Py_DECREF(getinitargs);
3512 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003513 return NULL;
3514 }
3515 }
3516 else {
3517 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003518
3519 args = PyTuple_New(0);
3520 if (args == NULL) {
3521 return NULL;
3522 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003523 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003524
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003525 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003526 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003527 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003528 Py_DECREF(getstate);
3529 if (state == NULL) {
3530 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003531 return NULL;
3532 }
3533 }
3534 else {
3535 PyObject **dictptr;
3536 PyErr_Clear();
3537 state = Py_None;
3538 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003539 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003540 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003541 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003542 Py_INCREF(state);
3543 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003545 if (state == Py_None) {
3546 Py_DECREF(state);
3547 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3548 }
3549 else
3550 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003551}
Tim Peters2a799bf2002-12-16 20:18:38 +00003552
3553static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3556 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003558 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003559 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3560 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003562 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003563 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003565 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003566 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3569 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003571 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003572};
3573
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003574static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003575PyDoc_STR("Abstract base class for time zone info objects.");
3576
Neal Norwitz227b5332006-03-22 09:28:35 +00003577static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003578 PyVarObject_HEAD_INIT(NULL, 0)
3579 "datetime.tzinfo", /* tp_name */
3580 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3581 0, /* tp_itemsize */
3582 0, /* tp_dealloc */
3583 0, /* tp_print */
3584 0, /* tp_getattr */
3585 0, /* tp_setattr */
3586 0, /* tp_reserved */
3587 0, /* tp_repr */
3588 0, /* tp_as_number */
3589 0, /* tp_as_sequence */
3590 0, /* tp_as_mapping */
3591 0, /* tp_hash */
3592 0, /* tp_call */
3593 0, /* tp_str */
3594 PyObject_GenericGetAttr, /* tp_getattro */
3595 0, /* tp_setattro */
3596 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003597 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003598 tzinfo_doc, /* tp_doc */
3599 0, /* tp_traverse */
3600 0, /* tp_clear */
3601 0, /* tp_richcompare */
3602 0, /* tp_weaklistoffset */
3603 0, /* tp_iter */
3604 0, /* tp_iternext */
3605 tzinfo_methods, /* tp_methods */
3606 0, /* tp_members */
3607 0, /* tp_getset */
3608 0, /* tp_base */
3609 0, /* tp_dict */
3610 0, /* tp_descr_get */
3611 0, /* tp_descr_set */
3612 0, /* tp_dictoffset */
3613 0, /* tp_init */
3614 0, /* tp_alloc */
3615 PyType_GenericNew, /* tp_new */
3616 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003617};
3618
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003619static char *timezone_kws[] = {"offset", "name", NULL};
3620
3621static PyObject *
3622timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3623{
3624 PyObject *offset;
3625 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003626 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3627 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003628 return new_timezone(offset, name);
3629
3630 return NULL;
3631}
3632
3633static void
3634timezone_dealloc(PyDateTime_TimeZone *self)
3635{
3636 Py_CLEAR(self->offset);
3637 Py_CLEAR(self->name);
3638 Py_TYPE(self)->tp_free((PyObject *)self);
3639}
3640
3641static PyObject *
3642timezone_richcompare(PyDateTime_TimeZone *self,
3643 PyDateTime_TimeZone *other, int op)
3644{
Brian Curtindfc80e32011-08-10 20:28:54 -05003645 if (op != Py_EQ && op != Py_NE)
3646 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003647 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003648 if (op == Py_EQ)
3649 Py_RETURN_FALSE;
3650 else
3651 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003652 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003653 return delta_richcompare(self->offset, other->offset, op);
3654}
3655
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003656static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003657timezone_hash(PyDateTime_TimeZone *self)
3658{
3659 return delta_hash((PyDateTime_Delta *)self->offset);
3660}
3661
3662/* Check argument type passed to tzname, utcoffset, or dst methods.
3663 Returns 0 for good argument. Returns -1 and sets exception info
3664 otherwise.
3665 */
3666static int
3667_timezone_check_argument(PyObject *dt, const char *meth)
3668{
3669 if (dt == Py_None || PyDateTime_Check(dt))
3670 return 0;
3671 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3672 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3673 return -1;
3674}
3675
3676static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003677timezone_repr(PyDateTime_TimeZone *self)
3678{
3679 /* Note that although timezone is not subclassable, it is convenient
3680 to use Py_TYPE(self)->tp_name here. */
3681 const char *type_name = Py_TYPE(self)->tp_name;
3682
3683 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3684 return PyUnicode_FromFormat("%s.utc", type_name);
3685
3686 if (self->name == NULL)
3687 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3688
3689 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3690 self->name);
3691}
3692
3693
3694static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003695timezone_str(PyDateTime_TimeZone *self)
3696{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003697 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003698 PyObject *offset;
3699 char sign;
3700
3701 if (self->name != NULL) {
3702 Py_INCREF(self->name);
3703 return self->name;
3704 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003705 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003706 (GET_TD_DAYS(self->offset) == 0 &&
3707 GET_TD_SECONDS(self->offset) == 0 &&
3708 GET_TD_MICROSECONDS(self->offset) == 0))
3709 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003710 /* Offset is normalized, so it is negative if days < 0 */
3711 if (GET_TD_DAYS(self->offset) < 0) {
3712 sign = '-';
3713 offset = delta_negative((PyDateTime_Delta *)self->offset);
3714 if (offset == NULL)
3715 return NULL;
3716 }
3717 else {
3718 sign = '+';
3719 offset = self->offset;
3720 Py_INCREF(offset);
3721 }
3722 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003723 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003724 seconds = GET_TD_SECONDS(offset);
3725 Py_DECREF(offset);
3726 minutes = divmod(seconds, 60, &seconds);
3727 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003728 if (microseconds != 0) {
3729 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3730 sign, hours, minutes,
3731 seconds, microseconds);
3732 }
3733 if (seconds != 0) {
3734 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3735 sign, hours, minutes, seconds);
3736 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003737 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003738}
3739
3740static PyObject *
3741timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3742{
3743 if (_timezone_check_argument(dt, "tzname") == -1)
3744 return NULL;
3745
3746 return timezone_str(self);
3747}
3748
3749static PyObject *
3750timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3751{
3752 if (_timezone_check_argument(dt, "utcoffset") == -1)
3753 return NULL;
3754
3755 Py_INCREF(self->offset);
3756 return self->offset;
3757}
3758
3759static PyObject *
3760timezone_dst(PyObject *self, PyObject *dt)
3761{
3762 if (_timezone_check_argument(dt, "dst") == -1)
3763 return NULL;
3764
3765 Py_RETURN_NONE;
3766}
3767
3768static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003769timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3770{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003771 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003772 PyErr_SetString(PyExc_TypeError,
3773 "fromutc: argument must be a datetime");
3774 return NULL;
3775 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003776 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003777 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3778 "is not self");
3779 return NULL;
3780 }
3781
3782 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3783}
3784
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003785static PyObject *
3786timezone_getinitargs(PyDateTime_TimeZone *self)
3787{
3788 if (self->name == NULL)
3789 return Py_BuildValue("(O)", self->offset);
3790 return Py_BuildValue("(OO)", self->offset, self->name);
3791}
3792
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003793static PyMethodDef timezone_methods[] = {
3794 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3795 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003796 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003797
3798 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003799 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003800
3801 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003802 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003803
3804 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3805 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3806
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003807 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3808 PyDoc_STR("pickle support")},
3809
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003810 {NULL, NULL}
3811};
3812
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003813static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003814PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3815
3816static PyTypeObject PyDateTime_TimeZoneType = {
3817 PyVarObject_HEAD_INIT(NULL, 0)
3818 "datetime.timezone", /* tp_name */
3819 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3820 0, /* tp_itemsize */
3821 (destructor)timezone_dealloc, /* tp_dealloc */
3822 0, /* tp_print */
3823 0, /* tp_getattr */
3824 0, /* tp_setattr */
3825 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003826 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003827 0, /* tp_as_number */
3828 0, /* tp_as_sequence */
3829 0, /* tp_as_mapping */
3830 (hashfunc)timezone_hash, /* tp_hash */
3831 0, /* tp_call */
3832 (reprfunc)timezone_str, /* tp_str */
3833 0, /* tp_getattro */
3834 0, /* tp_setattro */
3835 0, /* tp_as_buffer */
3836 Py_TPFLAGS_DEFAULT, /* tp_flags */
3837 timezone_doc, /* tp_doc */
3838 0, /* tp_traverse */
3839 0, /* tp_clear */
3840 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3841 0, /* tp_weaklistoffset */
3842 0, /* tp_iter */
3843 0, /* tp_iternext */
3844 timezone_methods, /* tp_methods */
3845 0, /* tp_members */
3846 0, /* tp_getset */
3847 &PyDateTime_TZInfoType, /* tp_base */
3848 0, /* tp_dict */
3849 0, /* tp_descr_get */
3850 0, /* tp_descr_set */
3851 0, /* tp_dictoffset */
3852 0, /* tp_init */
3853 0, /* tp_alloc */
3854 timezone_new, /* tp_new */
3855};
3856
Tim Peters2a799bf2002-12-16 20:18:38 +00003857/*
Tim Peters37f39822003-01-10 03:49:02 +00003858 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003859 */
3860
Tim Peters37f39822003-01-10 03:49:02 +00003861/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003862 */
3863
3864static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003865time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003866{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003867 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003868}
3869
Tim Peters37f39822003-01-10 03:49:02 +00003870static PyObject *
3871time_minute(PyDateTime_Time *self, void *unused)
3872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003873 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003874}
3875
3876/* The name time_second conflicted with some platform header file. */
3877static PyObject *
3878py_time_second(PyDateTime_Time *self, void *unused)
3879{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003880 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003881}
3882
3883static PyObject *
3884time_microsecond(PyDateTime_Time *self, void *unused)
3885{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003886 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003887}
3888
3889static PyObject *
3890time_tzinfo(PyDateTime_Time *self, void *unused)
3891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003892 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3893 Py_INCREF(result);
3894 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003895}
3896
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003897static PyObject *
3898time_fold(PyDateTime_Time *self, void *unused)
3899{
3900 return PyLong_FromLong(TIME_GET_FOLD(self));
3901}
3902
Tim Peters37f39822003-01-10 03:49:02 +00003903static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003904 {"hour", (getter)time_hour},
3905 {"minute", (getter)time_minute},
3906 {"second", (getter)py_time_second},
3907 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003908 {"tzinfo", (getter)time_tzinfo},
3909 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003910 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003911};
3912
3913/*
3914 * Constructors.
3915 */
3916
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003917static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003918 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003919
Tim Peters2a799bf2002-12-16 20:18:38 +00003920static PyObject *
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02003921time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
3922{
3923 PyDateTime_Time *me;
3924 char aware = (char)(tzinfo != Py_None);
3925
3926 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
3927 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
3928 return NULL;
3929 }
3930
3931 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3932 if (me != NULL) {
3933 const char *pdata = PyBytes_AS_STRING(state);
3934
3935 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3936 me->hashcode = -1;
3937 me->hastzinfo = aware;
3938 if (aware) {
3939 Py_INCREF(tzinfo);
3940 me->tzinfo = tzinfo;
3941 }
3942 if (pdata[0] & (1 << 7)) {
3943 me->data[0] -= 128;
3944 me->fold = 1;
3945 }
3946 else {
3947 me->fold = 0;
3948 }
3949 }
3950 return (PyObject *)me;
3951}
3952
3953static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003954time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003955{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003956 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003957 int hour = 0;
3958 int minute = 0;
3959 int second = 0;
3960 int usecond = 0;
3961 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003962 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003964 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02003965 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
3966 PyObject *state = PyTuple_GET_ITEM(args, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003967 if (PyTuple_GET_SIZE(args) == 2) {
3968 tzinfo = PyTuple_GET_ITEM(args, 1);
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02003969 }
3970 if (PyBytes_Check(state)) {
3971 if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3972 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
3973 {
3974 return time_from_pickle(type, state, tzinfo);
3975 }
3976 }
3977 else if (PyUnicode_Check(state)) {
3978 if (PyUnicode_READY(state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003979 return NULL;
3980 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02003981 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
3982 (0x7F & PyUnicode_READ_CHAR(state, 2)) < 24)
3983 {
3984 state = PyUnicode_AsLatin1String(state);
3985 if (state == NULL) {
3986 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
3987 /* More informative error message. */
3988 PyErr_SetString(PyExc_ValueError,
3989 "Failed to encode latin1 string when unpickling "
3990 "a time object. "
3991 "pickle.load(data, encoding='latin1') is assumed.");
3992 }
3993 return NULL;
3994 }
3995 self = time_from_pickle(type, state, tzinfo);
3996 Py_DECREF(state);
3997 return self;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003998 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003999 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004000 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004002
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004003 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004005 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004006 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
4007 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004008 }
4009 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004010}
4011
4012/*
4013 * Destructor.
4014 */
4015
4016static void
Tim Peters37f39822003-01-10 03:49:02 +00004017time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004018{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004019 if (HASTZINFO(self)) {
4020 Py_XDECREF(self->tzinfo);
4021 }
4022 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004023}
4024
4025/*
Tim Peters855fe882002-12-22 03:43:39 +00004026 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004027 */
4028
Tim Peters2a799bf2002-12-16 20:18:38 +00004029/* These are all METH_NOARGS, so don't need to check the arglist. */
4030static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004031time_utcoffset(PyObject *self, PyObject *unused) {
4032 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004033}
4034
4035static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004036time_dst(PyObject *self, PyObject *unused) {
4037 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00004038}
4039
4040static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004041time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004042 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004043}
4044
4045/*
Tim Peters37f39822003-01-10 03:49:02 +00004046 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004047 */
4048
4049static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004050time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004051{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004052 const char *type_name = Py_TYPE(self)->tp_name;
4053 int h = TIME_GET_HOUR(self);
4054 int m = TIME_GET_MINUTE(self);
4055 int s = TIME_GET_SECOND(self);
4056 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004057 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004058 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004060 if (us)
4061 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
4062 type_name, h, m, s, us);
4063 else if (s)
4064 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
4065 type_name, h, m, s);
4066 else
4067 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
4068 if (result != NULL && HASTZINFO(self))
4069 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004070 if (result != NULL && fold)
4071 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004072 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004073}
4074
Tim Peters37f39822003-01-10 03:49:02 +00004075static PyObject *
4076time_str(PyDateTime_Time *self)
4077{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07004078 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00004079}
Tim Peters2a799bf2002-12-16 20:18:38 +00004080
4081static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004082time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004084 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004085 char *timespec = NULL;
4086 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004087 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004088 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004089 static char *specs[][2] = {
4090 {"hours", "%02d"},
4091 {"minutes", "%02d:%02d"},
4092 {"seconds", "%02d:%02d:%02d"},
4093 {"milliseconds", "%02d:%02d:%02d.%03d"},
4094 {"microseconds", "%02d:%02d:%02d.%06d"},
4095 };
4096 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004097
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004098 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4099 return NULL;
4100
4101 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4102 if (us == 0) {
4103 /* seconds */
4104 given_spec = 2;
4105 }
4106 else {
4107 /* microseconds */
4108 given_spec = 4;
4109 }
4110 }
4111 else {
4112 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4113 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4114 if (given_spec == 3) {
4115 /* milliseconds */
4116 us = us / 1000;
4117 }
4118 break;
4119 }
4120 }
4121 }
4122
4123 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4124 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4125 return NULL;
4126 }
4127 else {
4128 result = PyUnicode_FromFormat(specs[given_spec][1],
4129 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4130 TIME_GET_SECOND(self), us);
4131 }
Tim Peters37f39822003-01-10 03:49:02 +00004132
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004133 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004134 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004136 /* We need to append the UTC offset. */
4137 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4138 Py_None) < 0) {
4139 Py_DECREF(result);
4140 return NULL;
4141 }
4142 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4143 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004144}
4145
Tim Peters37f39822003-01-10 03:49:02 +00004146static PyObject *
4147time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004149 PyObject *result;
4150 PyObject *tuple;
4151 PyObject *format;
4152 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004154 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4155 &format))
4156 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004158 /* Python's strftime does insane things with the year part of the
4159 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004160 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004161 */
4162 tuple = Py_BuildValue("iiiiiiiii",
4163 1900, 1, 1, /* year, month, day */
4164 TIME_GET_HOUR(self),
4165 TIME_GET_MINUTE(self),
4166 TIME_GET_SECOND(self),
4167 0, 1, -1); /* weekday, daynum, dst */
4168 if (tuple == NULL)
4169 return NULL;
4170 assert(PyTuple_Size(tuple) == 9);
4171 result = wrap_strftime((PyObject *)self, format, tuple,
4172 Py_None);
4173 Py_DECREF(tuple);
4174 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004175}
Tim Peters2a799bf2002-12-16 20:18:38 +00004176
4177/*
4178 * Miscellaneous methods.
4179 */
4180
Tim Peters37f39822003-01-10 03:49:02 +00004181static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004182time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004183{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004184 PyObject *result = NULL;
4185 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004186 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004187
Brian Curtindfc80e32011-08-10 20:28:54 -05004188 if (! PyTime_Check(other))
4189 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004190
4191 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004192 diff = memcmp(((PyDateTime_Time *)self)->data,
4193 ((PyDateTime_Time *)other)->data,
4194 _PyDateTime_TIME_DATASIZE);
4195 return diff_to_bool(diff, op);
4196 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004197 offset1 = time_utcoffset(self, NULL);
4198 if (offset1 == NULL)
4199 return NULL;
4200 offset2 = time_utcoffset(other, NULL);
4201 if (offset2 == NULL)
4202 goto done;
4203 /* If they're both naive, or both aware and have the same offsets,
4204 * we get off cheap. Note that if they're both naive, offset1 ==
4205 * offset2 == Py_None at this point.
4206 */
4207 if ((offset1 == offset2) ||
4208 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4209 delta_cmp(offset1, offset2) == 0)) {
4210 diff = memcmp(((PyDateTime_Time *)self)->data,
4211 ((PyDateTime_Time *)other)->data,
4212 _PyDateTime_TIME_DATASIZE);
4213 result = diff_to_bool(diff, op);
4214 }
4215 /* The hard case: both aware with different UTC offsets */
4216 else if (offset1 != Py_None && offset2 != Py_None) {
4217 int offsecs1, offsecs2;
4218 assert(offset1 != offset2); /* else last "if" handled it */
4219 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4220 TIME_GET_MINUTE(self) * 60 +
4221 TIME_GET_SECOND(self) -
4222 GET_TD_DAYS(offset1) * 86400 -
4223 GET_TD_SECONDS(offset1);
4224 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4225 TIME_GET_MINUTE(other) * 60 +
4226 TIME_GET_SECOND(other) -
4227 GET_TD_DAYS(offset2) * 86400 -
4228 GET_TD_SECONDS(offset2);
4229 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004230 if (diff == 0)
4231 diff = TIME_GET_MICROSECOND(self) -
4232 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004233 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004235 else if (op == Py_EQ) {
4236 result = Py_False;
4237 Py_INCREF(result);
4238 }
4239 else if (op == Py_NE) {
4240 result = Py_True;
4241 Py_INCREF(result);
4242 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004243 else {
4244 PyErr_SetString(PyExc_TypeError,
4245 "can't compare offset-naive and "
4246 "offset-aware times");
4247 }
4248 done:
4249 Py_DECREF(offset1);
4250 Py_XDECREF(offset2);
4251 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004252}
4253
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004254static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004255time_hash(PyDateTime_Time *self)
4256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004257 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004258 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004259 if (TIME_GET_FOLD(self)) {
4260 self0 = new_time_ex2(TIME_GET_HOUR(self),
4261 TIME_GET_MINUTE(self),
4262 TIME_GET_SECOND(self),
4263 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004264 HASTZINFO(self) ? self->tzinfo : Py_None,
4265 0, Py_TYPE(self));
4266 if (self0 == NULL)
4267 return -1;
4268 }
4269 else {
4270 self0 = (PyObject *)self;
4271 Py_INCREF(self0);
4272 }
4273 offset = time_utcoffset(self0, NULL);
4274 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004275
4276 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004277 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004279 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004280 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004281 self->hashcode = generic_hash(
4282 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004283 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004284 PyObject *temp1, *temp2;
4285 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004286 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004287 seconds = TIME_GET_HOUR(self) * 3600 +
4288 TIME_GET_MINUTE(self) * 60 +
4289 TIME_GET_SECOND(self);
4290 microseconds = TIME_GET_MICROSECOND(self);
4291 temp1 = new_delta(0, seconds, microseconds, 1);
4292 if (temp1 == NULL) {
4293 Py_DECREF(offset);
4294 return -1;
4295 }
4296 temp2 = delta_subtract(temp1, offset);
4297 Py_DECREF(temp1);
4298 if (temp2 == NULL) {
4299 Py_DECREF(offset);
4300 return -1;
4301 }
4302 self->hashcode = PyObject_Hash(temp2);
4303 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004304 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004305 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004306 }
4307 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004308}
Tim Peters2a799bf2002-12-16 20:18:38 +00004309
Tim Peters12bf3392002-12-24 05:41:27 +00004310static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004311time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004312{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004313 PyObject *clone;
4314 PyObject *tuple;
4315 int hh = TIME_GET_HOUR(self);
4316 int mm = TIME_GET_MINUTE(self);
4317 int ss = TIME_GET_SECOND(self);
4318 int us = TIME_GET_MICROSECOND(self);
4319 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004320 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004321
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004322 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004323 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004324 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004325 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004326 if (fold != 0 && fold != 1) {
4327 PyErr_SetString(PyExc_ValueError,
4328 "fold must be either 0 or 1");
4329 return NULL;
4330 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004331 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4332 if (tuple == NULL)
4333 return NULL;
4334 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004335 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004336 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004337 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004338 Py_DECREF(tuple);
4339 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004340}
4341
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004342static PyObject *
4343time_fromisoformat(PyObject *cls, PyObject *tstr) {
4344 assert(tstr != NULL);
4345
4346 if (!PyUnicode_Check(tstr)) {
4347 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4348 return NULL;
4349 }
4350
4351 Py_ssize_t len;
4352 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4353
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004354 if (p == NULL) {
4355 goto invalid_string_error;
4356 }
4357
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004358 int hour = 0, minute = 0, second = 0, microsecond = 0;
4359 int tzoffset, tzimicrosecond = 0;
4360 int rv = parse_isoformat_time(p, len,
4361 &hour, &minute, &second, &microsecond,
4362 &tzoffset, &tzimicrosecond);
4363
4364 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004365 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004366 }
4367
4368 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4369 tzimicrosecond);
4370
4371 if (tzinfo == NULL) {
4372 return NULL;
4373 }
4374
4375 PyObject *t;
4376 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4377 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4378 } else {
4379 t = PyObject_CallFunction(cls, "iiiiO",
4380 hour, minute, second, microsecond, tzinfo);
4381 }
4382
4383 Py_DECREF(tzinfo);
4384 return t;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004385
4386invalid_string_error:
4387 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4388 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004389}
4390
4391
Tim Peters371935f2003-02-01 01:52:50 +00004392/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004393
Tim Peters33e0f382003-01-10 02:05:14 +00004394/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004395 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4396 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004397 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004398 */
4399static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004400time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004402 PyObject *basestate;
4403 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004405 basestate = PyBytes_FromStringAndSize((char *)self->data,
4406 _PyDateTime_TIME_DATASIZE);
4407 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004408 if (proto > 3 && TIME_GET_FOLD(self))
4409 /* Set the first bit of the first byte */
4410 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4412 result = PyTuple_Pack(1, basestate);
4413 else
4414 result = PyTuple_Pack(2, basestate, self->tzinfo);
4415 Py_DECREF(basestate);
4416 }
4417 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004418}
4419
4420static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004421time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004422{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004423 int proto;
4424 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004425 return NULL;
4426
4427 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004428}
4429
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004430static PyObject *
4431time_reduce(PyDateTime_Time *self, PyObject *arg)
4432{
4433 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4434}
4435
Tim Peters37f39822003-01-10 03:49:02 +00004436static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004437
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004438 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4439 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4440 "[+HH:MM].\n\n"
4441 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004443 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4444 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004446 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4447 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004449 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4450 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004452 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4453 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004455 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4456 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004458 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4459 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004460
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004461 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4462 PyDoc_STR("string -> time from time.isoformat() output")},
4463
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004464 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004465 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004466
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004467 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4468 PyDoc_STR("__reduce__() -> (cls, state)")},
4469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004470 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004471};
4472
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004473static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004474PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4475\n\
4476All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004477a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004478
Neal Norwitz227b5332006-03-22 09:28:35 +00004479static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004480 PyVarObject_HEAD_INIT(NULL, 0)
4481 "datetime.time", /* tp_name */
4482 sizeof(PyDateTime_Time), /* tp_basicsize */
4483 0, /* tp_itemsize */
4484 (destructor)time_dealloc, /* tp_dealloc */
4485 0, /* tp_print */
4486 0, /* tp_getattr */
4487 0, /* tp_setattr */
4488 0, /* tp_reserved */
4489 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004490 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004491 0, /* tp_as_sequence */
4492 0, /* tp_as_mapping */
4493 (hashfunc)time_hash, /* tp_hash */
4494 0, /* tp_call */
4495 (reprfunc)time_str, /* tp_str */
4496 PyObject_GenericGetAttr, /* tp_getattro */
4497 0, /* tp_setattro */
4498 0, /* tp_as_buffer */
4499 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4500 time_doc, /* tp_doc */
4501 0, /* tp_traverse */
4502 0, /* tp_clear */
4503 time_richcompare, /* tp_richcompare */
4504 0, /* tp_weaklistoffset */
4505 0, /* tp_iter */
4506 0, /* tp_iternext */
4507 time_methods, /* tp_methods */
4508 0, /* tp_members */
4509 time_getset, /* tp_getset */
4510 0, /* tp_base */
4511 0, /* tp_dict */
4512 0, /* tp_descr_get */
4513 0, /* tp_descr_set */
4514 0, /* tp_dictoffset */
4515 0, /* tp_init */
4516 time_alloc, /* tp_alloc */
4517 time_new, /* tp_new */
4518 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004519};
4520
4521/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004522 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004523 */
4524
Tim Petersa9bc1682003-01-11 03:39:11 +00004525/* Accessor properties. Properties for day, month, and year are inherited
4526 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004527 */
4528
4529static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004530datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004532 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004533}
4534
Tim Petersa9bc1682003-01-11 03:39:11 +00004535static PyObject *
4536datetime_minute(PyDateTime_DateTime *self, void *unused)
4537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004538 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004539}
4540
4541static PyObject *
4542datetime_second(PyDateTime_DateTime *self, void *unused)
4543{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004545}
4546
4547static PyObject *
4548datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4549{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004550 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004551}
4552
4553static PyObject *
4554datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004556 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4557 Py_INCREF(result);
4558 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004559}
4560
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004561static PyObject *
4562datetime_fold(PyDateTime_DateTime *self, void *unused)
4563{
4564 return PyLong_FromLong(DATE_GET_FOLD(self));
4565}
4566
Tim Petersa9bc1682003-01-11 03:39:11 +00004567static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004568 {"hour", (getter)datetime_hour},
4569 {"minute", (getter)datetime_minute},
4570 {"second", (getter)datetime_second},
4571 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004572 {"tzinfo", (getter)datetime_tzinfo},
4573 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004574 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004575};
4576
4577/*
4578 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004579 */
4580
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004581static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004582 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004583 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004584};
4585
Tim Peters2a799bf2002-12-16 20:18:38 +00004586static PyObject *
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004587datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo)
4588{
4589 PyDateTime_DateTime *me;
4590 char aware = (char)(tzinfo != Py_None);
4591
4592 if (aware && check_tzinfo_subclass(tzinfo) < 0) {
4593 PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg");
4594 return NULL;
4595 }
4596
4597 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4598 if (me != NULL) {
4599 const char *pdata = PyBytes_AS_STRING(state);
4600
4601 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4602 me->hashcode = -1;
4603 me->hastzinfo = aware;
4604 if (aware) {
4605 Py_INCREF(tzinfo);
4606 me->tzinfo = tzinfo;
4607 }
4608 if (pdata[2] & (1 << 7)) {
4609 me->data[2] -= 128;
4610 me->fold = 1;
4611 }
4612 else {
4613 me->fold = 0;
4614 }
4615 }
4616 return (PyObject *)me;
4617}
4618
4619static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004620datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004622 PyObject *self = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004623 int year;
4624 int month;
4625 int day;
4626 int hour = 0;
4627 int minute = 0;
4628 int second = 0;
4629 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004630 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004633 /* Check for invocation from pickle with __getstate__ state */
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004634 if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) {
4635 PyObject *state = PyTuple_GET_ITEM(args, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004636 if (PyTuple_GET_SIZE(args) == 2) {
4637 tzinfo = PyTuple_GET_ITEM(args, 1);
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004638 }
4639 if (PyBytes_Check(state)) {
4640 if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4641 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4642 {
4643 return datetime_from_pickle(type, state, tzinfo);
4644 }
4645 }
4646 else if (PyUnicode_Check(state)) {
4647 if (PyUnicode_READY(state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004648 return NULL;
4649 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004650 if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE &&
4651 MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F))
4652 {
4653 state = PyUnicode_AsLatin1String(state);
4654 if (state == NULL) {
4655 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
4656 /* More informative error message. */
4657 PyErr_SetString(PyExc_ValueError,
4658 "Failed to encode latin1 string when unpickling "
4659 "a datetime object. "
4660 "pickle.load(data, encoding='latin1') is assumed.");
4661 }
4662 return NULL;
4663 }
4664 self = datetime_from_pickle(type, state, tzinfo);
4665 Py_DECREF(state);
4666 return self;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004667 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004668 }
Serhiy Storchaka0d5730e2018-12-07 14:56:02 +02004669 tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004670 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004671
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004672 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004673 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004674 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004675 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004676 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004677 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004678 }
4679 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004680}
4681
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004682/* TM_FUNC is the shared type of _PyTime_localtime() and
4683 * _PyTime_gmtime(). */
4684typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004685
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004686/* As of version 2015f max fold in IANA database is
4687 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004688static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004689/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004690static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004691
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004692static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004693utc_to_seconds(int year, int month, int day,
4694 int hour, int minute, int second)
4695{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004696 long long ordinal;
4697
4698 /* ymd_to_ord() doesn't support year <= 0 */
4699 if (year < MINYEAR || year > MAXYEAR) {
4700 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4701 return -1;
4702 }
4703
4704 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004705 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4706}
4707
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004708static long long
4709local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004710{
4711 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004712 time_t t;
4713 u -= epoch;
4714 t = u;
4715 if (t != u) {
4716 PyErr_SetString(PyExc_OverflowError,
4717 "timestamp out of range for platform time_t");
4718 return -1;
4719 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004720 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004721 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004722 return utc_to_seconds(local_time.tm_year + 1900,
4723 local_time.tm_mon + 1,
4724 local_time.tm_mday,
4725 local_time.tm_hour,
4726 local_time.tm_min,
4727 local_time.tm_sec);
4728}
4729
Tim Petersa9bc1682003-01-11 03:39:11 +00004730/* Internal helper.
4731 * Build datetime from a time_t and a distinct count of microseconds.
4732 * Pass localtime or gmtime for f, to control the interpretation of timet.
4733 */
4734static PyObject *
4735datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004736 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004737{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004738 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004739 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004740
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004741 if (f(timet, &tm) != 0)
4742 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004743
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004744 year = tm.tm_year + 1900;
4745 month = tm.tm_mon + 1;
4746 day = tm.tm_mday;
4747 hour = tm.tm_hour;
4748 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004749 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004750 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004751 * except to the extent that passing them on to the datetime
4752 * constructor would raise ValueError for a reason that
4753 * made no sense to the user.
4754 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004755 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004756
Victor Stinnerb67f0962017-02-10 10:34:02 +01004757 /* local timezone requires to compute fold */
Miss Islington (bot)97364932018-07-25 13:34:09 -07004758 if (tzinfo == Py_None && f == _PyTime_localtime
4759 /* On Windows, passing a negative value to local results
4760 * in an OSError because localtime_s on Windows does
4761 * not support negative timestamps. Unfortunately this
4762 * means that fold detection for time values between
4763 * 0 and max_fold_seconds will result in an identical
4764 * error since we subtract max_fold_seconds to detect a
4765 * fold. However, since we know there haven't been any
4766 * folds in the interval [0, max_fold_seconds) in any
4767 * timezone, we can hackily just forego fold detection
4768 * for this time range.
4769 */
4770#ifdef MS_WINDOWS
4771 && (timet - max_fold_seconds > 0)
4772#endif
4773 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004774 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004775
4776 result_seconds = utc_to_seconds(year, month, day,
4777 hour, minute, second);
4778 /* Probe max_fold_seconds to detect a fold. */
4779 probe_seconds = local(epoch + timet - max_fold_seconds);
4780 if (probe_seconds == -1)
4781 return NULL;
4782 transition = result_seconds - probe_seconds - max_fold_seconds;
4783 if (transition < 0) {
4784 probe_seconds = local(epoch + timet + transition);
4785 if (probe_seconds == -1)
4786 return NULL;
4787 if (probe_seconds == result_seconds)
4788 fold = 1;
4789 }
4790 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004791 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4792 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004793}
4794
4795/* Internal helper.
4796 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4797 * to control the interpretation of the timestamp. Since a double doesn't
4798 * have enough bits to cover a datetime's full range of precision, it's
4799 * better to call datetime_from_timet_and_us provided you have a way
4800 * to get that much precision (e.g., C time() isn't good enough).
4801 */
4802static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004803datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004804 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004805{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004806 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004807 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004808
Victor Stinnere4a994d2015-03-30 01:10:14 +02004809 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004810 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004811 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004812
Victor Stinner21f58932012-03-14 00:15:40 +01004813 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004814}
4815
4816/* Internal helper.
4817 * Build most accurate possible datetime for current time. Pass localtime or
4818 * gmtime for f as appropriate.
4819 */
4820static PyObject *
4821datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4822{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004823 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004824 time_t secs;
4825 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004826
Victor Stinner1e2b6882015-09-18 13:23:02 +02004827 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004828 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004829 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004830
Victor Stinner1e2b6882015-09-18 13:23:02 +02004831 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004832}
4833
Larry Hastings61272b72014-01-07 12:41:53 -08004834/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004835
4836@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004837datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004838
4839 tz: object = None
4840 Timezone object.
4841
4842Returns new datetime object representing current time local to tz.
4843
4844If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004845[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004846
Larry Hastings31826802013-10-19 00:09:25 -07004847static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004848datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004849/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004851 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004852
Larry Hastings31826802013-10-19 00:09:25 -07004853 /* Return best possible local time -- this isn't constrained by the
4854 * precision of a timestamp.
4855 */
4856 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004857 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004858
Larry Hastings5c661892014-01-24 06:17:25 -08004859 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004860 tz == Py_None ? _PyTime_localtime :
4861 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004862 tz);
4863 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004864 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004865 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004866 }
4867 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004868}
4869
Tim Petersa9bc1682003-01-11 03:39:11 +00004870/* Return best possible UTC time -- this isn't constrained by the
4871 * precision of a timestamp.
4872 */
4873static PyObject *
4874datetime_utcnow(PyObject *cls, PyObject *dummy)
4875{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004876 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004877}
4878
Tim Peters2a799bf2002-12-16 20:18:38 +00004879/* Return new local datetime from timestamp (Python timestamp -- a double). */
4880static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004881datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004883 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004884 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004885 PyObject *tzinfo = Py_None;
4886 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004887
Victor Stinner5d272cc2012-03-13 13:35:55 +01004888 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004889 keywords, &timestamp, &tzinfo))
4890 return NULL;
4891 if (check_tzinfo_subclass(tzinfo) < 0)
4892 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004894 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004895 tzinfo == Py_None ? _PyTime_localtime :
4896 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004897 timestamp,
4898 tzinfo);
4899 if (self != NULL && tzinfo != Py_None) {
4900 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004901 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004902 }
4903 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004904}
4905
Tim Petersa9bc1682003-01-11 03:39:11 +00004906/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4907static PyObject *
4908datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4909{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004910 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004911 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004912
Victor Stinner5d272cc2012-03-13 13:35:55 +01004913 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004914 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004915 Py_None);
4916 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004917}
4918
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004919/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004920static PyObject *
4921datetime_strptime(PyObject *cls, PyObject *args)
4922{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004923 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004924 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004925 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004926
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004927 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004928 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004929
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004930 if (module == NULL) {
4931 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004932 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004933 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 }
Victor Stinner20401de2016-12-09 15:24:31 +01004935 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4936 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004937}
4938
Tim Petersa9bc1682003-01-11 03:39:11 +00004939/* Return new datetime from date/datetime and time arguments. */
4940static PyObject *
4941datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4942{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004943 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004944 PyObject *date;
4945 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004946 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004947 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004948
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004949 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004950 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004951 &PyDateTime_TimeType, &time, &tzinfo)) {
4952 if (tzinfo == NULL) {
4953 if (HASTZINFO(time))
4954 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4955 else
4956 tzinfo = Py_None;
4957 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004958 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
4959 GET_MONTH(date),
4960 GET_DAY(date),
4961 TIME_GET_HOUR(time),
4962 TIME_GET_MINUTE(time),
4963 TIME_GET_SECOND(time),
4964 TIME_GET_MICROSECOND(time),
4965 tzinfo,
4966 TIME_GET_FOLD(time),
4967 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004968 }
4969 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004970}
Tim Peters2a799bf2002-12-16 20:18:38 +00004971
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004972static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004973_sanitize_isoformat_str(PyObject *dtstr)
4974{
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004975 // `fromisoformat` allows surrogate characters in exactly one position,
4976 // the separator; to allow datetime_fromisoformat to make the simplifying
4977 // assumption that all valid strings can be encoded in UTF-8, this function
4978 // replaces any surrogate character separators with `T`.
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004979 //
4980 // The result of this, if not NULL, returns a new reference
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004981 Py_ssize_t len = PyUnicode_GetLength(dtstr);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004982 if (len < 0) {
4983 return NULL;
4984 }
4985
4986 if (len <= 10 ||
4987 !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
4988 Py_INCREF(dtstr);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004989 return dtstr;
4990 }
4991
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004992 PyObject *str_out = _PyUnicode_Copy(dtstr);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004993 if (str_out == NULL) {
4994 return NULL;
4995 }
4996
Miss Islington (bot)18450be2018-10-22 15:35:15 -07004997 if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004998 Py_DECREF(str_out);
4999 return NULL;
5000 }
5001
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005002 return str_out;
5003}
5004
5005static PyObject *
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005006datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
5007{
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005008 assert(dtstr != NULL);
5009
5010 if (!PyUnicode_Check(dtstr)) {
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005011 PyErr_SetString(PyExc_TypeError,
5012 "fromisoformat: argument must be str");
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005013 return NULL;
5014 }
5015
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005016 PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr);
5017 if (dtstr_clean == NULL) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005018 goto error;
5019 }
5020
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005021 Py_ssize_t len;
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005022 const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005023
5024 if (dt_ptr == NULL) {
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005025 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
5026 // Encoding errors are invalid string errors at this point
5027 goto invalid_string_error;
5028 }
5029 else {
5030 goto error;
5031 }
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005032 }
5033
5034 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005035
5036 int year = 0, month = 0, day = 0;
5037 int hour = 0, minute = 0, second = 0, microsecond = 0;
5038 int tzoffset = 0, tzusec = 0;
5039
5040 // date has a fixed length of 10
5041 int rv = parse_isoformat_date(p, &year, &month, &day);
5042
5043 if (!rv && len > 10) {
5044 // In UTF-8, the length of multi-byte characters is encoded in the MSB
5045 if ((p[10] & 0x80) == 0) {
5046 p += 11;
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005047 }
5048 else {
5049 switch (p[10] & 0xf0) {
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005050 case 0xe0:
5051 p += 13;
5052 break;
5053 case 0xf0:
5054 p += 14;
5055 break;
5056 default:
5057 p += 12;
5058 break;
5059 }
5060 }
5061
5062 len -= (p - dt_ptr);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005063 rv = parse_isoformat_time(p, len, &hour, &minute, &second,
5064 &microsecond, &tzoffset, &tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005065 }
5066 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005067 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005068 }
5069
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005070 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005071 if (tzinfo == NULL) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005072 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005073 }
5074
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05005075 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
5076 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005077
5078 Py_DECREF(tzinfo);
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005079 Py_DECREF(dtstr_clean);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005080 return dt;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005081
5082invalid_string_error:
5083 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
5084
5085error:
Miss Islington (bot)18450be2018-10-22 15:35:15 -07005086 Py_XDECREF(dtstr_clean);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04005087
5088 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005089}
5090
Tim Peters2a799bf2002-12-16 20:18:38 +00005091/*
5092 * Destructor.
5093 */
5094
5095static void
Tim Petersa9bc1682003-01-11 03:39:11 +00005096datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005098 if (HASTZINFO(self)) {
5099 Py_XDECREF(self->tzinfo);
5100 }
5101 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005102}
5103
5104/*
5105 * Indirect access to tzinfo methods.
5106 */
5107
Tim Peters2a799bf2002-12-16 20:18:38 +00005108/* These are all METH_NOARGS, so don't need to check the arglist. */
5109static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005110datetime_utcoffset(PyObject *self, PyObject *unused) {
5111 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005112}
5113
5114static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005115datetime_dst(PyObject *self, PyObject *unused) {
5116 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00005117}
5118
5119static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005120datetime_tzname(PyObject *self, PyObject *unused) {
5121 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005122}
5123
5124/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005125 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005126 */
5127
Tim Petersa9bc1682003-01-11 03:39:11 +00005128/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5129 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005130 */
5131static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005132add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005133 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005135 /* Note that the C-level additions can't overflow, because of
5136 * invariant bounds on the member values.
5137 */
5138 int year = GET_YEAR(date);
5139 int month = GET_MONTH(date);
5140 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5141 int hour = DATE_GET_HOUR(date);
5142 int minute = DATE_GET_MINUTE(date);
5143 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5144 int microsecond = DATE_GET_MICROSECOND(date) +
5145 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005147 assert(factor == 1 || factor == -1);
5148 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005149 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005150 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005151 }
5152
5153 return new_datetime(year, month, day,
5154 hour, minute, second, microsecond,
5155 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005156}
5157
5158static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005159datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005161 if (PyDateTime_Check(left)) {
5162 /* datetime + ??? */
5163 if (PyDelta_Check(right))
5164 /* datetime + delta */
5165 return add_datetime_timedelta(
5166 (PyDateTime_DateTime *)left,
5167 (PyDateTime_Delta *)right,
5168 1);
5169 }
5170 else if (PyDelta_Check(left)) {
5171 /* delta + datetime */
5172 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5173 (PyDateTime_Delta *) left,
5174 1);
5175 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005176 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005177}
5178
5179static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005180datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005182 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005184 if (PyDateTime_Check(left)) {
5185 /* datetime - ??? */
5186 if (PyDateTime_Check(right)) {
5187 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005188 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005189 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005190
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005191 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5192 offset2 = offset1 = Py_None;
5193 Py_INCREF(offset1);
5194 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005195 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005196 else {
5197 offset1 = datetime_utcoffset(left, NULL);
5198 if (offset1 == NULL)
5199 return NULL;
5200 offset2 = datetime_utcoffset(right, NULL);
5201 if (offset2 == NULL) {
5202 Py_DECREF(offset1);
5203 return NULL;
5204 }
5205 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5206 PyErr_SetString(PyExc_TypeError,
5207 "can't subtract offset-naive and "
5208 "offset-aware datetimes");
5209 Py_DECREF(offset1);
5210 Py_DECREF(offset2);
5211 return NULL;
5212 }
5213 }
5214 if ((offset1 != offset2) &&
5215 delta_cmp(offset1, offset2) != 0) {
5216 offdiff = delta_subtract(offset1, offset2);
5217 if (offdiff == NULL) {
5218 Py_DECREF(offset1);
5219 Py_DECREF(offset2);
5220 return NULL;
5221 }
5222 }
5223 Py_DECREF(offset1);
5224 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005225 delta_d = ymd_to_ord(GET_YEAR(left),
5226 GET_MONTH(left),
5227 GET_DAY(left)) -
5228 ymd_to_ord(GET_YEAR(right),
5229 GET_MONTH(right),
5230 GET_DAY(right));
5231 /* These can't overflow, since the values are
5232 * normalized. At most this gives the number of
5233 * seconds in one day.
5234 */
5235 delta_s = (DATE_GET_HOUR(left) -
5236 DATE_GET_HOUR(right)) * 3600 +
5237 (DATE_GET_MINUTE(left) -
5238 DATE_GET_MINUTE(right)) * 60 +
5239 (DATE_GET_SECOND(left) -
5240 DATE_GET_SECOND(right));
5241 delta_us = DATE_GET_MICROSECOND(left) -
5242 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005244 if (result == NULL)
5245 return NULL;
5246
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005247 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005248 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005249 Py_DECREF(offdiff);
5250 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005251 }
5252 else if (PyDelta_Check(right)) {
5253 /* datetime - delta */
5254 result = add_datetime_timedelta(
5255 (PyDateTime_DateTime *)left,
5256 (PyDateTime_Delta *)right,
5257 -1);
5258 }
5259 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005261 if (result == Py_NotImplemented)
5262 Py_INCREF(result);
5263 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005264}
5265
5266/* Various ways to turn a datetime into a string. */
5267
5268static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005269datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005271 const char *type_name = Py_TYPE(self)->tp_name;
5272 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005274 if (DATE_GET_MICROSECOND(self)) {
5275 baserepr = PyUnicode_FromFormat(
5276 "%s(%d, %d, %d, %d, %d, %d, %d)",
5277 type_name,
5278 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5279 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5280 DATE_GET_SECOND(self),
5281 DATE_GET_MICROSECOND(self));
5282 }
5283 else if (DATE_GET_SECOND(self)) {
5284 baserepr = PyUnicode_FromFormat(
5285 "%s(%d, %d, %d, %d, %d, %d)",
5286 type_name,
5287 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5288 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5289 DATE_GET_SECOND(self));
5290 }
5291 else {
5292 baserepr = PyUnicode_FromFormat(
5293 "%s(%d, %d, %d, %d, %d)",
5294 type_name,
5295 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5296 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5297 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005298 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5299 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005300 if (baserepr == NULL || ! HASTZINFO(self))
5301 return baserepr;
5302 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005303}
5304
Tim Petersa9bc1682003-01-11 03:39:11 +00005305static PyObject *
5306datetime_str(PyDateTime_DateTime *self)
5307{
Victor Stinner4c381542016-12-09 00:33:39 +01005308 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005309}
Tim Peters2a799bf2002-12-16 20:18:38 +00005310
5311static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005312datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005314 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005315 char *timespec = NULL;
5316 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005317 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005318 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005319 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005320 static char *specs[][2] = {
5321 {"hours", "%04d-%02d-%02d%c%02d"},
5322 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5323 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5324 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5325 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5326 };
5327 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005328
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005329 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005330 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005331
5332 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5333 if (us == 0) {
5334 /* seconds */
5335 given_spec = 2;
5336 }
5337 else {
5338 /* microseconds */
5339 given_spec = 4;
5340 }
5341 }
5342 else {
5343 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5344 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5345 if (given_spec == 3) {
5346 us = us / 1000;
5347 }
5348 break;
5349 }
5350 }
5351 }
5352
5353 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5354 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5355 return NULL;
5356 }
5357 else {
5358 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005359 GET_YEAR(self), GET_MONTH(self),
5360 GET_DAY(self), (int)sep,
5361 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5362 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005363 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005365 if (!result || !HASTZINFO(self))
5366 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005368 /* We need to append the UTC offset. */
5369 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5370 (PyObject *)self) < 0) {
5371 Py_DECREF(result);
5372 return NULL;
5373 }
5374 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5375 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005376}
5377
Tim Petersa9bc1682003-01-11 03:39:11 +00005378static PyObject *
5379datetime_ctime(PyDateTime_DateTime *self)
5380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005381 return format_ctime((PyDateTime_Date *)self,
5382 DATE_GET_HOUR(self),
5383 DATE_GET_MINUTE(self),
5384 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005385}
5386
Tim Peters2a799bf2002-12-16 20:18:38 +00005387/* Miscellaneous methods. */
5388
Tim Petersa9bc1682003-01-11 03:39:11 +00005389static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005390flip_fold(PyObject *dt)
5391{
5392 return new_datetime_ex2(GET_YEAR(dt),
5393 GET_MONTH(dt),
5394 GET_DAY(dt),
5395 DATE_GET_HOUR(dt),
5396 DATE_GET_MINUTE(dt),
5397 DATE_GET_SECOND(dt),
5398 DATE_GET_MICROSECOND(dt),
5399 HASTZINFO(dt) ?
5400 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5401 !DATE_GET_FOLD(dt),
5402 Py_TYPE(dt));
5403}
5404
5405static PyObject *
5406get_flip_fold_offset(PyObject *dt)
5407{
5408 PyObject *result, *flip_dt;
5409
5410 flip_dt = flip_fold(dt);
5411 if (flip_dt == NULL)
5412 return NULL;
5413 result = datetime_utcoffset(flip_dt, NULL);
5414 Py_DECREF(flip_dt);
5415 return result;
5416}
5417
5418/* PEP 495 exception: Whenever one or both of the operands in
5419 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakafd936662018-03-28 23:05:24 +03005420 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005421 *
5422 * Return 1 if exception applies, 0 if not, and -1 on error.
5423 */
5424static int
5425pep495_eq_exception(PyObject *self, PyObject *other,
5426 PyObject *offset_self, PyObject *offset_other)
5427{
5428 int result = 0;
5429 PyObject *flip_offset;
5430
5431 flip_offset = get_flip_fold_offset(self);
5432 if (flip_offset == NULL)
5433 return -1;
5434 if (flip_offset != offset_self &&
5435 delta_cmp(flip_offset, offset_self))
5436 {
5437 result = 1;
5438 goto done;
5439 }
5440 Py_DECREF(flip_offset);
5441
5442 flip_offset = get_flip_fold_offset(other);
5443 if (flip_offset == NULL)
5444 return -1;
5445 if (flip_offset != offset_other &&
5446 delta_cmp(flip_offset, offset_other))
5447 result = 1;
5448 done:
5449 Py_DECREF(flip_offset);
5450 return result;
5451}
5452
5453static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005454datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005455{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005456 PyObject *result = NULL;
5457 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005458 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005460 if (! PyDateTime_Check(other)) {
5461 if (PyDate_Check(other)) {
5462 /* Prevent invocation of date_richcompare. We want to
5463 return NotImplemented here to give the other object
5464 a chance. But since DateTime is a subclass of
5465 Date, if the other object is a Date, it would
5466 compute an ordering based on the date part alone,
5467 and we don't want that. So force unequal or
5468 uncomparable here in that case. */
5469 if (op == Py_EQ)
5470 Py_RETURN_FALSE;
5471 if (op == Py_NE)
5472 Py_RETURN_TRUE;
5473 return cmperror(self, other);
5474 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005475 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005476 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005477
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005478 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005479 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5480 ((PyDateTime_DateTime *)other)->data,
5481 _PyDateTime_DATETIME_DATASIZE);
5482 return diff_to_bool(diff, op);
5483 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005484 offset1 = datetime_utcoffset(self, NULL);
5485 if (offset1 == NULL)
5486 return NULL;
5487 offset2 = datetime_utcoffset(other, NULL);
5488 if (offset2 == NULL)
5489 goto done;
5490 /* If they're both naive, or both aware and have the same offsets,
5491 * we get off cheap. Note that if they're both naive, offset1 ==
5492 * offset2 == Py_None at this point.
5493 */
5494 if ((offset1 == offset2) ||
5495 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5496 delta_cmp(offset1, offset2) == 0)) {
5497 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5498 ((PyDateTime_DateTime *)other)->data,
5499 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005500 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5501 int ex = pep495_eq_exception(self, other, offset1, offset2);
5502 if (ex == -1)
5503 goto done;
5504 if (ex)
5505 diff = 1;
5506 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005507 result = diff_to_bool(diff, op);
5508 }
5509 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005510 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005511
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005512 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005513 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5514 other);
5515 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005516 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005517 diff = GET_TD_DAYS(delta);
5518 if (diff == 0)
5519 diff = GET_TD_SECONDS(delta) |
5520 GET_TD_MICROSECONDS(delta);
5521 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005522 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5523 int ex = pep495_eq_exception(self, other, offset1, offset2);
5524 if (ex == -1)
5525 goto done;
5526 if (ex)
5527 diff = 1;
5528 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005529 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005530 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005531 else if (op == Py_EQ) {
5532 result = Py_False;
5533 Py_INCREF(result);
5534 }
5535 else if (op == Py_NE) {
5536 result = Py_True;
5537 Py_INCREF(result);
5538 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005539 else {
5540 PyErr_SetString(PyExc_TypeError,
5541 "can't compare offset-naive and "
5542 "offset-aware datetimes");
5543 }
5544 done:
5545 Py_DECREF(offset1);
5546 Py_XDECREF(offset2);
5547 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005548}
5549
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005550static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005551datetime_hash(PyDateTime_DateTime *self)
5552{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005553 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005554 PyObject *offset, *self0;
5555 if (DATE_GET_FOLD(self)) {
5556 self0 = new_datetime_ex2(GET_YEAR(self),
5557 GET_MONTH(self),
5558 GET_DAY(self),
5559 DATE_GET_HOUR(self),
5560 DATE_GET_MINUTE(self),
5561 DATE_GET_SECOND(self),
5562 DATE_GET_MICROSECOND(self),
5563 HASTZINFO(self) ? self->tzinfo : Py_None,
5564 0, Py_TYPE(self));
5565 if (self0 == NULL)
5566 return -1;
5567 }
5568 else {
5569 self0 = (PyObject *)self;
5570 Py_INCREF(self0);
5571 }
5572 offset = datetime_utcoffset(self0, NULL);
5573 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005574
5575 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005576 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005578 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005579 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005580 self->hashcode = generic_hash(
5581 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005582 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005583 PyObject *temp1, *temp2;
5584 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005586 assert(HASTZINFO(self));
5587 days = ymd_to_ord(GET_YEAR(self),
5588 GET_MONTH(self),
5589 GET_DAY(self));
5590 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005591 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005592 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005593 temp1 = new_delta(days, seconds,
5594 DATE_GET_MICROSECOND(self),
5595 1);
5596 if (temp1 == NULL) {
5597 Py_DECREF(offset);
5598 return -1;
5599 }
5600 temp2 = delta_subtract(temp1, offset);
5601 Py_DECREF(temp1);
5602 if (temp2 == NULL) {
5603 Py_DECREF(offset);
5604 return -1;
5605 }
5606 self->hashcode = PyObject_Hash(temp2);
5607 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005608 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005609 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005610 }
5611 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005612}
Tim Peters2a799bf2002-12-16 20:18:38 +00005613
5614static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005615datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005617 PyObject *clone;
5618 PyObject *tuple;
5619 int y = GET_YEAR(self);
5620 int m = GET_MONTH(self);
5621 int d = GET_DAY(self);
5622 int hh = DATE_GET_HOUR(self);
5623 int mm = DATE_GET_MINUTE(self);
5624 int ss = DATE_GET_SECOND(self);
5625 int us = DATE_GET_MICROSECOND(self);
5626 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005627 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005628
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005629 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005630 datetime_kws,
5631 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005632 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005633 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005634 if (fold != 0 && fold != 1) {
5635 PyErr_SetString(PyExc_ValueError,
5636 "fold must be either 0 or 1");
5637 return NULL;
5638 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005639 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5640 if (tuple == NULL)
5641 return NULL;
5642 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005643 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005644 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005645 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005646 Py_DECREF(tuple);
5647 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005648}
5649
5650static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005651local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005652{
5653 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005654 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005655 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005656 PyObject *nameo = NULL;
5657 const char *zone = NULL;
5658
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005659 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005660 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005661#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005662 zone = local_time_tm.tm_zone;
5663 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005664#else /* HAVE_STRUCT_TM_TM_ZONE */
5665 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005666 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005667 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005668 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005669 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005670 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005671 local_time = new_datetime(local_time_tm.tm_year + 1900,
5672 local_time_tm.tm_mon + 1,
5673 local_time_tm.tm_mday,
5674 local_time_tm.tm_hour,
5675 local_time_tm.tm_min,
5676 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005677 if (local_time == NULL) {
5678 return NULL;
5679 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005680 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005681 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005682 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5683 utc_time_tm.tm_mon + 1,
5684 utc_time_tm.tm_mday,
5685 utc_time_tm.tm_hour,
5686 utc_time_tm.tm_min,
5687 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005688 if (utc_time == NULL) {
5689 Py_DECREF(local_time);
5690 return NULL;
5691 }
5692 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005693 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005694 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005695 }
5696#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005697 if (delta == NULL) {
5698 return NULL;
5699 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005700 if (zone != NULL) {
5701 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5702 if (nameo == NULL)
5703 goto error;
5704 }
5705 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005706 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005707 error:
5708 Py_DECREF(delta);
5709 return result;
5710}
5711
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005712static PyObject *
5713local_timezone(PyDateTime_DateTime *utc_time)
5714{
5715 time_t timestamp;
5716 PyObject *delta;
5717 PyObject *one_second;
5718 PyObject *seconds;
5719
5720 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5721 if (delta == NULL)
5722 return NULL;
5723 one_second = new_delta(0, 1, 0, 0);
5724 if (one_second == NULL) {
5725 Py_DECREF(delta);
5726 return NULL;
5727 }
5728 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5729 (PyDateTime_Delta *)one_second);
5730 Py_DECREF(one_second);
5731 Py_DECREF(delta);
5732 if (seconds == NULL)
5733 return NULL;
5734 timestamp = _PyLong_AsTime_t(seconds);
5735 Py_DECREF(seconds);
5736 if (timestamp == -1 && PyErr_Occurred())
5737 return NULL;
5738 return local_timezone_from_timestamp(timestamp);
5739}
5740
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005741static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005742local_to_seconds(int year, int month, int day,
5743 int hour, int minute, int second, int fold);
5744
5745static PyObject *
5746local_timezone_from_local(PyDateTime_DateTime *local_dt)
5747{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005748 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005749 time_t timestamp;
5750 seconds = local_to_seconds(GET_YEAR(local_dt),
5751 GET_MONTH(local_dt),
5752 GET_DAY(local_dt),
5753 DATE_GET_HOUR(local_dt),
5754 DATE_GET_MINUTE(local_dt),
5755 DATE_GET_SECOND(local_dt),
5756 DATE_GET_FOLD(local_dt));
5757 if (seconds == -1)
5758 return NULL;
5759 /* XXX: add bounds check */
5760 timestamp = seconds - epoch;
5761 return local_timezone_from_timestamp(timestamp);
5762}
5763
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005764static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005765datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005766{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005767 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005768 PyObject *offset;
5769 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005770 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005771 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005772 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005773
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005774 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005775 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005776 return NULL;
5777
5778 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005779 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005780
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005781 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005782 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005783 self_tzinfo = local_timezone_from_local(self);
5784 if (self_tzinfo == NULL)
5785 return NULL;
5786 } else {
5787 self_tzinfo = self->tzinfo;
5788 Py_INCREF(self_tzinfo);
5789 }
Tim Peters521fc152002-12-31 17:36:56 +00005790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005791 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005792 if (self_tzinfo == tzinfo) {
5793 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005794 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005795 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005796 }
Tim Peters521fc152002-12-31 17:36:56 +00005797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005798 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005799 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5800 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005801 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005802 return NULL;
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005803 else if(offset == Py_None) {
5804 Py_DECREF(offset);
5805 goto naive;
5806 }
5807 else if (!PyDelta_Check(offset)) {
5808 Py_DECREF(offset);
5809 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5810 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5811 return NULL;
5812 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005813 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005814 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5815 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005816 Py_DECREF(offset);
5817 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005818 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005819
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005820 /* Make sure result is aware and UTC. */
5821 if (!HASTZINFO(result)) {
5822 temp = (PyObject *)result;
5823 result = (PyDateTime_DateTime *)
5824 new_datetime_ex2(GET_YEAR(result),
5825 GET_MONTH(result),
5826 GET_DAY(result),
5827 DATE_GET_HOUR(result),
5828 DATE_GET_MINUTE(result),
5829 DATE_GET_SECOND(result),
5830 DATE_GET_MICROSECOND(result),
5831 PyDateTime_TimeZone_UTC,
5832 DATE_GET_FOLD(result),
5833 Py_TYPE(result));
5834 Py_DECREF(temp);
5835 if (result == NULL)
5836 return NULL;
5837 }
5838 else {
5839 /* Result is already aware - just replace tzinfo. */
5840 temp = result->tzinfo;
5841 result->tzinfo = PyDateTime_TimeZone_UTC;
5842 Py_INCREF(result->tzinfo);
5843 Py_DECREF(temp);
5844 }
5845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005846 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005847 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005848 if (tzinfo == Py_None) {
5849 tzinfo = local_timezone(result);
5850 if (tzinfo == NULL) {
5851 Py_DECREF(result);
5852 return NULL;
5853 }
5854 }
5855 else
5856 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005857 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005858 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005859
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005860 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005861 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005862 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005863 Py_DECREF(temp);
5864
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005865 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005866}
5867
5868static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005869datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005870{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005871 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005873 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005874 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005875
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005876 dst = call_dst(self->tzinfo, (PyObject *)self);
5877 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005878 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005879
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005880 if (dst != Py_None)
5881 dstflag = delta_bool((PyDateTime_Delta *)dst);
5882 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005883 }
5884 return build_struct_time(GET_YEAR(self),
5885 GET_MONTH(self),
5886 GET_DAY(self),
5887 DATE_GET_HOUR(self),
5888 DATE_GET_MINUTE(self),
5889 DATE_GET_SECOND(self),
5890 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005891}
5892
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005893static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005894local_to_seconds(int year, int month, int day,
5895 int hour, int minute, int second, int fold)
5896{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005897 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005898 t = utc_to_seconds(year, month, day, hour, minute, second);
5899 /* Our goal is to solve t = local(u) for u. */
5900 lt = local(t);
5901 if (lt == -1)
5902 return -1;
5903 a = lt - t;
5904 u1 = t - a;
5905 t1 = local(u1);
5906 if (t1 == -1)
5907 return -1;
5908 if (t1 == t) {
5909 /* We found one solution, but it may not be the one we need.
5910 * Look for an earlier solution (if `fold` is 0), or a
5911 * later one (if `fold` is 1). */
5912 if (fold)
5913 u2 = u1 + max_fold_seconds;
5914 else
5915 u2 = u1 - max_fold_seconds;
5916 lt = local(u2);
5917 if (lt == -1)
5918 return -1;
5919 b = lt - u2;
5920 if (a == b)
5921 return u1;
5922 }
5923 else {
5924 b = t1 - u1;
5925 assert(a != b);
5926 }
5927 u2 = t - b;
5928 t2 = local(u2);
5929 if (t2 == -1)
5930 return -1;
5931 if (t2 == t)
5932 return u2;
5933 if (t1 == t)
5934 return u1;
5935 /* We have found both offsets a and b, but neither t - a nor t - b is
5936 * a solution. This means t is in the gap. */
5937 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5938}
5939
5940/* date(1970,1,1).toordinal() == 719163 */
5941#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5942
Tim Peters2a799bf2002-12-16 20:18:38 +00005943static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005944datetime_timestamp(PyDateTime_DateTime *self)
5945{
5946 PyObject *result;
5947
5948 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5949 PyObject *delta;
5950 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5951 if (delta == NULL)
5952 return NULL;
5953 result = delta_total_seconds(delta);
5954 Py_DECREF(delta);
5955 }
5956 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005957 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005958 seconds = local_to_seconds(GET_YEAR(self),
5959 GET_MONTH(self),
5960 GET_DAY(self),
5961 DATE_GET_HOUR(self),
5962 DATE_GET_MINUTE(self),
5963 DATE_GET_SECOND(self),
5964 DATE_GET_FOLD(self));
5965 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005966 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005967 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5968 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005969 }
5970 return result;
5971}
5972
5973static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005974datetime_getdate(PyDateTime_DateTime *self)
5975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005976 return new_date(GET_YEAR(self),
5977 GET_MONTH(self),
5978 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005979}
5980
5981static PyObject *
5982datetime_gettime(PyDateTime_DateTime *self)
5983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005984 return new_time(DATE_GET_HOUR(self),
5985 DATE_GET_MINUTE(self),
5986 DATE_GET_SECOND(self),
5987 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005988 Py_None,
5989 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005990}
5991
5992static PyObject *
5993datetime_gettimetz(PyDateTime_DateTime *self)
5994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005995 return new_time(DATE_GET_HOUR(self),
5996 DATE_GET_MINUTE(self),
5997 DATE_GET_SECOND(self),
5998 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005999 GET_DT_TZINFO(self),
6000 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00006001}
6002
6003static PyObject *
6004datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00006005{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006006 int y, m, d, hh, mm, ss;
6007 PyObject *tzinfo;
6008 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00006009
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006010 tzinfo = GET_DT_TZINFO(self);
6011 if (tzinfo == Py_None) {
6012 utcself = self;
6013 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006014 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006015 else {
6016 PyObject *offset;
6017 offset = call_utcoffset(tzinfo, (PyObject *)self);
6018 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00006019 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006020 if (offset == Py_None) {
6021 Py_DECREF(offset);
6022 utcself = self;
6023 Py_INCREF(utcself);
6024 }
6025 else {
6026 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
6027 (PyDateTime_Delta *)offset, -1);
6028 Py_DECREF(offset);
6029 if (utcself == NULL)
6030 return NULL;
6031 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006032 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00006033 y = GET_YEAR(utcself);
6034 m = GET_MONTH(utcself);
6035 d = GET_DAY(utcself);
6036 hh = DATE_GET_HOUR(utcself);
6037 mm = DATE_GET_MINUTE(utcself);
6038 ss = DATE_GET_SECOND(utcself);
6039
6040 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006041 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00006042}
6043
Tim Peters371935f2003-02-01 01:52:50 +00006044/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00006045
Tim Petersa9bc1682003-01-11 03:39:11 +00006046/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00006047 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
6048 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00006049 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00006050 */
6051static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006052datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00006053{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006054 PyObject *basestate;
6055 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006057 basestate = PyBytes_FromStringAndSize((char *)self->data,
6058 _PyDateTime_DATETIME_DATASIZE);
6059 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006060 if (proto > 3 && DATE_GET_FOLD(self))
6061 /* Set the first bit of the third byte */
6062 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006063 if (! HASTZINFO(self) || self->tzinfo == Py_None)
6064 result = PyTuple_Pack(1, basestate);
6065 else
6066 result = PyTuple_Pack(2, basestate, self->tzinfo);
6067 Py_DECREF(basestate);
6068 }
6069 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00006070}
6071
6072static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006073datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00006074{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006075 int proto;
6076 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006077 return NULL;
6078
6079 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00006080}
6081
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006082static PyObject *
6083datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
6084{
6085 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
6086}
6087
Tim Petersa9bc1682003-01-11 03:39:11 +00006088static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00006089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006090 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00006091
Larry Hastingsed4a1c52013-11-18 09:32:13 -08006092 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00006093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006094 {"utcnow", (PyCFunction)datetime_utcnow,
6095 METH_NOARGS | METH_CLASS,
6096 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006098 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
6099 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6100 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006102 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
6103 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05006104 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006106 {"strptime", (PyCFunction)datetime_strptime,
6107 METH_VARARGS | METH_CLASS,
6108 PyDoc_STR("string, format -> new datetime parsed from a string "
6109 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00006110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006111 {"combine", (PyCFunction)datetime_combine,
6112 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
6113 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006114
Paul Ganssle09dc2f52017-12-21 00:33:49 -05006115 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
6116 METH_O | METH_CLASS,
6117 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006119 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006121 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6122 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006124 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6125 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006127 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6128 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006130 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6131 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006133 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6134 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006135
Alexander Belopolskya4415142012-06-08 12:33:09 -04006136 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6137 PyDoc_STR("Return POSIX timestamp as float.")},
6138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006139 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6140 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006142 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
6143 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006144 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006145 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006146 "defaults to 'T'.\n"
6147 "timespec specifies what components of the time to include"
6148 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6149 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006151 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6152 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006154 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6155 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006157 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6158 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006160 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
6161 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006163 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
6164 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006165
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006166 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006167 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006168
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006169 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6170 PyDoc_STR("__reduce__() -> (cls, state)")},
6171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006172 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006173};
6174
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006175static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006176PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6177\n\
6178The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006179instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006180
Tim Petersa9bc1682003-01-11 03:39:11 +00006181static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006182 datetime_add, /* nb_add */
6183 datetime_subtract, /* nb_subtract */
6184 0, /* nb_multiply */
6185 0, /* nb_remainder */
6186 0, /* nb_divmod */
6187 0, /* nb_power */
6188 0, /* nb_negative */
6189 0, /* nb_positive */
6190 0, /* nb_absolute */
6191 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006192};
6193
Neal Norwitz227b5332006-03-22 09:28:35 +00006194static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006195 PyVarObject_HEAD_INIT(NULL, 0)
6196 "datetime.datetime", /* tp_name */
6197 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6198 0, /* tp_itemsize */
6199 (destructor)datetime_dealloc, /* tp_dealloc */
6200 0, /* tp_print */
6201 0, /* tp_getattr */
6202 0, /* tp_setattr */
6203 0, /* tp_reserved */
6204 (reprfunc)datetime_repr, /* tp_repr */
6205 &datetime_as_number, /* tp_as_number */
6206 0, /* tp_as_sequence */
6207 0, /* tp_as_mapping */
6208 (hashfunc)datetime_hash, /* tp_hash */
6209 0, /* tp_call */
6210 (reprfunc)datetime_str, /* tp_str */
6211 PyObject_GenericGetAttr, /* tp_getattro */
6212 0, /* tp_setattro */
6213 0, /* tp_as_buffer */
6214 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6215 datetime_doc, /* tp_doc */
6216 0, /* tp_traverse */
6217 0, /* tp_clear */
6218 datetime_richcompare, /* tp_richcompare */
6219 0, /* tp_weaklistoffset */
6220 0, /* tp_iter */
6221 0, /* tp_iternext */
6222 datetime_methods, /* tp_methods */
6223 0, /* tp_members */
6224 datetime_getset, /* tp_getset */
6225 &PyDateTime_DateType, /* tp_base */
6226 0, /* tp_dict */
6227 0, /* tp_descr_get */
6228 0, /* tp_descr_set */
6229 0, /* tp_dictoffset */
6230 0, /* tp_init */
6231 datetime_alloc, /* tp_alloc */
6232 datetime_new, /* tp_new */
6233 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006234};
6235
6236/* ---------------------------------------------------------------------------
6237 * Module methods and initialization.
6238 */
6239
6240static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006241 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006242};
6243
Tim Peters9ddf40b2004-06-20 22:41:32 +00006244/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6245 * datetime.h.
6246 */
6247static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006248 &PyDateTime_DateType,
6249 &PyDateTime_DateTimeType,
6250 &PyDateTime_TimeType,
6251 &PyDateTime_DeltaType,
6252 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006253 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006254 new_date_ex,
6255 new_datetime_ex,
6256 new_time_ex,
6257 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006258 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006259 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006260 date_fromtimestamp,
6261 new_datetime_ex2,
6262 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006263};
6264
6265
Martin v. Löwis1a214512008-06-11 05:26:20 +00006266
6267static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006268 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006269 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006270 "Fast implementation of the datetime type.",
6271 -1,
6272 module_methods,
6273 NULL,
6274 NULL,
6275 NULL,
6276 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006277};
6278
Tim Peters2a799bf2002-12-16 20:18:38 +00006279PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006280PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006282 PyObject *m; /* a module object */
6283 PyObject *d; /* its dict */
6284 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006285 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006287 m = PyModule_Create(&datetimemodule);
6288 if (m == NULL)
6289 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006291 if (PyType_Ready(&PyDateTime_DateType) < 0)
6292 return NULL;
6293 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6294 return NULL;
6295 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6296 return NULL;
6297 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6298 return NULL;
6299 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6300 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006301 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6302 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006304 /* timedelta values */
6305 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006307 x = new_delta(0, 0, 1, 0);
6308 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6309 return NULL;
6310 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006312 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6313 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6314 return NULL;
6315 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006317 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6318 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6319 return NULL;
6320 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006322 /* date values */
6323 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006325 x = new_date(1, 1, 1);
6326 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6327 return NULL;
6328 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006330 x = new_date(MAXYEAR, 12, 31);
6331 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6332 return NULL;
6333 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006335 x = new_delta(1, 0, 0, 0);
6336 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6337 return NULL;
6338 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006340 /* time values */
6341 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006342
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006343 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006344 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6345 return NULL;
6346 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006347
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006348 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006349 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6350 return NULL;
6351 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006353 x = new_delta(0, 0, 1, 0);
6354 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6355 return NULL;
6356 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006358 /* datetime values */
6359 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006360
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006361 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006362 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6363 return NULL;
6364 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006365
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006366 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006367 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6368 return NULL;
6369 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006371 x = new_delta(0, 0, 1, 0);
6372 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6373 return NULL;
6374 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006375
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006376 /* timezone values */
6377 d = PyDateTime_TimeZoneType.tp_dict;
6378
6379 delta = new_delta(0, 0, 0, 0);
6380 if (delta == NULL)
6381 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006382 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006383 Py_DECREF(delta);
6384 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6385 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006386 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006387 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006388
6389 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6390 if (delta == NULL)
6391 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006392 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006393 Py_DECREF(delta);
6394 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6395 return NULL;
6396 Py_DECREF(x);
6397
6398 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6399 if (delta == NULL)
6400 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006401 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006402 Py_DECREF(delta);
6403 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6404 return NULL;
6405 Py_DECREF(x);
6406
Alexander Belopolskya4415142012-06-08 12:33:09 -04006407 /* Epoch */
6408 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006409 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006410 if (PyDateTime_Epoch == NULL)
6411 return NULL;
6412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006413 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006414 PyModule_AddIntMacro(m, MINYEAR);
6415 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006417 Py_INCREF(&PyDateTime_DateType);
6418 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006420 Py_INCREF(&PyDateTime_DateTimeType);
6421 PyModule_AddObject(m, "datetime",
6422 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006424 Py_INCREF(&PyDateTime_TimeType);
6425 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006427 Py_INCREF(&PyDateTime_DeltaType);
6428 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006430 Py_INCREF(&PyDateTime_TZInfoType);
6431 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006432
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006433 Py_INCREF(&PyDateTime_TimeZoneType);
6434 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006436 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6437 if (x == NULL)
6438 return NULL;
6439 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006441 /* A 4-year cycle has an extra leap day over what we'd get from
6442 * pasting together 4 single years.
6443 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006444 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006445 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006447 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6448 * get from pasting together 4 100-year cycles.
6449 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006450 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006451 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006453 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6454 * pasting together 25 4-year cycles.
6455 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006456 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006457 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006459 us_per_ms = PyLong_FromLong(1000);
6460 us_per_second = PyLong_FromLong(1000000);
6461 us_per_minute = PyLong_FromLong(60000000);
6462 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006463 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006464 us_per_minute == NULL || seconds_per_day == NULL)
6465 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006467 /* The rest are too big for 32-bit ints, but even
6468 * us_per_week fits in 40 bits, so doubles should be exact.
6469 */
6470 us_per_hour = PyLong_FromDouble(3600000000.0);
6471 us_per_day = PyLong_FromDouble(86400000000.0);
6472 us_per_week = PyLong_FromDouble(604800000000.0);
6473 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6474 return NULL;
6475 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006476}
Tim Petersf3615152003-01-01 21:51:37 +00006477
6478/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006479Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006480 x.n = x stripped of its timezone -- its naive time.
6481 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006482 return None
Tim Petersf3615152003-01-01 21:51:37 +00006483 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006484 return None
Tim Petersf3615152003-01-01 21:51:37 +00006485 x.s = x's standard offset, x.o - x.d
6486
6487Now some derived rules, where k is a duration (timedelta).
6488
64891. x.o = x.s + x.d
6490 This follows from the definition of x.s.
6491
Tim Petersc5dc4da2003-01-02 17:55:03 +000064922. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006493 This is actually a requirement, an assumption we need to make about
6494 sane tzinfo classes.
6495
64963. The naive UTC time corresponding to x is x.n - x.o.
6497 This is again a requirement for a sane tzinfo class.
6498
64994. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006500 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006501
Tim Petersc5dc4da2003-01-02 17:55:03 +000065025. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006503 Again follows from how arithmetic is defined.
6504
Tim Peters8bb5ad22003-01-24 02:44:45 +00006505Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006506(meaning that the various tzinfo methods exist, and don't blow up or return
6507None when called).
6508
Tim Petersa9bc1682003-01-11 03:39:11 +00006509The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006510x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006511
6512By #3, we want
6513
Tim Peters8bb5ad22003-01-24 02:44:45 +00006514 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006515
6516The algorithm starts by attaching tz to x.n, and calling that y. So
6517x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6518becomes true; in effect, we want to solve [2] for k:
6519
Tim Peters8bb5ad22003-01-24 02:44:45 +00006520 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006521
6522By #1, this is the same as
6523
Tim Peters8bb5ad22003-01-24 02:44:45 +00006524 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006525
6526By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6527Substituting that into [3],
6528
Tim Peters8bb5ad22003-01-24 02:44:45 +00006529 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6530 k - (y+k).s - (y+k).d = 0; rearranging,
6531 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6532 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006533
Tim Peters8bb5ad22003-01-24 02:44:45 +00006534On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6535approximate k by ignoring the (y+k).d term at first. Note that k can't be
6536very large, since all offset-returning methods return a duration of magnitude
6537less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6538be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006539
6540In any case, the new value is
6541
Tim Peters8bb5ad22003-01-24 02:44:45 +00006542 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006543
Tim Peters8bb5ad22003-01-24 02:44:45 +00006544It's helpful to step back at look at [4] from a higher level: it's simply
6545mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006546
6547At this point, if
6548
Tim Peters8bb5ad22003-01-24 02:44:45 +00006549 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006550
6551we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006552at the start of daylight time. Picture US Eastern for concreteness. The wall
6553time 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 +00006554sense then. The docs ask that an Eastern tzinfo class consider such a time to
6555be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6556on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006557the only spelling that makes sense on the local wall clock.
6558
Tim Petersc5dc4da2003-01-02 17:55:03 +00006559In fact, if [5] holds at this point, we do have the standard-time spelling,
6560but that takes a bit of proof. We first prove a stronger result. What's the
6561difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006562
Tim Peters8bb5ad22003-01-24 02:44:45 +00006563 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006564
Tim Petersc5dc4da2003-01-02 17:55:03 +00006565Now
6566 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006567 (y + y.s).n = by #5
6568 y.n + y.s = since y.n = x.n
6569 x.n + y.s = since z and y are have the same tzinfo member,
6570 y.s = z.s by #2
6571 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006572
Tim Petersc5dc4da2003-01-02 17:55:03 +00006573Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006574
Tim Petersc5dc4da2003-01-02 17:55:03 +00006575 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006576 x.n - ((x.n + z.s) - z.o) = expanding
6577 x.n - x.n - z.s + z.o = cancelling
6578 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006579 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006580
Tim Petersc5dc4da2003-01-02 17:55:03 +00006581So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006582
Tim Petersc5dc4da2003-01-02 17:55:03 +00006583If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006584spelling we wanted in the endcase described above. We're done. Contrarily,
6585if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006586
Tim Petersc5dc4da2003-01-02 17:55:03 +00006587If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6588add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006589local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006590
Tim Petersc5dc4da2003-01-02 17:55:03 +00006591Let
Tim Petersf3615152003-01-01 21:51:37 +00006592
Tim Peters4fede1a2003-01-04 00:26:59 +00006593 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006594
Tim Peters4fede1a2003-01-04 00:26:59 +00006595and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006596
Tim Peters8bb5ad22003-01-24 02:44:45 +00006597 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006598
Tim Peters8bb5ad22003-01-24 02:44:45 +00006599If so, we're done. If not, the tzinfo class is insane, according to the
6600assumptions we've made. This also requires a bit of proof. As before, let's
6601compute the difference between the LHS and RHS of [8] (and skipping some of
6602the justifications for the kinds of substitutions we've done several times
6603already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006604
Tim Peters8bb5ad22003-01-24 02:44:45 +00006605 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006606 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6607 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6608 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6609 - z.n + z.n - z.o + z'.o = cancel z.n
6610 - z.o + z'.o = #1 twice
6611 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6612 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006613
6614So 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 +00006615we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6616return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006617
Tim Peters8bb5ad22003-01-24 02:44:45 +00006618How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6619a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6620would have to change the result dst() returns: we start in DST, and moving
6621a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006622
Tim Peters8bb5ad22003-01-24 02:44:45 +00006623There isn't a sane case where this can happen. The closest it gets is at
6624the end of DST, where there's an hour in UTC with no spelling in a hybrid
6625tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6626that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6627UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6628time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6629clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6630standard time. Since that's what the local clock *does*, we want to map both
6631UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006632in local time, but so it goes -- it's the way the local clock works.
6633
Tim Peters8bb5ad22003-01-24 02:44:45 +00006634When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6635so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6636z' = 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 +00006637(correctly) concludes that z' is not UTC-equivalent to x.
6638
6639Because we know z.d said z was in daylight time (else [5] would have held and
6640we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006641and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006642return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6643but the reasoning doesn't depend on the example -- it depends on there being
6644two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006645z' must be in standard time, and is the spelling we want in this case.
6646
6647Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6648concerned (because it takes z' as being in standard time rather than the
6649daylight time we intend here), but returning it gives the real-life "local
6650clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6651tz.
6652
6653When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6654the 1:MM standard time spelling we want.
6655
6656So how can this break? One of the assumptions must be violated. Two
6657possibilities:
6658
66591) [2] effectively says that y.s is invariant across all y belong to a given
6660 time zone. This isn't true if, for political reasons or continental drift,
6661 a region decides to change its base offset from UTC.
6662
66632) There may be versions of "double daylight" time where the tail end of
6664 the analysis gives up a step too early. I haven't thought about that
6665 enough to say.
6666
6667In any case, it's clear that the default fromutc() is strong enough to handle
6668"almost all" time zones: so long as the standard offset is invariant, it
6669doesn't matter if daylight time transition points change from year to year, or
6670if daylight time is skipped in some years; it doesn't matter how large or
6671small dst() may get within its bounds; and it doesn't even matter if some
6672perverse time zone returns a negative dst()). So a breaking case must be
6673pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006674--------------------------------------------------------------------------- */