blob: 81a0b1f16811fd77ca2138efff8674e3c7b8c310 [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
670static const char*
671parse_digits(const char* ptr, int* var, size_t num_digits)
672{
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
685static int parse_isoformat_date(const char *dtstr,
686 int* year, int *month, int* day) {
687 /* Parse the date components of the result of date.isoformat()
688 *
689 * Return codes:
690 * 0: Success
691 * -1: Failed to parse date component
692 * -2: Failed to parse dateseparator
693 */
694 const char *p = dtstr;
695 p = parse_digits(p, year, 4);
696 if (NULL == p) {
697 return -1;
698 }
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100699
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500700 if (*(p++) != '-') {
701 return -2;
702 }
703
704 p = parse_digits(p, month, 2);
705 if (NULL == p) {
706 return -1;
707 }
708
709 if (*(p++) != '-') {
710 return -2;
711 }
712
713 p = parse_digits(p, day, 2);
714 if (p == NULL) {
715 return -1;
716 }
717
718 return 0;
719}
720
721static int
722parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end,
723 int* hour, int* minute, int *second, int *microsecond) {
724 const char *p = tstr;
725 const char *p_end = tstr_end;
726 int *vals[3] = {hour, minute, second};
727
728 // Parse [HH[:MM[:SS]]]
729 for (size_t i = 0; i < 3; ++i) {
730 p = parse_digits(p, vals[i], 2);
731 if (NULL == p) {
732 return -3;
733 }
734
735 char c = *(p++);
736 if (p >= p_end) {
737 return c != '\0';
738 } else if (c == ':') {
739 continue;
740 } else if (c == '.') {
741 break;
742 } else {
743 return -4; // Malformed time separator
744 }
745 }
746
747 // Parse .fff[fff]
748 size_t len_remains = p_end - p;
749 if (!(len_remains == 6 || len_remains == 3)) {
750 return -3;
751 }
752
753 p = parse_digits(p, microsecond, len_remains);
754 if (NULL == p) {
755 return -3;
756 }
757
758 if (len_remains == 3) {
759 *microsecond *= 1000;
760 }
761
762 // Return 1 if it's not the end of the string
763 return *p != '\0';
764}
765
766static int
767parse_isoformat_time(const char *dtstr, size_t dtlen,
768 int* hour, int *minute, int *second, int *microsecond,
769 int* tzoffset, int *tzmicrosecond) {
770 // Parse the time portion of a datetime.isoformat() string
771 //
772 // Return codes:
773 // 0: Success (no tzoffset)
774 // 1: Success (with tzoffset)
775 // -3: Failed to parse time component
776 // -4: Failed to parse time separator
777 // -5: Malformed timezone string
778
779 const char *p = dtstr;
780 const char *p_end = dtstr + dtlen;
781
782 const char *tzinfo_pos = p;
783 do {
784 if (*tzinfo_pos == '+' || *tzinfo_pos == '-') {
785 break;
786 }
787 } while(++tzinfo_pos < p_end);
788
789 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos,
790 hour, minute, second, microsecond);
791
792 if (rv < 0) {
793 return rv;
794 } else if (tzinfo_pos == p_end) {
795 // We know that there's no time zone, so if there's stuff at the
796 // end of the string it's an error.
797 if (rv == 1) {
798 return -5;
799 } else {
800 return 0;
801 }
802 }
803
804 // Parse time zone component
805 // Valid formats are:
806 // - +HH:MM (len 6)
807 // - +HH:MM:SS (len 9)
808 // - +HH:MM:SS.ffffff (len 16)
809 size_t tzlen = p_end - tzinfo_pos;
810 if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) {
811 return -5;
812 }
813
814 int tzsign = (*tzinfo_pos == '-')?-1:1;
815 tzinfo_pos++;
816 int tzhour = 0, tzminute = 0, tzsecond = 0;
817 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end,
818 &tzhour, &tzminute, &tzsecond, tzmicrosecond);
819
820 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
821 *tzmicrosecond *= tzsign;
822
823 return rv?-5:1;
824}
825
826
827/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000828 * Create various objects, mostly without range checking.
829 */
830
831/* Create a date instance with no range checking. */
832static PyObject *
833new_date_ex(int year, int month, int day, PyTypeObject *type)
834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000836
Victor Stinnerb67f0962017-02-10 10:34:02 +0100837 if (check_date_args(year, month, day) < 0) {
838 return NULL;
839 }
840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
842 if (self != NULL)
843 set_date_fields(self, year, month, day);
844 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000845}
846
847#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000849
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500850// Forward declaration
851static PyObject * new_datetime_ex(int, int, int, int, int, int, int,
852 PyObject*, PyTypeObject*);
853
854/* Create date instance with no range checking, or call subclass constructor */
855static PyObject *
856new_date_subclass_ex(int year, int month, int day, PyObject *cls) {
857 PyObject *result;
858 // We have "fast path" constructors for two subclasses: date and datetime
859 if ((PyTypeObject *)cls == &PyDateTime_DateType) {
860 result = new_date_ex(year, month, day, (PyTypeObject *)cls);
861 } else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
862 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
863 (PyTypeObject *)cls);
864 } else {
865 result = PyObject_CallFunction(cls, "iii", year, month, day);
866 }
867
868 return result;
869}
870
Tim Petersb0c854d2003-05-17 15:57:00 +0000871/* Create a datetime instance with no range checking. */
872static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400873new_datetime_ex2(int year, int month, int day, int hour, int minute,
874 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 PyDateTime_DateTime *self;
877 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000878
Victor Stinnerb67f0962017-02-10 10:34:02 +0100879 if (check_date_args(year, month, day) < 0) {
880 return NULL;
881 }
882 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
883 return NULL;
884 }
885 if (check_tzinfo_subclass(tzinfo) < 0) {
886 return NULL;
887 }
888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
890 if (self != NULL) {
891 self->hastzinfo = aware;
892 set_date_fields((PyDateTime_Date *)self, year, month, day);
893 DATE_SET_HOUR(self, hour);
894 DATE_SET_MINUTE(self, minute);
895 DATE_SET_SECOND(self, second);
896 DATE_SET_MICROSECOND(self, usecond);
897 if (aware) {
898 Py_INCREF(tzinfo);
899 self->tzinfo = tzinfo;
900 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400901 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 }
903 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000904}
905
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400906static PyObject *
907new_datetime_ex(int year, int month, int day, int hour, int minute,
908 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
909{
910 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
911 tzinfo, 0, type);
912}
913
914#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
915 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000917
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500918static PyObject *
919new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
920 int second, int usecond, PyObject *tzinfo,
921 int fold, PyObject *cls) {
922 PyObject* dt;
923 if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) {
924 // Use the fast path constructor
925 dt = new_datetime(year, month, day, hour, minute, second, usecond,
926 tzinfo, fold);
927 } else {
928 // Subclass
929 dt = PyObject_CallFunction(cls, "iiiiiiiO",
930 year,
931 month,
932 day,
933 hour,
934 minute,
935 second,
936 usecond,
937 tzinfo);
938 }
939
940 return dt;
941}
942
943static PyObject *
944new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
945 int second, int usecond, PyObject *tzinfo,
946 PyObject *cls) {
947 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
948 second, usecond, tzinfo, 0,
949 cls);
950}
951
Tim Petersb0c854d2003-05-17 15:57:00 +0000952/* Create a time instance with no range checking. */
953static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400954new_time_ex2(int hour, int minute, int second, int usecond,
955 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 PyDateTime_Time *self;
958 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000959
Victor Stinnerb67f0962017-02-10 10:34:02 +0100960 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
961 return NULL;
962 }
963 if (check_tzinfo_subclass(tzinfo) < 0) {
964 return NULL;
965 }
966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
968 if (self != NULL) {
969 self->hastzinfo = aware;
970 self->hashcode = -1;
971 TIME_SET_HOUR(self, hour);
972 TIME_SET_MINUTE(self, minute);
973 TIME_SET_SECOND(self, second);
974 TIME_SET_MICROSECOND(self, usecond);
975 if (aware) {
976 Py_INCREF(tzinfo);
977 self->tzinfo = tzinfo;
978 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400979 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 }
981 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000982}
983
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400984static PyObject *
985new_time_ex(int hour, int minute, int second, int usecond,
986 PyObject *tzinfo, PyTypeObject *type)
987{
988 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
989}
990
991#define new_time(hh, mm, ss, us, tzinfo, fold) \
992 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000993
994/* Create a timedelta instance. Normalize the members iff normalize is
995 * true. Passing false is a speed optimization, if you know for sure
996 * that seconds and microseconds are already in their proper ranges. In any
997 * case, raises OverflowError and returns NULL if the normalized days is out
998 * of range).
999 */
1000static PyObject *
1001new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +00001003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 if (normalize)
1007 normalize_d_s_us(&days, &seconds, &microseconds);
1008 assert(0 <= seconds && seconds < 24*3600);
1009 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +00001010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 if (check_delta_day_range(days) < 0)
1012 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1015 if (self != NULL) {
1016 self->hashcode = -1;
1017 SET_TD_DAYS(self, days);
1018 SET_TD_SECONDS(self, seconds);
1019 SET_TD_MICROSECONDS(self, microseconds);
1020 }
1021 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001022}
1023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024#define new_delta(d, s, us, normalize) \
1025 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001026
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001027
1028typedef struct
1029{
1030 PyObject_HEAD
1031 PyObject *offset;
1032 PyObject *name;
1033} PyDateTime_TimeZone;
1034
Victor Stinner6ced7c42011-03-21 18:15:42 +01001035/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001036static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -04001037/* The interned Epoch datetime instance */
1038static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00001039
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001040/* Create new timezone instance checking offset range. This
1041 function does not check the name argument. Caller must assure
1042 that offset is a timedelta instance and name is either NULL
1043 or a unicode object. */
1044static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001045create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001046{
1047 PyDateTime_TimeZone *self;
1048 PyTypeObject *type = &PyDateTime_TimeZoneType;
1049
1050 assert(offset != NULL);
1051 assert(PyDelta_Check(offset));
1052 assert(name == NULL || PyUnicode_Check(name));
1053
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001054 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1055 if (self == NULL) {
1056 return NULL;
1057 }
1058 Py_INCREF(offset);
1059 self->offset = offset;
1060 Py_XINCREF(name);
1061 self->name = name;
1062 return (PyObject *)self;
1063}
1064
1065static int delta_bool(PyDateTime_Delta *self);
1066
1067static PyObject *
1068new_timezone(PyObject *offset, PyObject *name)
1069{
1070 assert(offset != NULL);
1071 assert(PyDelta_Check(offset));
1072 assert(name == NULL || PyUnicode_Check(name));
1073
1074 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
1075 Py_INCREF(PyDateTime_TimeZone_UTC);
1076 return PyDateTime_TimeZone_UTC;
1077 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001078 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1079 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1080 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1081 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04001082 " timedelta(hours=24),"
1083 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001084 return NULL;
1085 }
1086
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001087 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001088}
1089
Tim Petersb0c854d2003-05-17 15:57:00 +00001090/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001091 * tzinfo helpers.
1092 */
1093
Tim Peters855fe882002-12-22 03:43:39 +00001094/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
1095 * raise TypeError and return -1.
1096 */
1097static int
1098check_tzinfo_subclass(PyObject *p)
1099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 if (p == Py_None || PyTZInfo_Check(p))
1101 return 0;
1102 PyErr_Format(PyExc_TypeError,
1103 "tzinfo argument must be None or of a tzinfo subclass, "
1104 "not type '%s'",
1105 Py_TYPE(p)->tp_name);
1106 return -1;
Tim Peters855fe882002-12-22 03:43:39 +00001107}
1108
Tim Peters2a799bf2002-12-16 20:18:38 +00001109/* If self has a tzinfo member, return a BORROWED reference to it. Else
1110 * return NULL, which is NOT AN ERROR. There are no error returns here,
1111 * and the caller must not decref the result.
1112 */
1113static PyObject *
1114get_tzinfo_member(PyObject *self)
1115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 if (PyDateTime_Check(self) && HASTZINFO(self))
1119 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1120 else if (PyTime_Check(self) && HASTZINFO(self))
1121 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001124}
1125
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001126/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
1127 * be an instance of the tzinfo class. If the method returns None, this
1128 * returns None. If the method doesn't return None or timedelta, TypeError is
1129 * raised and this returns NULL. If it returns a timedelta and the value is
1130 * out of range or isn't a whole number of minutes, ValueError is raised and
1131 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +00001132 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001133static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001134call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001135{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001136 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001139 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001141
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001142 if (tzinfo == Py_None)
1143 Py_RETURN_NONE;
1144 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1145 if (offset == Py_None || offset == NULL)
1146 return offset;
1147 if (PyDelta_Check(offset)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001148 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1149 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1150 Py_DECREF(offset);
1151 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1152 " strictly between -timedelta(hours=24) and"
1153 " timedelta(hours=24).");
1154 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 }
1156 }
1157 else {
1158 PyErr_Format(PyExc_TypeError,
1159 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001160 "timedelta, not '%.200s'",
1161 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07001162 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001163 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001165
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001166 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001167}
1168
1169/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1170 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
1171 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +00001172 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001173 * If utcoffset() returns an out of range timedelta,
1174 * ValueError is raised and this returns -1. Else *none is
1175 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001176 */
Tim Peters855fe882002-12-22 03:43:39 +00001177static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001178call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1179{
1180 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001181}
1182
Tim Peters2a799bf2002-12-16 20:18:38 +00001183/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1184 * result. tzinfo must be an instance of the tzinfo class. If dst()
1185 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001186 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00001187 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +00001188 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001189 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001190 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001191static PyObject *
1192call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001193{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001194 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001195}
1196
Tim Petersbad8ff02002-12-30 20:52:32 +00001197/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +00001198 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001199 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001200 * returns NULL. If the result is a string, we ensure it is a Unicode
1201 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001202 */
1203static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001204call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001207 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 assert(tzinfo != NULL);
1210 assert(check_tzinfo_subclass(tzinfo) >= 0);
1211 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001214 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001215
Victor Stinner20401de2016-12-09 15:24:31 +01001216 result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname,
1217 tzinfoarg, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001218
1219 if (result == NULL || result == Py_None)
1220 return result;
1221
1222 if (!PyUnicode_Check(result)) {
1223 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1224 "return None or a string, not '%s'",
1225 Py_TYPE(result)->tp_name);
1226 Py_DECREF(result);
1227 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001229
1230 return result;
Tim Peters00237032002-12-27 02:21:51 +00001231}
1232
Tim Peters2a799bf2002-12-16 20:18:38 +00001233/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1234 * stuff
1235 * ", tzinfo=" + repr(tzinfo)
1236 * before the closing ")".
1237 */
1238static PyObject *
1239append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 assert(PyUnicode_Check(repr));
1244 assert(tzinfo);
1245 if (tzinfo == Py_None)
1246 return repr;
1247 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001248 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1249 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 Py_DECREF(repr);
1251 if (temp == NULL)
1252 return NULL;
1253 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1254 Py_DECREF(temp);
1255 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001256}
1257
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001258/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1259 * stuff
1260 * ", fold=" + repr(tzinfo)
1261 * before the closing ")".
1262 */
1263static PyObject *
1264append_keyword_fold(PyObject *repr, int fold)
1265{
1266 PyObject *temp;
1267
1268 assert(PyUnicode_Check(repr));
1269 if (fold == 0)
1270 return repr;
1271 /* Get rid of the trailing ')'. */
1272 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1273 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1274 Py_DECREF(repr);
1275 if (temp == NULL)
1276 return NULL;
1277 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1278 Py_DECREF(temp);
1279 return repr;
1280}
1281
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001282static inline PyObject *
1283tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) {
1284 PyObject *tzinfo;
1285 if (rv == 1) {
1286 // Create a timezone from offset in seconds (0 returns UTC)
1287 if (tzoffset == 0) {
1288 Py_INCREF(PyDateTime_TimeZone_UTC);
1289 return PyDateTime_TimeZone_UTC;
1290 }
1291
1292 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
Miss Islington (bot)c7f54352018-08-24 12:13:57 -04001293 if (delta == NULL) {
1294 return NULL;
1295 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001296 tzinfo = new_timezone(delta, NULL);
Miss Islington (bot)c7f54352018-08-24 12:13:57 -04001297 Py_DECREF(delta);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001298 } else {
1299 tzinfo = Py_None;
1300 Py_INCREF(Py_None);
1301 }
1302
1303 return tzinfo;
1304}
1305
Tim Peters2a799bf2002-12-16 20:18:38 +00001306/* ---------------------------------------------------------------------------
1307 * String format helpers.
1308 */
1309
1310static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001311format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001312{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001313 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1315 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001316 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1318 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1319 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1324 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1325 GET_DAY(date), hours, minutes, seconds,
1326 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001327}
1328
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001329static PyObject *delta_negative(PyDateTime_Delta *self);
1330
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001331/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001332 * buflen bytes remaining. The UTC offset is gotten by calling
1333 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1334 * *buf, and that's all. Else the returned value is checked for sanity (an
1335 * integer in range), and if that's OK it's converted to an hours & minutes
1336 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001337 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001338 * Returns 0 if everything is OK. If the return value from utcoffset() is
1339 * bogus, an appropriate exception is set and -1 is returned.
1340 */
1341static int
Tim Peters328fff72002-12-20 01:31:27 +00001342format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001344{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001345 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001346 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001350
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001351 offset = call_utcoffset(tzinfo, tzinfoarg);
1352 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001354 if (offset == Py_None) {
1355 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 *buf = '\0';
1357 return 0;
1358 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001359 /* Offset is normalized, so it is negative if days < 0 */
1360 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001362 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001363 if (offset == NULL)
1364 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001366 else {
1367 sign = '+';
1368 }
1369 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001370 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001371 seconds = GET_TD_SECONDS(offset);
1372 Py_DECREF(offset);
1373 minutes = divmod(seconds, 60, &seconds);
1374 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001375 if (microseconds) {
1376 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1377 hours, sep, minutes, sep, seconds, microseconds);
1378 return 0;
1379 }
1380 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001381 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1382 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001383 return 0;
1384 }
1385 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001387}
1388
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001389static PyObject *
1390make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 PyObject *temp;
1393 PyObject *tzinfo = get_tzinfo_member(object);
1394 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001395 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 if (Zreplacement == NULL)
1398 return NULL;
1399 if (tzinfo == Py_None || tzinfo == NULL)
1400 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 assert(tzinfoarg != NULL);
1403 temp = call_tzname(tzinfo, tzinfoarg);
1404 if (temp == NULL)
1405 goto Error;
1406 if (temp == Py_None) {
1407 Py_DECREF(temp);
1408 return Zreplacement;
1409 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 assert(PyUnicode_Check(temp));
1412 /* Since the tzname is getting stuffed into the
1413 * format, we have to double any % signs so that
1414 * strftime doesn't treat them as format codes.
1415 */
1416 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001417 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 Py_DECREF(temp);
1419 if (Zreplacement == NULL)
1420 return NULL;
1421 if (!PyUnicode_Check(Zreplacement)) {
1422 PyErr_SetString(PyExc_TypeError,
1423 "tzname.replace() did not return a string");
1424 goto Error;
1425 }
1426 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001427
1428 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 Py_DECREF(Zreplacement);
1430 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001431}
1432
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001433static PyObject *
1434make_freplacement(PyObject *object)
1435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 char freplacement[64];
1437 if (PyTime_Check(object))
1438 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1439 else if (PyDateTime_Check(object))
1440 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1441 else
1442 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001445}
1446
Tim Peters2a799bf2002-12-16 20:18:38 +00001447/* I sure don't want to reproduce the strftime code from the time module,
1448 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001449 * giving special meanings to the %z, %Z and %f format codes via a
1450 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001451 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1452 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001453 */
1454static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001455wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1461 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1462 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 const char *pin; /* pointer to next char in input format */
1465 Py_ssize_t flen; /* length of input format */
1466 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 PyObject *newfmt = NULL; /* py string, the output format */
1469 char *pnew; /* pointer to available byte in output format */
1470 size_t totalnew; /* number bytes total in output format buffer,
1471 exclusive of trailing \0 */
1472 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 const char *ptoappend; /* ptr to string to append to output buffer */
1475 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 assert(object && format && timetuple);
1478 assert(PyUnicode_Check(format));
1479 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001480 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 if (!pin)
1482 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 /* Scan the input format, looking for %z/%Z/%f escapes, building
1485 * a new format. Since computing the replacements for those codes
1486 * is expensive, don't unless they're actually used.
1487 */
1488 if (flen > INT_MAX - 1) {
1489 PyErr_NoMemory();
1490 goto Done;
1491 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 totalnew = flen + 1; /* realistic if no %z/%Z */
1494 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1495 if (newfmt == NULL) goto Done;
1496 pnew = PyBytes_AsString(newfmt);
1497 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 while ((ch = *pin++) != '\0') {
1500 if (ch != '%') {
1501 ptoappend = pin - 1;
1502 ntoappend = 1;
1503 }
1504 else if ((ch = *pin++) == '\0') {
1505 /* There's a lone trailing %; doesn't make sense. */
1506 PyErr_SetString(PyExc_ValueError, "strftime format "
1507 "ends with raw %");
1508 goto Done;
1509 }
1510 /* A % has been seen and ch is the character after it. */
1511 else if (ch == 'z') {
1512 if (zreplacement == NULL) {
1513 /* format utcoffset */
1514 char buf[100];
1515 PyObject *tzinfo = get_tzinfo_member(object);
1516 zreplacement = PyBytes_FromStringAndSize("", 0);
1517 if (zreplacement == NULL) goto Done;
1518 if (tzinfo != Py_None && tzinfo != NULL) {
1519 assert(tzinfoarg != NULL);
1520 if (format_utcoffset(buf,
1521 sizeof(buf),
1522 "",
1523 tzinfo,
1524 tzinfoarg) < 0)
1525 goto Done;
1526 Py_DECREF(zreplacement);
1527 zreplacement =
1528 PyBytes_FromStringAndSize(buf,
1529 strlen(buf));
1530 if (zreplacement == NULL)
1531 goto Done;
1532 }
1533 }
1534 assert(zreplacement != NULL);
1535 ptoappend = PyBytes_AS_STRING(zreplacement);
1536 ntoappend = PyBytes_GET_SIZE(zreplacement);
1537 }
1538 else if (ch == 'Z') {
1539 /* format tzname */
1540 if (Zreplacement == NULL) {
1541 Zreplacement = make_Zreplacement(object,
1542 tzinfoarg);
1543 if (Zreplacement == NULL)
1544 goto Done;
1545 }
1546 assert(Zreplacement != NULL);
1547 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001548 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001550 if (ptoappend == NULL)
1551 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 }
1553 else if (ch == 'f') {
1554 /* format microseconds */
1555 if (freplacement == NULL) {
1556 freplacement = make_freplacement(object);
1557 if (freplacement == NULL)
1558 goto Done;
1559 }
1560 assert(freplacement != NULL);
1561 assert(PyBytes_Check(freplacement));
1562 ptoappend = PyBytes_AS_STRING(freplacement);
1563 ntoappend = PyBytes_GET_SIZE(freplacement);
1564 }
1565 else {
1566 /* percent followed by neither z nor Z */
1567 ptoappend = pin - 2;
1568 ntoappend = 2;
1569 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 /* Append the ntoappend chars starting at ptoappend to
1572 * the new format.
1573 */
1574 if (ntoappend == 0)
1575 continue;
1576 assert(ptoappend != NULL);
1577 assert(ntoappend > 0);
1578 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001579 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 PyErr_NoMemory();
1581 goto Done;
1582 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001583 totalnew <<= 1;
1584 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 pnew = PyBytes_AsString(newfmt) + usednew;
1587 }
1588 memcpy(pnew, ptoappend, ntoappend);
1589 pnew += ntoappend;
1590 usednew += ntoappend;
1591 assert(usednew <= totalnew);
1592 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1595 goto Done;
1596 {
1597 PyObject *format;
1598 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 if (time == NULL)
1601 goto Done;
1602 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1603 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001604 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1605 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 Py_DECREF(format);
1607 }
1608 Py_DECREF(time);
1609 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001610 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 Py_XDECREF(freplacement);
1612 Py_XDECREF(zreplacement);
1613 Py_XDECREF(Zreplacement);
1614 Py_XDECREF(newfmt);
1615 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001616}
1617
Tim Peters2a799bf2002-12-16 20:18:38 +00001618/* ---------------------------------------------------------------------------
1619 * Wrap functions from the time module. These aren't directly available
1620 * from C. Perhaps they should be.
1621 */
1622
1623/* Call time.time() and return its result (a Python float). */
1624static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001625time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 PyObject *result = NULL;
1628 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001631 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001632
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001633 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 Py_DECREF(time);
1635 }
1636 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001637}
1638
1639/* Build a time.struct_time. The weekday and day number are automatically
1640 * computed from the y,m,d args.
1641 */
1642static PyObject *
1643build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001646 PyObject *result;
1647 _Py_IDENTIFIER(struct_time);
1648 PyObject *args;
1649
Tim Peters2a799bf2002-12-16 20:18:38 +00001650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001652 if (time == NULL) {
1653 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 }
Victor Stinner2b635972016-12-09 00:38:16 +01001655
1656 args = Py_BuildValue("iiiiiiiii",
1657 y, m, d,
1658 hh, mm, ss,
1659 weekday(y, m, d),
1660 days_before_month(y, m) + d,
1661 dstflag);
1662 if (args == NULL) {
1663 Py_DECREF(time);
1664 return NULL;
1665 }
1666
1667 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1668 args, NULL);
1669 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001670 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001672}
1673
1674/* ---------------------------------------------------------------------------
1675 * Miscellaneous helpers.
1676 */
1677
Mark Dickinsone94c6792009-02-02 20:36:42 +00001678/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001679 * The comparisons here all most naturally compute a cmp()-like result.
1680 * This little helper turns that into a bool result for rich comparisons.
1681 */
1682static PyObject *
1683diff_to_bool(int diff, int op)
1684{
stratakise8b19652017-11-02 11:32:54 +01001685 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001686}
1687
Tim Peters07534a62003-02-07 22:50:28 +00001688/* Raises a "can't compare" TypeError and returns NULL. */
1689static PyObject *
1690cmperror(PyObject *a, PyObject *b)
1691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 PyErr_Format(PyExc_TypeError,
1693 "can't compare %s to %s",
1694 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1695 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001696}
1697
Tim Peters2a799bf2002-12-16 20:18:38 +00001698/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001699 * Cached Python objects; these are set by the module init function.
1700 */
1701
1702/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703static PyObject *us_per_ms = NULL; /* 1000 */
1704static PyObject *us_per_second = NULL; /* 1000000 */
1705static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001706static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1707static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1708static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001709static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1710
Tim Peters2a799bf2002-12-16 20:18:38 +00001711/* ---------------------------------------------------------------------------
1712 * Class implementations.
1713 */
1714
1715/*
1716 * PyDateTime_Delta implementation.
1717 */
1718
1719/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001721 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001722 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1723 * due to ubiquitous overflow possibilities.
1724 */
1725static PyObject *
1726delta_to_microseconds(PyDateTime_Delta *self)
1727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 PyObject *x1 = NULL;
1729 PyObject *x2 = NULL;
1730 PyObject *x3 = NULL;
1731 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001733 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1734 if (x1 == NULL)
1735 goto Done;
1736 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1737 if (x2 == NULL)
1738 goto Done;
1739 Py_DECREF(x1);
1740 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 /* x2 has days in seconds */
1743 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1744 if (x1 == NULL)
1745 goto Done;
1746 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1747 if (x3 == NULL)
1748 goto Done;
1749 Py_DECREF(x1);
1750 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001751 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001752
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 /* x3 has days+seconds in seconds */
1754 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1755 if (x1 == NULL)
1756 goto Done;
1757 Py_DECREF(x3);
1758 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 /* x1 has days+seconds in us */
1761 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1762 if (x2 == NULL)
1763 goto Done;
1764 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001765 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001766
1767Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 Py_XDECREF(x1);
1769 Py_XDECREF(x2);
1770 Py_XDECREF(x3);
1771 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001772}
1773
Serhiy Storchaka95949422013-08-27 19:40:23 +03001774/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001775 */
1776static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001777microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 int us;
1780 int s;
1781 int d;
1782 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 PyObject *tuple = NULL;
1785 PyObject *num = NULL;
1786 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001787
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001788 assert(PyLong_CheckExact(pyus));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 tuple = PyNumber_Divmod(pyus, us_per_second);
1790 if (tuple == NULL)
1791 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 num = PyTuple_GetItem(tuple, 1); /* us */
1794 if (num == NULL)
1795 goto Done;
1796 temp = PyLong_AsLong(num);
1797 num = NULL;
1798 if (temp == -1 && PyErr_Occurred())
1799 goto Done;
1800 assert(0 <= temp && temp < 1000000);
1801 us = (int)temp;
1802 if (us < 0) {
1803 /* The divisor was positive, so this must be an error. */
1804 assert(PyErr_Occurred());
1805 goto Done;
1806 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1809 if (num == NULL)
1810 goto Done;
1811 Py_INCREF(num);
1812 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 tuple = PyNumber_Divmod(num, seconds_per_day);
1815 if (tuple == NULL)
1816 goto Done;
1817 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 num = PyTuple_GetItem(tuple, 1); /* seconds */
1820 if (num == NULL)
1821 goto Done;
1822 temp = PyLong_AsLong(num);
1823 num = NULL;
1824 if (temp == -1 && PyErr_Occurred())
1825 goto Done;
1826 assert(0 <= temp && temp < 24*3600);
1827 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 if (s < 0) {
1830 /* The divisor was positive, so this must be an error. */
1831 assert(PyErr_Occurred());
1832 goto Done;
1833 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1836 if (num == NULL)
1837 goto Done;
1838 Py_INCREF(num);
1839 temp = PyLong_AsLong(num);
1840 if (temp == -1 && PyErr_Occurred())
1841 goto Done;
1842 d = (int)temp;
1843 if ((long)d != temp) {
1844 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1845 "large to fit in a C int");
1846 goto Done;
1847 }
1848 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001849
1850Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 Py_XDECREF(tuple);
1852 Py_XDECREF(num);
1853 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001854}
1855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856#define microseconds_to_delta(pymicros) \
1857 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001858
Tim Peters2a799bf2002-12-16 20:18:38 +00001859static PyObject *
1860multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 PyObject *pyus_in;
1863 PyObject *pyus_out;
1864 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 pyus_in = delta_to_microseconds(delta);
1867 if (pyus_in == NULL)
1868 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1871 Py_DECREF(pyus_in);
1872 if (pyus_out == NULL)
1873 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 result = microseconds_to_delta(pyus_out);
1876 Py_DECREF(pyus_out);
1877 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001878}
1879
1880static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001881get_float_as_integer_ratio(PyObject *floatobj)
1882{
1883 PyObject *ratio;
1884
1885 assert(floatobj && PyFloat_Check(floatobj));
1886 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1887 if (ratio == NULL) {
1888 return NULL;
1889 }
1890 if (!PyTuple_Check(ratio)) {
1891 PyErr_Format(PyExc_TypeError,
1892 "unexpected return type from as_integer_ratio(): "
1893 "expected tuple, got '%.200s'",
1894 Py_TYPE(ratio)->tp_name);
1895 Py_DECREF(ratio);
1896 return NULL;
1897 }
1898 if (PyTuple_Size(ratio) != 2) {
1899 PyErr_SetString(PyExc_ValueError,
1900 "as_integer_ratio() must return a 2-tuple");
1901 Py_DECREF(ratio);
1902 return NULL;
1903 }
1904 return ratio;
1905}
1906
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001907/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001908static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001909multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001910{
1911 PyObject *result = NULL;
1912 PyObject *pyus_in = NULL, *temp, *pyus_out;
1913 PyObject *ratio = NULL;
1914
1915 pyus_in = delta_to_microseconds(delta);
1916 if (pyus_in == NULL)
1917 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001918 ratio = get_float_as_integer_ratio(floatobj);
1919 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001920 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001921 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001922 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001923 Py_DECREF(pyus_in);
1924 pyus_in = NULL;
1925 if (temp == NULL)
1926 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001927 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001928 Py_DECREF(temp);
1929 if (pyus_out == NULL)
1930 goto error;
1931 result = microseconds_to_delta(pyus_out);
1932 Py_DECREF(pyus_out);
1933 error:
1934 Py_XDECREF(pyus_in);
1935 Py_XDECREF(ratio);
1936
1937 return result;
1938}
1939
1940static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001941divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1942{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 PyObject *pyus_in;
1944 PyObject *pyus_out;
1945 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 pyus_in = delta_to_microseconds(delta);
1948 if (pyus_in == NULL)
1949 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1952 Py_DECREF(pyus_in);
1953 if (pyus_out == NULL)
1954 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 result = microseconds_to_delta(pyus_out);
1957 Py_DECREF(pyus_out);
1958 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001959}
1960
1961static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001962divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 PyObject *pyus_left;
1965 PyObject *pyus_right;
1966 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 pyus_left = delta_to_microseconds(left);
1969 if (pyus_left == NULL)
1970 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 pyus_right = delta_to_microseconds(right);
1973 if (pyus_right == NULL) {
1974 Py_DECREF(pyus_left);
1975 return NULL;
1976 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1979 Py_DECREF(pyus_left);
1980 Py_DECREF(pyus_right);
1981 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001982}
1983
1984static PyObject *
1985truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 PyObject *pyus_left;
1988 PyObject *pyus_right;
1989 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 pyus_left = delta_to_microseconds(left);
1992 if (pyus_left == NULL)
1993 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 pyus_right = delta_to_microseconds(right);
1996 if (pyus_right == NULL) {
1997 Py_DECREF(pyus_left);
1998 return NULL;
1999 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2002 Py_DECREF(pyus_left);
2003 Py_DECREF(pyus_right);
2004 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002005}
2006
2007static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002008truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2009{
2010 PyObject *result;
2011 PyObject *pyus_in, *pyus_out;
2012 pyus_in = delta_to_microseconds(delta);
2013 if (pyus_in == NULL)
2014 return NULL;
2015 pyus_out = divide_nearest(pyus_in, i);
2016 Py_DECREF(pyus_in);
2017 if (pyus_out == NULL)
2018 return NULL;
2019 result = microseconds_to_delta(pyus_out);
2020 Py_DECREF(pyus_out);
2021
2022 return result;
2023}
2024
2025static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002026delta_add(PyObject *left, PyObject *right)
2027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2031 /* delta + delta */
2032 /* The C-level additions can't overflow because of the
2033 * invariant bounds.
2034 */
2035 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2036 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2037 int microseconds = GET_TD_MICROSECONDS(left) +
2038 GET_TD_MICROSECONDS(right);
2039 result = new_delta(days, seconds, microseconds, 1);
2040 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 if (result == Py_NotImplemented)
2043 Py_INCREF(result);
2044 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002045}
2046
2047static PyObject *
2048delta_negative(PyDateTime_Delta *self)
2049{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 return new_delta(-GET_TD_DAYS(self),
2051 -GET_TD_SECONDS(self),
2052 -GET_TD_MICROSECONDS(self),
2053 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002054}
2055
2056static PyObject *
2057delta_positive(PyDateTime_Delta *self)
2058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 /* Could optimize this (by returning self) if this isn't a
2060 * subclass -- but who uses unary + ? Approximately nobody.
2061 */
2062 return new_delta(GET_TD_DAYS(self),
2063 GET_TD_SECONDS(self),
2064 GET_TD_MICROSECONDS(self),
2065 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002066}
2067
2068static PyObject *
2069delta_abs(PyDateTime_Delta *self)
2070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 assert(GET_TD_MICROSECONDS(self) >= 0);
2074 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 if (GET_TD_DAYS(self) < 0)
2077 result = delta_negative(self);
2078 else
2079 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002082}
2083
2084static PyObject *
2085delta_subtract(PyObject *left, PyObject *right)
2086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2090 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002091 /* The C-level additions can't overflow because of the
2092 * invariant bounds.
2093 */
2094 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2095 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2096 int microseconds = GET_TD_MICROSECONDS(left) -
2097 GET_TD_MICROSECONDS(right);
2098 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 if (result == Py_NotImplemented)
2102 Py_INCREF(result);
2103 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002104}
2105
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002106static int
2107delta_cmp(PyObject *self, PyObject *other)
2108{
2109 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2110 if (diff == 0) {
2111 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2112 if (diff == 0)
2113 diff = GET_TD_MICROSECONDS(self) -
2114 GET_TD_MICROSECONDS(other);
2115 }
2116 return diff;
2117}
2118
Tim Peters2a799bf2002-12-16 20:18:38 +00002119static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002120delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002123 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 return diff_to_bool(diff, op);
2125 }
2126 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002127 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002129}
2130
2131static PyObject *delta_getstate(PyDateTime_Delta *self);
2132
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002133static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002134delta_hash(PyDateTime_Delta *self)
2135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 if (self->hashcode == -1) {
2137 PyObject *temp = delta_getstate(self);
2138 if (temp != NULL) {
2139 self->hashcode = PyObject_Hash(temp);
2140 Py_DECREF(temp);
2141 }
2142 }
2143 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002144}
2145
2146static PyObject *
2147delta_multiply(PyObject *left, PyObject *right)
2148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 if (PyDelta_Check(left)) {
2152 /* delta * ??? */
2153 if (PyLong_Check(right))
2154 result = multiply_int_timedelta(right,
2155 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002156 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002157 result = multiply_truedivide_timedelta_float(
2158 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 }
2160 else if (PyLong_Check(left))
2161 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002162 (PyDateTime_Delta *) right);
2163 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002164 result = multiply_truedivide_timedelta_float(
2165 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 if (result == Py_NotImplemented)
2168 Py_INCREF(result);
2169 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002170}
2171
2172static PyObject *
2173delta_divide(PyObject *left, PyObject *right)
2174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 if (PyDelta_Check(left)) {
2178 /* delta * ??? */
2179 if (PyLong_Check(right))
2180 result = divide_timedelta_int(
2181 (PyDateTime_Delta *)left,
2182 right);
2183 else if (PyDelta_Check(right))
2184 result = divide_timedelta_timedelta(
2185 (PyDateTime_Delta *)left,
2186 (PyDateTime_Delta *)right);
2187 }
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
Mark Dickinson7c186e22010-04-20 22:32:49 +00002194static PyObject *
2195delta_truedivide(PyObject *left, PyObject *right)
2196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 if (PyDelta_Check(left)) {
2200 if (PyDelta_Check(right))
2201 result = truedivide_timedelta_timedelta(
2202 (PyDateTime_Delta *)left,
2203 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002204 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002205 result = multiply_truedivide_timedelta_float(
2206 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002207 else if (PyLong_Check(right))
2208 result = truedivide_timedelta_int(
2209 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002212 if (result == Py_NotImplemented)
2213 Py_INCREF(result);
2214 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002215}
2216
2217static PyObject *
2218delta_remainder(PyObject *left, PyObject *right)
2219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 PyObject *pyus_left;
2221 PyObject *pyus_right;
2222 PyObject *pyus_remainder;
2223 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002224
Brian Curtindfc80e32011-08-10 20:28:54 -05002225 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2226 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2229 if (pyus_left == NULL)
2230 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2233 if (pyus_right == NULL) {
2234 Py_DECREF(pyus_left);
2235 return NULL;
2236 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002238 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2239 Py_DECREF(pyus_left);
2240 Py_DECREF(pyus_right);
2241 if (pyus_remainder == NULL)
2242 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 remainder = microseconds_to_delta(pyus_remainder);
2245 Py_DECREF(pyus_remainder);
2246 if (remainder == NULL)
2247 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002250}
2251
2252static PyObject *
2253delta_divmod(PyObject *left, PyObject *right)
2254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 PyObject *pyus_left;
2256 PyObject *pyus_right;
2257 PyObject *divmod;
2258 PyObject *delta;
2259 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002260
Brian Curtindfc80e32011-08-10 20:28:54 -05002261 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2262 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2265 if (pyus_left == NULL)
2266 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2269 if (pyus_right == NULL) {
2270 Py_DECREF(pyus_left);
2271 return NULL;
2272 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2275 Py_DECREF(pyus_left);
2276 Py_DECREF(pyus_right);
2277 if (divmod == NULL)
2278 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 assert(PyTuple_Size(divmod) == 2);
2281 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2282 if (delta == NULL) {
2283 Py_DECREF(divmod);
2284 return NULL;
2285 }
2286 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2287 Py_DECREF(delta);
2288 Py_DECREF(divmod);
2289 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002290}
2291
Tim Peters2a799bf2002-12-16 20:18:38 +00002292/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2293 * timedelta constructor. sofar is the # of microseconds accounted for
2294 * so far, and there are factor microseconds per current unit, the number
2295 * of which is given by num. num * factor is added to sofar in a
2296 * numerically careful way, and that's the result. Any fractional
2297 * microseconds left over (this can happen if num is a float type) are
2298 * added into *leftover.
2299 * Note that there are many ways this can give an error (NULL) return.
2300 */
2301static PyObject *
2302accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2303 double *leftover)
2304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 PyObject *prod;
2306 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002310 if (PyLong_Check(num)) {
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002311 prod = PyNumber_Multiply(factor, num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 if (prod == NULL)
2313 return NULL;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002314 assert(PyLong_CheckExact(prod));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 sum = PyNumber_Add(sofar, prod);
2316 Py_DECREF(prod);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002317 assert(sum == NULL || PyLong_CheckExact(sum));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 return sum;
2319 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002321 if (PyFloat_Check(num)) {
2322 double dnum;
2323 double fracpart;
2324 double intpart;
2325 PyObject *x;
2326 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002328 /* The Plan: decompose num into an integer part and a
2329 * fractional part, num = intpart + fracpart.
2330 * Then num * factor ==
2331 * intpart * factor + fracpart * factor
2332 * and the LHS can be computed exactly in long arithmetic.
2333 * The RHS is again broken into an int part and frac part.
2334 * and the frac part is added into *leftover.
2335 */
2336 dnum = PyFloat_AsDouble(num);
2337 if (dnum == -1.0 && PyErr_Occurred())
2338 return NULL;
2339 fracpart = modf(dnum, &intpart);
2340 x = PyLong_FromDouble(intpart);
2341 if (x == NULL)
2342 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 prod = PyNumber_Multiply(x, factor);
2345 Py_DECREF(x);
2346 if (prod == NULL)
2347 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 sum = PyNumber_Add(sofar, prod);
2350 Py_DECREF(prod);
2351 if (sum == NULL)
2352 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002354 if (fracpart == 0.0)
2355 return sum;
2356 /* So far we've lost no information. Dealing with the
2357 * fractional part requires float arithmetic, and may
2358 * lose a little info.
2359 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002360 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 dnum *= fracpart;
2364 fracpart = modf(dnum, &intpart);
2365 x = PyLong_FromDouble(intpart);
2366 if (x == NULL) {
2367 Py_DECREF(sum);
2368 return NULL;
2369 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002371 y = PyNumber_Add(sum, x);
2372 Py_DECREF(sum);
2373 Py_DECREF(x);
2374 *leftover += fracpart;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002375 assert(y == NULL || PyLong_CheckExact(y));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 return y;
2377 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 PyErr_Format(PyExc_TypeError,
2380 "unsupported type for timedelta %s component: %s",
2381 tag, Py_TYPE(num)->tp_name);
2382 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002383}
2384
2385static PyObject *
2386delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 /* Argument objects. */
2391 PyObject *day = NULL;
2392 PyObject *second = NULL;
2393 PyObject *us = NULL;
2394 PyObject *ms = NULL;
2395 PyObject *minute = NULL;
2396 PyObject *hour = NULL;
2397 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 PyObject *x = NULL; /* running sum of microseconds */
2400 PyObject *y = NULL; /* temp sum of microseconds */
2401 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 static char *keywords[] = {
2404 "days", "seconds", "microseconds", "milliseconds",
2405 "minutes", "hours", "weeks", NULL
2406 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2409 keywords,
2410 &day, &second, &us,
2411 &ms, &minute, &hour, &week) == 0)
2412 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 x = PyLong_FromLong(0);
2415 if (x == NULL)
2416 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418#define CLEANUP \
2419 Py_DECREF(x); \
2420 x = y; \
2421 if (x == NULL) \
2422 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002425 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 CLEANUP;
2427 }
2428 if (ms) {
2429 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2430 CLEANUP;
2431 }
2432 if (second) {
2433 y = accum("seconds", x, second, us_per_second, &leftover_us);
2434 CLEANUP;
2435 }
2436 if (minute) {
2437 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2438 CLEANUP;
2439 }
2440 if (hour) {
2441 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2442 CLEANUP;
2443 }
2444 if (day) {
2445 y = accum("days", x, day, us_per_day, &leftover_us);
2446 CLEANUP;
2447 }
2448 if (week) {
2449 y = accum("weeks", x, week, us_per_week, &leftover_us);
2450 CLEANUP;
2451 }
2452 if (leftover_us) {
2453 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002454 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002455 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002456 PyObject *temp;
2457
Victor Stinner69cc4872015-09-08 23:58:54 +02002458 whole_us = round(leftover_us);
2459 if (fabs(whole_us - leftover_us) == 0.5) {
2460 /* We're exactly halfway between two integers. In order
2461 * to do round-half-to-even, we must determine whether x
2462 * is odd. Note that x is odd when it's last bit is 1. The
2463 * code below uses bitwise and operation to check the last
2464 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002465 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002466 if (temp == NULL) {
2467 Py_DECREF(x);
2468 goto Done;
2469 }
2470 x_is_odd = PyObject_IsTrue(temp);
2471 Py_DECREF(temp);
2472 if (x_is_odd == -1) {
2473 Py_DECREF(x);
2474 goto Done;
2475 }
2476 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2477 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002478
Victor Stinner36a5a062013-08-28 01:53:39 +02002479 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 if (temp == NULL) {
2482 Py_DECREF(x);
2483 goto Done;
2484 }
2485 y = PyNumber_Add(x, temp);
2486 Py_DECREF(temp);
2487 CLEANUP;
2488 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 self = microseconds_to_delta_ex(x, type);
2491 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002492Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002494
2495#undef CLEANUP
2496}
2497
2498static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002499delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002501 return (GET_TD_DAYS(self) != 0
2502 || GET_TD_SECONDS(self) != 0
2503 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002504}
2505
2506static PyObject *
2507delta_repr(PyDateTime_Delta *self)
2508{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002509 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002510
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002511 if (args == NULL) {
2512 return NULL;
2513 }
2514
2515 const char *sep = "";
2516
2517 if (GET_TD_DAYS(self) != 0) {
2518 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2519 if (args == NULL) {
2520 return NULL;
2521 }
2522 sep = ", ";
2523 }
2524
2525 if (GET_TD_SECONDS(self) != 0) {
2526 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2527 GET_TD_SECONDS(self)));
2528 if (args == NULL) {
2529 return NULL;
2530 }
2531 sep = ", ";
2532 }
2533
2534 if (GET_TD_MICROSECONDS(self) != 0) {
2535 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2536 GET_TD_MICROSECONDS(self)));
2537 if (args == NULL) {
2538 return NULL;
2539 }
2540 }
2541
2542 if (PyUnicode_GET_LENGTH(args) == 0) {
2543 Py_SETREF(args, PyUnicode_FromString("0"));
2544 if (args == NULL) {
2545 return NULL;
2546 }
2547 }
2548
2549 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2550 args);
2551 Py_DECREF(args);
2552 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002553}
2554
2555static PyObject *
2556delta_str(PyDateTime_Delta *self)
2557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558 int us = GET_TD_MICROSECONDS(self);
2559 int seconds = GET_TD_SECONDS(self);
2560 int minutes = divmod(seconds, 60, &seconds);
2561 int hours = divmod(minutes, 60, &minutes);
2562 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 if (days) {
2565 if (us)
2566 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2567 days, (days == 1 || days == -1) ? "" : "s",
2568 hours, minutes, seconds, us);
2569 else
2570 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2571 days, (days == 1 || days == -1) ? "" : "s",
2572 hours, minutes, seconds);
2573 } else {
2574 if (us)
2575 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2576 hours, minutes, seconds, us);
2577 else
2578 return PyUnicode_FromFormat("%d:%02d:%02d",
2579 hours, minutes, seconds);
2580 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002581
Tim Peters2a799bf2002-12-16 20:18:38 +00002582}
2583
Tim Peters371935f2003-02-01 01:52:50 +00002584/* Pickle support, a simple use of __reduce__. */
2585
Tim Petersb57f8f02003-02-01 02:54:15 +00002586/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002587static PyObject *
2588delta_getstate(PyDateTime_Delta *self)
2589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002590 return Py_BuildValue("iii", GET_TD_DAYS(self),
2591 GET_TD_SECONDS(self),
2592 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002593}
2594
Tim Peters2a799bf2002-12-16 20:18:38 +00002595static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002596delta_total_seconds(PyObject *self)
2597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 PyObject *total_seconds;
2599 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2602 if (total_microseconds == NULL)
2603 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002604
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002605 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002609}
2610
2611static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002612delta_reduce(PyDateTime_Delta* self)
2613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002614 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002615}
2616
2617#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2618
2619static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 {"days", T_INT, OFFSET(days), READONLY,
2622 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 {"seconds", T_INT, OFFSET(seconds), READONLY,
2625 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002627 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2628 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2629 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002630};
2631
2632static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2634 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2637 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002640};
2641
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002642static const char delta_doc[] =
Miss Islington (bot)ef7f29f2018-10-19 16:02:13 -07002643PyDoc_STR("Difference between two datetime values.\n\n"
2644 "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, "
2645 "minutes=0, hours=0, weeks=0)\n\n"
2646 "All arguments are optional and default to 0.\n"
2647 "Arguments may be integers or floats, and may be positive or negative.");
Tim Peters2a799bf2002-12-16 20:18:38 +00002648
2649static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 delta_add, /* nb_add */
2651 delta_subtract, /* nb_subtract */
2652 delta_multiply, /* nb_multiply */
2653 delta_remainder, /* nb_remainder */
2654 delta_divmod, /* nb_divmod */
2655 0, /* nb_power */
2656 (unaryfunc)delta_negative, /* nb_negative */
2657 (unaryfunc)delta_positive, /* nb_positive */
2658 (unaryfunc)delta_abs, /* nb_absolute */
2659 (inquiry)delta_bool, /* nb_bool */
2660 0, /*nb_invert*/
2661 0, /*nb_lshift*/
2662 0, /*nb_rshift*/
2663 0, /*nb_and*/
2664 0, /*nb_xor*/
2665 0, /*nb_or*/
2666 0, /*nb_int*/
2667 0, /*nb_reserved*/
2668 0, /*nb_float*/
2669 0, /*nb_inplace_add*/
2670 0, /*nb_inplace_subtract*/
2671 0, /*nb_inplace_multiply*/
2672 0, /*nb_inplace_remainder*/
2673 0, /*nb_inplace_power*/
2674 0, /*nb_inplace_lshift*/
2675 0, /*nb_inplace_rshift*/
2676 0, /*nb_inplace_and*/
2677 0, /*nb_inplace_xor*/
2678 0, /*nb_inplace_or*/
2679 delta_divide, /* nb_floor_divide */
2680 delta_truedivide, /* nb_true_divide */
2681 0, /* nb_inplace_floor_divide */
2682 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002683};
2684
2685static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002686 PyVarObject_HEAD_INIT(NULL, 0)
2687 "datetime.timedelta", /* tp_name */
2688 sizeof(PyDateTime_Delta), /* tp_basicsize */
2689 0, /* tp_itemsize */
2690 0, /* tp_dealloc */
2691 0, /* tp_print */
2692 0, /* tp_getattr */
2693 0, /* tp_setattr */
2694 0, /* tp_reserved */
2695 (reprfunc)delta_repr, /* tp_repr */
2696 &delta_as_number, /* tp_as_number */
2697 0, /* tp_as_sequence */
2698 0, /* tp_as_mapping */
2699 (hashfunc)delta_hash, /* tp_hash */
2700 0, /* tp_call */
2701 (reprfunc)delta_str, /* tp_str */
2702 PyObject_GenericGetAttr, /* tp_getattro */
2703 0, /* tp_setattro */
2704 0, /* tp_as_buffer */
2705 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2706 delta_doc, /* tp_doc */
2707 0, /* tp_traverse */
2708 0, /* tp_clear */
2709 delta_richcompare, /* tp_richcompare */
2710 0, /* tp_weaklistoffset */
2711 0, /* tp_iter */
2712 0, /* tp_iternext */
2713 delta_methods, /* tp_methods */
2714 delta_members, /* tp_members */
2715 0, /* tp_getset */
2716 0, /* tp_base */
2717 0, /* tp_dict */
2718 0, /* tp_descr_get */
2719 0, /* tp_descr_set */
2720 0, /* tp_dictoffset */
2721 0, /* tp_init */
2722 0, /* tp_alloc */
2723 delta_new, /* tp_new */
2724 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002725};
2726
2727/*
2728 * PyDateTime_Date implementation.
2729 */
2730
2731/* Accessor properties. */
2732
2733static PyObject *
2734date_year(PyDateTime_Date *self, void *unused)
2735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002736 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002737}
2738
2739static PyObject *
2740date_month(PyDateTime_Date *self, void *unused)
2741{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002742 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002743}
2744
2745static PyObject *
2746date_day(PyDateTime_Date *self, void *unused)
2747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002748 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002749}
2750
2751static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002752 {"year", (getter)date_year},
2753 {"month", (getter)date_month},
2754 {"day", (getter)date_day},
2755 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002756};
2757
2758/* Constructors. */
2759
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002760static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002761
Tim Peters2a799bf2002-12-16 20:18:38 +00002762static PyObject *
2763date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002765 PyObject *self = NULL;
2766 PyObject *state;
2767 int year;
2768 int month;
2769 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002771 /* Check for invocation from pickle with __getstate__ state */
2772 if (PyTuple_GET_SIZE(args) == 1 &&
2773 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2774 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2775 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2776 {
2777 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002779 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2780 if (me != NULL) {
2781 char *pdata = PyBytes_AS_STRING(state);
2782 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2783 me->hashcode = -1;
2784 }
2785 return (PyObject *)me;
2786 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002788 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2789 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002790 self = new_date_ex(year, month, day, type);
2791 }
2792 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002793}
2794
2795/* Return new date from localtime(t). */
2796static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002797date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002798{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002799 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002800 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002801
Victor Stinnere4a994d2015-03-30 01:10:14 +02002802 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002803 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002804
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002805 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002806 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002807
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002808 return new_date_subclass_ex(tm.tm_year + 1900,
2809 tm.tm_mon + 1,
2810 tm.tm_mday,
2811 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002812}
2813
2814/* Return new date from current time.
2815 * We say this is equivalent to fromtimestamp(time.time()), and the
2816 * only way to be sure of that is to *call* time.time(). That's not
2817 * generally the same as calling C's time.
2818 */
2819static PyObject *
2820date_today(PyObject *cls, PyObject *dummy)
2821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 PyObject *time;
2823 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002824 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002826 time = time_time();
2827 if (time == NULL)
2828 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002830 /* Note well: today() is a class method, so this may not call
2831 * date.fromtimestamp. For example, it may call
2832 * datetime.fromtimestamp. That's why we need all the accuracy
2833 * time.time() delivers; if someone were gonzo about optimization,
2834 * date.today() could get away with plain C time().
2835 */
Victor Stinner20401de2016-12-09 15:24:31 +01002836 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2837 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002838 Py_DECREF(time);
2839 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002840}
2841
2842/* Return new date from given timestamp (Python timestamp -- a double). */
2843static PyObject *
2844date_fromtimestamp(PyObject *cls, PyObject *args)
2845{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002846 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002848
Victor Stinner5d272cc2012-03-13 13:35:55 +01002849 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2850 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002852}
2853
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002854
Tim Peters2a799bf2002-12-16 20:18:38 +00002855/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2856 * the ordinal is out of range.
2857 */
2858static PyObject *
2859date_fromordinal(PyObject *cls, PyObject *args)
2860{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002861 PyObject *result = NULL;
2862 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2865 int year;
2866 int month;
2867 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002869 if (ordinal < 1)
2870 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2871 ">= 1");
2872 else {
2873 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002874 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 }
2876 }
2877 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002878}
2879
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002880/* Return the new date from a string as generated by date.isoformat() */
2881static PyObject *
2882date_fromisoformat(PyObject *cls, PyObject *dtstr) {
2883 assert(dtstr != NULL);
2884
2885 if (!PyUnicode_Check(dtstr)) {
2886 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
2887 return NULL;
2888 }
2889
2890 Py_ssize_t len;
2891
2892 const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002893 if (dt_ptr == NULL) {
2894 goto invalid_string_error;
2895 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002896
2897 int year = 0, month = 0, day = 0;
2898
2899 int rv;
2900 if (len == 10) {
2901 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
2902 } else {
2903 rv = -1;
2904 }
2905
2906 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002907 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002908 }
2909
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002910 return new_date_subclass_ex(year, month, day, cls);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002911
2912invalid_string_error:
2913 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R",
2914 dtstr);
2915 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002916}
2917
2918
Tim Peters2a799bf2002-12-16 20:18:38 +00002919/*
2920 * Date arithmetic.
2921 */
2922
2923/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2924 * instead.
2925 */
2926static PyObject *
2927add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2928{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002929 PyObject *result = NULL;
2930 int year = GET_YEAR(date);
2931 int month = GET_MONTH(date);
2932 int deltadays = GET_TD_DAYS(delta);
2933 /* C-level overflow is impossible because |deltadays| < 1e9. */
2934 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002936 if (normalize_date(&year, &month, &day) >= 0)
2937 result = new_date(year, month, day);
2938 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002939}
2940
2941static PyObject *
2942date_add(PyObject *left, PyObject *right)
2943{
Brian Curtindfc80e32011-08-10 20:28:54 -05002944 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2945 Py_RETURN_NOTIMPLEMENTED;
2946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002947 if (PyDate_Check(left)) {
2948 /* date + ??? */
2949 if (PyDelta_Check(right))
2950 /* date + delta */
2951 return add_date_timedelta((PyDateTime_Date *) left,
2952 (PyDateTime_Delta *) right,
2953 0);
2954 }
2955 else {
2956 /* ??? + date
2957 * 'right' must be one of us, or we wouldn't have been called
2958 */
2959 if (PyDelta_Check(left))
2960 /* delta + date */
2961 return add_date_timedelta((PyDateTime_Date *) right,
2962 (PyDateTime_Delta *) left,
2963 0);
2964 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002965 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002966}
2967
2968static PyObject *
2969date_subtract(PyObject *left, PyObject *right)
2970{
Brian Curtindfc80e32011-08-10 20:28:54 -05002971 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2972 Py_RETURN_NOTIMPLEMENTED;
2973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002974 if (PyDate_Check(left)) {
2975 if (PyDate_Check(right)) {
2976 /* date - date */
2977 int left_ord = ymd_to_ord(GET_YEAR(left),
2978 GET_MONTH(left),
2979 GET_DAY(left));
2980 int right_ord = ymd_to_ord(GET_YEAR(right),
2981 GET_MONTH(right),
2982 GET_DAY(right));
2983 return new_delta(left_ord - right_ord, 0, 0, 0);
2984 }
2985 if (PyDelta_Check(right)) {
2986 /* date - delta */
2987 return add_date_timedelta((PyDateTime_Date *) left,
2988 (PyDateTime_Delta *) right,
2989 1);
2990 }
2991 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002992 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002993}
2994
2995
2996/* Various ways to turn a date into a string. */
2997
2998static PyObject *
2999date_repr(PyDateTime_Date *self)
3000{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003001 return PyUnicode_FromFormat("%s(%d, %d, %d)",
3002 Py_TYPE(self)->tp_name,
3003 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003004}
3005
3006static PyObject *
3007date_isoformat(PyDateTime_Date *self)
3008{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003009 return PyUnicode_FromFormat("%04d-%02d-%02d",
3010 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003011}
3012
Tim Peterse2df5ff2003-05-02 18:39:55 +00003013/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003014static PyObject *
3015date_str(PyDateTime_Date *self)
3016{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003017 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003018}
3019
3020
3021static PyObject *
3022date_ctime(PyDateTime_Date *self)
3023{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003024 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003025}
3026
3027static PyObject *
3028date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003030 /* This method can be inherited, and needs to call the
3031 * timetuple() method appropriate to self's class.
3032 */
3033 PyObject *result;
3034 PyObject *tuple;
3035 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003036 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003037 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003039 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3040 &format))
3041 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003042
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003043 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003044 if (tuple == NULL)
3045 return NULL;
3046 result = wrap_strftime((PyObject *)self, format, tuple,
3047 (PyObject *)self);
3048 Py_DECREF(tuple);
3049 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003050}
3051
Eric Smith1ba31142007-09-11 18:06:02 +00003052static PyObject *
3053date_format(PyDateTime_Date *self, PyObject *args)
3054{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003055 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003057 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3058 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003060 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003061 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003063
Victor Stinner20401de2016-12-09 15:24:31 +01003064 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3065 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003066}
3067
Tim Peters2a799bf2002-12-16 20:18:38 +00003068/* ISO methods. */
3069
3070static PyObject *
3071date_isoweekday(PyDateTime_Date *self)
3072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003073 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003075 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003076}
3077
3078static PyObject *
3079date_isocalendar(PyDateTime_Date *self)
3080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003081 int year = GET_YEAR(self);
3082 int week1_monday = iso_week1_monday(year);
3083 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3084 int week;
3085 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003087 week = divmod(today - week1_monday, 7, &day);
3088 if (week < 0) {
3089 --year;
3090 week1_monday = iso_week1_monday(year);
3091 week = divmod(today - week1_monday, 7, &day);
3092 }
3093 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3094 ++year;
3095 week = 0;
3096 }
3097 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003098}
3099
3100/* Miscellaneous methods. */
3101
Tim Peters2a799bf2002-12-16 20:18:38 +00003102static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003103date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003104{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003105 if (PyDate_Check(other)) {
3106 int diff = memcmp(((PyDateTime_Date *)self)->data,
3107 ((PyDateTime_Date *)other)->data,
3108 _PyDateTime_DATE_DATASIZE);
3109 return diff_to_bool(diff, op);
3110 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003111 else
3112 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003113}
3114
3115static PyObject *
3116date_timetuple(PyDateTime_Date *self)
3117{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003118 return build_struct_time(GET_YEAR(self),
3119 GET_MONTH(self),
3120 GET_DAY(self),
3121 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003122}
3123
Tim Peters12bf3392002-12-24 05:41:27 +00003124static PyObject *
3125date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003127 PyObject *clone;
3128 PyObject *tuple;
3129 int year = GET_YEAR(self);
3130 int month = GET_MONTH(self);
3131 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003133 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3134 &year, &month, &day))
3135 return NULL;
3136 tuple = Py_BuildValue("iii", year, month, day);
3137 if (tuple == NULL)
3138 return NULL;
3139 clone = date_new(Py_TYPE(self), tuple, NULL);
3140 Py_DECREF(tuple);
3141 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003142}
3143
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003144static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003145generic_hash(unsigned char *data, int len)
3146{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003147 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003148}
3149
3150
3151static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003152
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003153static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003154date_hash(PyDateTime_Date *self)
3155{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003156 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003157 self->hashcode = generic_hash(
3158 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003159 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003161 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003162}
3163
3164static PyObject *
3165date_toordinal(PyDateTime_Date *self)
3166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003167 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3168 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003169}
3170
3171static PyObject *
3172date_weekday(PyDateTime_Date *self)
3173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003174 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003176 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003177}
3178
Tim Peters371935f2003-02-01 01:52:50 +00003179/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003180
Tim Petersb57f8f02003-02-01 02:54:15 +00003181/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003182static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003183date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003185 PyObject* field;
3186 field = PyBytes_FromStringAndSize((char*)self->data,
3187 _PyDateTime_DATE_DATASIZE);
3188 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003189}
3190
3191static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003192date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003193{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003194 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003195}
3196
3197static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003199 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00003200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003201 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
3202 METH_CLASS,
3203 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
3204 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003206 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3207 METH_CLASS,
3208 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3209 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003210
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003211 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3212 METH_CLASS,
3213 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3216 PyDoc_STR("Current date or datetime: same as "
3217 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003219 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003221 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3222 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003224 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
3225 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003227 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3228 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003230 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3231 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003233 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3234 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3235 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003237 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3238 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003240 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3241 PyDoc_STR("Return the day of the week represented by the date.\n"
3242 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003244 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3245 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3246 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003248 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3249 PyDoc_STR("Return the day of the week represented by the date.\n"
3250 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003252 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3253 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003255 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3256 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003258 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003259};
3260
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003261static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003262PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003263
3264static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003265 date_add, /* nb_add */
3266 date_subtract, /* nb_subtract */
3267 0, /* nb_multiply */
3268 0, /* nb_remainder */
3269 0, /* nb_divmod */
3270 0, /* nb_power */
3271 0, /* nb_negative */
3272 0, /* nb_positive */
3273 0, /* nb_absolute */
3274 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003275};
3276
3277static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003278 PyVarObject_HEAD_INIT(NULL, 0)
3279 "datetime.date", /* tp_name */
3280 sizeof(PyDateTime_Date), /* tp_basicsize */
3281 0, /* tp_itemsize */
3282 0, /* tp_dealloc */
3283 0, /* tp_print */
3284 0, /* tp_getattr */
3285 0, /* tp_setattr */
3286 0, /* tp_reserved */
3287 (reprfunc)date_repr, /* tp_repr */
3288 &date_as_number, /* tp_as_number */
3289 0, /* tp_as_sequence */
3290 0, /* tp_as_mapping */
3291 (hashfunc)date_hash, /* tp_hash */
3292 0, /* tp_call */
3293 (reprfunc)date_str, /* tp_str */
3294 PyObject_GenericGetAttr, /* tp_getattro */
3295 0, /* tp_setattro */
3296 0, /* tp_as_buffer */
3297 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3298 date_doc, /* tp_doc */
3299 0, /* tp_traverse */
3300 0, /* tp_clear */
3301 date_richcompare, /* tp_richcompare */
3302 0, /* tp_weaklistoffset */
3303 0, /* tp_iter */
3304 0, /* tp_iternext */
3305 date_methods, /* tp_methods */
3306 0, /* tp_members */
3307 date_getset, /* tp_getset */
3308 0, /* tp_base */
3309 0, /* tp_dict */
3310 0, /* tp_descr_get */
3311 0, /* tp_descr_set */
3312 0, /* tp_dictoffset */
3313 0, /* tp_init */
3314 0, /* tp_alloc */
3315 date_new, /* tp_new */
3316 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003317};
3318
3319/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003320 * PyDateTime_TZInfo implementation.
3321 */
3322
3323/* This is a pure abstract base class, so doesn't do anything beyond
3324 * raising NotImplemented exceptions. Real tzinfo classes need
3325 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003326 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003327 * be subclasses of this tzinfo class, which is easy and quick to check).
3328 *
3329 * Note: For reasons having to do with pickling of subclasses, we have
3330 * to allow tzinfo objects to be instantiated. This wasn't an issue
3331 * in the Python implementation (__init__() could raise NotImplementedError
3332 * there without ill effect), but doing so in the C implementation hit a
3333 * brick wall.
3334 */
3335
3336static PyObject *
3337tzinfo_nogo(const char* methodname)
3338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003339 PyErr_Format(PyExc_NotImplementedError,
3340 "a tzinfo subclass must implement %s()",
3341 methodname);
3342 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003343}
3344
3345/* Methods. A subclass must implement these. */
3346
Tim Peters52dcce22003-01-23 16:36:11 +00003347static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003348tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003350 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003351}
3352
Tim Peters52dcce22003-01-23 16:36:11 +00003353static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003354tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003356 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003357}
3358
Tim Peters52dcce22003-01-23 16:36:11 +00003359static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003360tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003362 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003363}
3364
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003365
3366static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3367 PyDateTime_Delta *delta,
3368 int factor);
3369static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3370static PyObject *datetime_dst(PyObject *self, PyObject *);
3371
Tim Peters52dcce22003-01-23 16:36:11 +00003372static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003373tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003374{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003375 PyObject *result = NULL;
3376 PyObject *off = NULL, *dst = NULL;
3377 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003378
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003379 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003380 PyErr_SetString(PyExc_TypeError,
3381 "fromutc: argument must be a datetime");
3382 return NULL;
3383 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003384 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003385 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3386 "is not self");
3387 return NULL;
3388 }
Tim Peters52dcce22003-01-23 16:36:11 +00003389
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003390 off = datetime_utcoffset(dt, NULL);
3391 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003392 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003393 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003394 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3395 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003396 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003397 }
Tim Peters52dcce22003-01-23 16:36:11 +00003398
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003399 dst = datetime_dst(dt, NULL);
3400 if (dst == NULL)
3401 goto Fail;
3402 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003403 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3404 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003405 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003406 }
Tim Peters52dcce22003-01-23 16:36:11 +00003407
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003408 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3409 if (delta == NULL)
3410 goto Fail;
3411 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003412 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003413 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003414
3415 Py_DECREF(dst);
3416 dst = call_dst(GET_DT_TZINFO(dt), result);
3417 if (dst == NULL)
3418 goto Fail;
3419 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003420 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003421 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003422 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003423 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003424 if (result == NULL)
3425 goto Fail;
3426 }
3427 Py_DECREF(delta);
3428 Py_DECREF(dst);
3429 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003430 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003431
3432Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003433 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3434 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003435
Miss Islington (bot)e86db342018-02-03 17:41:43 -08003436 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003437Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003438 Py_XDECREF(off);
3439 Py_XDECREF(dst);
3440 Py_XDECREF(delta);
3441 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003442 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003443}
3444
Tim Peters2a799bf2002-12-16 20:18:38 +00003445/*
3446 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003447 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003448 */
3449
Guido van Rossum177e41a2003-01-30 22:06:23 +00003450static PyObject *
3451tzinfo_reduce(PyObject *self)
3452{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003453 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003454 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003455 _Py_IDENTIFIER(__getinitargs__);
3456 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003457
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003458 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003459 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003460 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003461 Py_DECREF(getinitargs);
3462 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003463 return NULL;
3464 }
3465 }
3466 else {
3467 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003468
3469 args = PyTuple_New(0);
3470 if (args == NULL) {
3471 return NULL;
3472 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003473 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003474
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003475 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003476 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003477 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003478 Py_DECREF(getstate);
3479 if (state == NULL) {
3480 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003481 return NULL;
3482 }
3483 }
3484 else {
3485 PyObject **dictptr;
3486 PyErr_Clear();
3487 state = Py_None;
3488 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003489 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003490 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003491 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003492 Py_INCREF(state);
3493 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003495 if (state == Py_None) {
3496 Py_DECREF(state);
3497 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3498 }
3499 else
3500 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003501}
Tim Peters2a799bf2002-12-16 20:18:38 +00003502
3503static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003505 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3506 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003509 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3510 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003512 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003513 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003515 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003516 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003518 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3519 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003521 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003522};
3523
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003524static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003525PyDoc_STR("Abstract base class for time zone info objects.");
3526
Neal Norwitz227b5332006-03-22 09:28:35 +00003527static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003528 PyVarObject_HEAD_INIT(NULL, 0)
3529 "datetime.tzinfo", /* tp_name */
3530 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3531 0, /* tp_itemsize */
3532 0, /* tp_dealloc */
3533 0, /* tp_print */
3534 0, /* tp_getattr */
3535 0, /* tp_setattr */
3536 0, /* tp_reserved */
3537 0, /* tp_repr */
3538 0, /* tp_as_number */
3539 0, /* tp_as_sequence */
3540 0, /* tp_as_mapping */
3541 0, /* tp_hash */
3542 0, /* tp_call */
3543 0, /* tp_str */
3544 PyObject_GenericGetAttr, /* tp_getattro */
3545 0, /* tp_setattro */
3546 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003547 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003548 tzinfo_doc, /* tp_doc */
3549 0, /* tp_traverse */
3550 0, /* tp_clear */
3551 0, /* tp_richcompare */
3552 0, /* tp_weaklistoffset */
3553 0, /* tp_iter */
3554 0, /* tp_iternext */
3555 tzinfo_methods, /* tp_methods */
3556 0, /* tp_members */
3557 0, /* tp_getset */
3558 0, /* tp_base */
3559 0, /* tp_dict */
3560 0, /* tp_descr_get */
3561 0, /* tp_descr_set */
3562 0, /* tp_dictoffset */
3563 0, /* tp_init */
3564 0, /* tp_alloc */
3565 PyType_GenericNew, /* tp_new */
3566 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003567};
3568
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003569static char *timezone_kws[] = {"offset", "name", NULL};
3570
3571static PyObject *
3572timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3573{
3574 PyObject *offset;
3575 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003576 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3577 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003578 return new_timezone(offset, name);
3579
3580 return NULL;
3581}
3582
3583static void
3584timezone_dealloc(PyDateTime_TimeZone *self)
3585{
3586 Py_CLEAR(self->offset);
3587 Py_CLEAR(self->name);
3588 Py_TYPE(self)->tp_free((PyObject *)self);
3589}
3590
3591static PyObject *
3592timezone_richcompare(PyDateTime_TimeZone *self,
3593 PyDateTime_TimeZone *other, int op)
3594{
Brian Curtindfc80e32011-08-10 20:28:54 -05003595 if (op != Py_EQ && op != Py_NE)
3596 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003597 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003598 if (op == Py_EQ)
3599 Py_RETURN_FALSE;
3600 else
3601 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003602 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003603 return delta_richcompare(self->offset, other->offset, op);
3604}
3605
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003606static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003607timezone_hash(PyDateTime_TimeZone *self)
3608{
3609 return delta_hash((PyDateTime_Delta *)self->offset);
3610}
3611
3612/* Check argument type passed to tzname, utcoffset, or dst methods.
3613 Returns 0 for good argument. Returns -1 and sets exception info
3614 otherwise.
3615 */
3616static int
3617_timezone_check_argument(PyObject *dt, const char *meth)
3618{
3619 if (dt == Py_None || PyDateTime_Check(dt))
3620 return 0;
3621 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3622 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3623 return -1;
3624}
3625
3626static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003627timezone_repr(PyDateTime_TimeZone *self)
3628{
3629 /* Note that although timezone is not subclassable, it is convenient
3630 to use Py_TYPE(self)->tp_name here. */
3631 const char *type_name = Py_TYPE(self)->tp_name;
3632
3633 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3634 return PyUnicode_FromFormat("%s.utc", type_name);
3635
3636 if (self->name == NULL)
3637 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3638
3639 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3640 self->name);
3641}
3642
3643
3644static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003645timezone_str(PyDateTime_TimeZone *self)
3646{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003647 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003648 PyObject *offset;
3649 char sign;
3650
3651 if (self->name != NULL) {
3652 Py_INCREF(self->name);
3653 return self->name;
3654 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003655 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003656 (GET_TD_DAYS(self->offset) == 0 &&
3657 GET_TD_SECONDS(self->offset) == 0 &&
3658 GET_TD_MICROSECONDS(self->offset) == 0))
3659 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003660 /* Offset is normalized, so it is negative if days < 0 */
3661 if (GET_TD_DAYS(self->offset) < 0) {
3662 sign = '-';
3663 offset = delta_negative((PyDateTime_Delta *)self->offset);
3664 if (offset == NULL)
3665 return NULL;
3666 }
3667 else {
3668 sign = '+';
3669 offset = self->offset;
3670 Py_INCREF(offset);
3671 }
3672 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003673 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003674 seconds = GET_TD_SECONDS(offset);
3675 Py_DECREF(offset);
3676 minutes = divmod(seconds, 60, &seconds);
3677 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003678 if (microseconds != 0) {
3679 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3680 sign, hours, minutes,
3681 seconds, microseconds);
3682 }
3683 if (seconds != 0) {
3684 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3685 sign, hours, minutes, seconds);
3686 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003687 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003688}
3689
3690static PyObject *
3691timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3692{
3693 if (_timezone_check_argument(dt, "tzname") == -1)
3694 return NULL;
3695
3696 return timezone_str(self);
3697}
3698
3699static PyObject *
3700timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3701{
3702 if (_timezone_check_argument(dt, "utcoffset") == -1)
3703 return NULL;
3704
3705 Py_INCREF(self->offset);
3706 return self->offset;
3707}
3708
3709static PyObject *
3710timezone_dst(PyObject *self, PyObject *dt)
3711{
3712 if (_timezone_check_argument(dt, "dst") == -1)
3713 return NULL;
3714
3715 Py_RETURN_NONE;
3716}
3717
3718static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003719timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3720{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003721 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003722 PyErr_SetString(PyExc_TypeError,
3723 "fromutc: argument must be a datetime");
3724 return NULL;
3725 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003726 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003727 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3728 "is not self");
3729 return NULL;
3730 }
3731
3732 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3733}
3734
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003735static PyObject *
3736timezone_getinitargs(PyDateTime_TimeZone *self)
3737{
3738 if (self->name == NULL)
3739 return Py_BuildValue("(O)", self->offset);
3740 return Py_BuildValue("(OO)", self->offset, self->name);
3741}
3742
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003743static PyMethodDef timezone_methods[] = {
3744 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3745 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003746 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003747
3748 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003749 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003750
3751 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003752 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003753
3754 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3755 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3756
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003757 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3758 PyDoc_STR("pickle support")},
3759
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003760 {NULL, NULL}
3761};
3762
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003763static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003764PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3765
3766static PyTypeObject PyDateTime_TimeZoneType = {
3767 PyVarObject_HEAD_INIT(NULL, 0)
3768 "datetime.timezone", /* tp_name */
3769 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3770 0, /* tp_itemsize */
3771 (destructor)timezone_dealloc, /* tp_dealloc */
3772 0, /* tp_print */
3773 0, /* tp_getattr */
3774 0, /* tp_setattr */
3775 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003776 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003777 0, /* tp_as_number */
3778 0, /* tp_as_sequence */
3779 0, /* tp_as_mapping */
3780 (hashfunc)timezone_hash, /* tp_hash */
3781 0, /* tp_call */
3782 (reprfunc)timezone_str, /* tp_str */
3783 0, /* tp_getattro */
3784 0, /* tp_setattro */
3785 0, /* tp_as_buffer */
3786 Py_TPFLAGS_DEFAULT, /* tp_flags */
3787 timezone_doc, /* tp_doc */
3788 0, /* tp_traverse */
3789 0, /* tp_clear */
3790 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3791 0, /* tp_weaklistoffset */
3792 0, /* tp_iter */
3793 0, /* tp_iternext */
3794 timezone_methods, /* tp_methods */
3795 0, /* tp_members */
3796 0, /* tp_getset */
3797 &PyDateTime_TZInfoType, /* tp_base */
3798 0, /* tp_dict */
3799 0, /* tp_descr_get */
3800 0, /* tp_descr_set */
3801 0, /* tp_dictoffset */
3802 0, /* tp_init */
3803 0, /* tp_alloc */
3804 timezone_new, /* tp_new */
3805};
3806
Tim Peters2a799bf2002-12-16 20:18:38 +00003807/*
Tim Peters37f39822003-01-10 03:49:02 +00003808 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003809 */
3810
Tim Peters37f39822003-01-10 03:49:02 +00003811/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003812 */
3813
3814static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003815time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003817 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003818}
3819
Tim Peters37f39822003-01-10 03:49:02 +00003820static PyObject *
3821time_minute(PyDateTime_Time *self, void *unused)
3822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003823 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003824}
3825
3826/* The name time_second conflicted with some platform header file. */
3827static PyObject *
3828py_time_second(PyDateTime_Time *self, void *unused)
3829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003830 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003831}
3832
3833static PyObject *
3834time_microsecond(PyDateTime_Time *self, void *unused)
3835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003836 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003837}
3838
3839static PyObject *
3840time_tzinfo(PyDateTime_Time *self, void *unused)
3841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003842 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3843 Py_INCREF(result);
3844 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003845}
3846
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003847static PyObject *
3848time_fold(PyDateTime_Time *self, void *unused)
3849{
3850 return PyLong_FromLong(TIME_GET_FOLD(self));
3851}
3852
Tim Peters37f39822003-01-10 03:49:02 +00003853static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003854 {"hour", (getter)time_hour},
3855 {"minute", (getter)time_minute},
3856 {"second", (getter)py_time_second},
3857 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003858 {"tzinfo", (getter)time_tzinfo},
3859 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003860 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003861};
3862
3863/*
3864 * Constructors.
3865 */
3866
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003867static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003868 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003869
Tim Peters2a799bf2002-12-16 20:18:38 +00003870static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003871time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003873 PyObject *self = NULL;
3874 PyObject *state;
3875 int hour = 0;
3876 int minute = 0;
3877 int second = 0;
3878 int usecond = 0;
3879 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003880 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003882 /* Check for invocation from pickle with __getstate__ state */
3883 if (PyTuple_GET_SIZE(args) >= 1 &&
3884 PyTuple_GET_SIZE(args) <= 2 &&
3885 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3886 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003887 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003888 {
3889 PyDateTime_Time *me;
3890 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003892 if (PyTuple_GET_SIZE(args) == 2) {
3893 tzinfo = PyTuple_GET_ITEM(args, 1);
3894 if (check_tzinfo_subclass(tzinfo) < 0) {
3895 PyErr_SetString(PyExc_TypeError, "bad "
3896 "tzinfo state arg");
3897 return NULL;
3898 }
3899 }
3900 aware = (char)(tzinfo != Py_None);
3901 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3902 if (me != NULL) {
3903 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003905 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3906 me->hashcode = -1;
3907 me->hastzinfo = aware;
3908 if (aware) {
3909 Py_INCREF(tzinfo);
3910 me->tzinfo = tzinfo;
3911 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003912 if (pdata[0] & (1 << 7)) {
3913 me->data[0] -= 128;
3914 me->fold = 1;
3915 }
3916 else {
3917 me->fold = 0;
3918 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003919 }
3920 return (PyObject *)me;
3921 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003922
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003923 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003924 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003925 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003926 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3927 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003928 }
3929 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003930}
3931
3932/*
3933 * Destructor.
3934 */
3935
3936static void
Tim Peters37f39822003-01-10 03:49:02 +00003937time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003938{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003939 if (HASTZINFO(self)) {
3940 Py_XDECREF(self->tzinfo);
3941 }
3942 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003943}
3944
3945/*
Tim Peters855fe882002-12-22 03:43:39 +00003946 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003947 */
3948
Tim Peters2a799bf2002-12-16 20:18:38 +00003949/* These are all METH_NOARGS, so don't need to check the arglist. */
3950static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003951time_utcoffset(PyObject *self, PyObject *unused) {
3952 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003953}
3954
3955static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003956time_dst(PyObject *self, PyObject *unused) {
3957 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003958}
3959
3960static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003961time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003962 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003963}
3964
3965/*
Tim Peters37f39822003-01-10 03:49:02 +00003966 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003967 */
3968
3969static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003970time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003972 const char *type_name = Py_TYPE(self)->tp_name;
3973 int h = TIME_GET_HOUR(self);
3974 int m = TIME_GET_MINUTE(self);
3975 int s = TIME_GET_SECOND(self);
3976 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003977 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 if (us)
3981 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3982 type_name, h, m, s, us);
3983 else if (s)
3984 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3985 type_name, h, m, s);
3986 else
3987 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3988 if (result != NULL && HASTZINFO(self))
3989 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003990 if (result != NULL && fold)
3991 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003992 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003993}
3994
Tim Peters37f39822003-01-10 03:49:02 +00003995static PyObject *
3996time_str(PyDateTime_Time *self)
3997{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003998 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003999}
Tim Peters2a799bf2002-12-16 20:18:38 +00004000
4001static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004002time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004005 char *timespec = NULL;
4006 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004007 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004008 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004009 static char *specs[][2] = {
4010 {"hours", "%02d"},
4011 {"minutes", "%02d:%02d"},
4012 {"seconds", "%02d:%02d:%02d"},
4013 {"milliseconds", "%02d:%02d:%02d.%03d"},
4014 {"microseconds", "%02d:%02d:%02d.%06d"},
4015 };
4016 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004017
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004018 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4019 return NULL;
4020
4021 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4022 if (us == 0) {
4023 /* seconds */
4024 given_spec = 2;
4025 }
4026 else {
4027 /* microseconds */
4028 given_spec = 4;
4029 }
4030 }
4031 else {
4032 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4033 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4034 if (given_spec == 3) {
4035 /* milliseconds */
4036 us = us / 1000;
4037 }
4038 break;
4039 }
4040 }
4041 }
4042
4043 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4044 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4045 return NULL;
4046 }
4047 else {
4048 result = PyUnicode_FromFormat(specs[given_spec][1],
4049 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4050 TIME_GET_SECOND(self), us);
4051 }
Tim Peters37f39822003-01-10 03:49:02 +00004052
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004053 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004054 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004056 /* We need to append the UTC offset. */
4057 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4058 Py_None) < 0) {
4059 Py_DECREF(result);
4060 return NULL;
4061 }
4062 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4063 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004064}
4065
Tim Peters37f39822003-01-10 03:49:02 +00004066static PyObject *
4067time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004069 PyObject *result;
4070 PyObject *tuple;
4071 PyObject *format;
4072 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004074 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4075 &format))
4076 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004078 /* Python's strftime does insane things with the year part of the
4079 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004080 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004081 */
4082 tuple = Py_BuildValue("iiiiiiiii",
4083 1900, 1, 1, /* year, month, day */
4084 TIME_GET_HOUR(self),
4085 TIME_GET_MINUTE(self),
4086 TIME_GET_SECOND(self),
4087 0, 1, -1); /* weekday, daynum, dst */
4088 if (tuple == NULL)
4089 return NULL;
4090 assert(PyTuple_Size(tuple) == 9);
4091 result = wrap_strftime((PyObject *)self, format, tuple,
4092 Py_None);
4093 Py_DECREF(tuple);
4094 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004095}
Tim Peters2a799bf2002-12-16 20:18:38 +00004096
4097/*
4098 * Miscellaneous methods.
4099 */
4100
Tim Peters37f39822003-01-10 03:49:02 +00004101static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004102time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004103{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004104 PyObject *result = NULL;
4105 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004106 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004107
Brian Curtindfc80e32011-08-10 20:28:54 -05004108 if (! PyTime_Check(other))
4109 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004110
4111 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004112 diff = memcmp(((PyDateTime_Time *)self)->data,
4113 ((PyDateTime_Time *)other)->data,
4114 _PyDateTime_TIME_DATASIZE);
4115 return diff_to_bool(diff, op);
4116 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004117 offset1 = time_utcoffset(self, NULL);
4118 if (offset1 == NULL)
4119 return NULL;
4120 offset2 = time_utcoffset(other, NULL);
4121 if (offset2 == NULL)
4122 goto done;
4123 /* If they're both naive, or both aware and have the same offsets,
4124 * we get off cheap. Note that if they're both naive, offset1 ==
4125 * offset2 == Py_None at this point.
4126 */
4127 if ((offset1 == offset2) ||
4128 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4129 delta_cmp(offset1, offset2) == 0)) {
4130 diff = memcmp(((PyDateTime_Time *)self)->data,
4131 ((PyDateTime_Time *)other)->data,
4132 _PyDateTime_TIME_DATASIZE);
4133 result = diff_to_bool(diff, op);
4134 }
4135 /* The hard case: both aware with different UTC offsets */
4136 else if (offset1 != Py_None && offset2 != Py_None) {
4137 int offsecs1, offsecs2;
4138 assert(offset1 != offset2); /* else last "if" handled it */
4139 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4140 TIME_GET_MINUTE(self) * 60 +
4141 TIME_GET_SECOND(self) -
4142 GET_TD_DAYS(offset1) * 86400 -
4143 GET_TD_SECONDS(offset1);
4144 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4145 TIME_GET_MINUTE(other) * 60 +
4146 TIME_GET_SECOND(other) -
4147 GET_TD_DAYS(offset2) * 86400 -
4148 GET_TD_SECONDS(offset2);
4149 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004150 if (diff == 0)
4151 diff = TIME_GET_MICROSECOND(self) -
4152 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004153 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004154 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004155 else if (op == Py_EQ) {
4156 result = Py_False;
4157 Py_INCREF(result);
4158 }
4159 else if (op == Py_NE) {
4160 result = Py_True;
4161 Py_INCREF(result);
4162 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004163 else {
4164 PyErr_SetString(PyExc_TypeError,
4165 "can't compare offset-naive and "
4166 "offset-aware times");
4167 }
4168 done:
4169 Py_DECREF(offset1);
4170 Py_XDECREF(offset2);
4171 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004172}
4173
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004174static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004175time_hash(PyDateTime_Time *self)
4176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004178 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004179 if (TIME_GET_FOLD(self)) {
4180 self0 = new_time_ex2(TIME_GET_HOUR(self),
4181 TIME_GET_MINUTE(self),
4182 TIME_GET_SECOND(self),
4183 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004184 HASTZINFO(self) ? self->tzinfo : Py_None,
4185 0, Py_TYPE(self));
4186 if (self0 == NULL)
4187 return -1;
4188 }
4189 else {
4190 self0 = (PyObject *)self;
4191 Py_INCREF(self0);
4192 }
4193 offset = time_utcoffset(self0, NULL);
4194 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004195
4196 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004197 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004199 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004200 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004201 self->hashcode = generic_hash(
4202 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004203 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004204 PyObject *temp1, *temp2;
4205 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004206 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004207 seconds = TIME_GET_HOUR(self) * 3600 +
4208 TIME_GET_MINUTE(self) * 60 +
4209 TIME_GET_SECOND(self);
4210 microseconds = TIME_GET_MICROSECOND(self);
4211 temp1 = new_delta(0, seconds, microseconds, 1);
4212 if (temp1 == NULL) {
4213 Py_DECREF(offset);
4214 return -1;
4215 }
4216 temp2 = delta_subtract(temp1, offset);
4217 Py_DECREF(temp1);
4218 if (temp2 == NULL) {
4219 Py_DECREF(offset);
4220 return -1;
4221 }
4222 self->hashcode = PyObject_Hash(temp2);
4223 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004224 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004225 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 }
4227 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004228}
Tim Peters2a799bf2002-12-16 20:18:38 +00004229
Tim Peters12bf3392002-12-24 05:41:27 +00004230static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004231time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004233 PyObject *clone;
4234 PyObject *tuple;
4235 int hh = TIME_GET_HOUR(self);
4236 int mm = TIME_GET_MINUTE(self);
4237 int ss = TIME_GET_SECOND(self);
4238 int us = TIME_GET_MICROSECOND(self);
4239 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004240 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004241
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004242 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004243 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004244 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004245 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004246 if (fold != 0 && fold != 1) {
4247 PyErr_SetString(PyExc_ValueError,
4248 "fold must be either 0 or 1");
4249 return NULL;
4250 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004251 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4252 if (tuple == NULL)
4253 return NULL;
4254 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004255 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004256 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004257 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004258 Py_DECREF(tuple);
4259 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004260}
4261
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004262static PyObject *
4263time_fromisoformat(PyObject *cls, PyObject *tstr) {
4264 assert(tstr != NULL);
4265
4266 if (!PyUnicode_Check(tstr)) {
4267 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4268 return NULL;
4269 }
4270
4271 Py_ssize_t len;
4272 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4273
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004274 if (p == NULL) {
4275 goto invalid_string_error;
4276 }
4277
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004278 int hour = 0, minute = 0, second = 0, microsecond = 0;
4279 int tzoffset, tzimicrosecond = 0;
4280 int rv = parse_isoformat_time(p, len,
4281 &hour, &minute, &second, &microsecond,
4282 &tzoffset, &tzimicrosecond);
4283
4284 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004285 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004286 }
4287
4288 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4289 tzimicrosecond);
4290
4291 if (tzinfo == NULL) {
4292 return NULL;
4293 }
4294
4295 PyObject *t;
4296 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4297 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4298 } else {
4299 t = PyObject_CallFunction(cls, "iiiiO",
4300 hour, minute, second, microsecond, tzinfo);
4301 }
4302
4303 Py_DECREF(tzinfo);
4304 return t;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004305
4306invalid_string_error:
4307 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4308 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004309}
4310
4311
Tim Peters371935f2003-02-01 01:52:50 +00004312/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004313
Tim Peters33e0f382003-01-10 02:05:14 +00004314/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004315 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4316 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004317 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004318 */
4319static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004320time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004322 PyObject *basestate;
4323 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004325 basestate = PyBytes_FromStringAndSize((char *)self->data,
4326 _PyDateTime_TIME_DATASIZE);
4327 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004328 if (proto > 3 && TIME_GET_FOLD(self))
4329 /* Set the first bit of the first byte */
4330 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004331 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4332 result = PyTuple_Pack(1, basestate);
4333 else
4334 result = PyTuple_Pack(2, basestate, self->tzinfo);
4335 Py_DECREF(basestate);
4336 }
4337 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004338}
4339
4340static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004341time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004342{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004343 int proto;
4344 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004345 return NULL;
4346
4347 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004348}
4349
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004350static PyObject *
4351time_reduce(PyDateTime_Time *self, PyObject *arg)
4352{
4353 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4354}
4355
Tim Peters37f39822003-01-10 03:49:02 +00004356static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004357
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004358 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4359 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4360 "[+HH:MM].\n\n"
4361 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004363 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4364 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004366 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4367 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004369 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4370 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004372 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4373 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004375 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4376 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004378 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4379 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004380
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004381 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4382 PyDoc_STR("string -> time from time.isoformat() output")},
4383
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004384 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004385 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004386
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004387 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4388 PyDoc_STR("__reduce__() -> (cls, state)")},
4389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004390 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004391};
4392
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004393static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004394PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4395\n\
4396All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004397a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004398
Neal Norwitz227b5332006-03-22 09:28:35 +00004399static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004400 PyVarObject_HEAD_INIT(NULL, 0)
4401 "datetime.time", /* tp_name */
4402 sizeof(PyDateTime_Time), /* tp_basicsize */
4403 0, /* tp_itemsize */
4404 (destructor)time_dealloc, /* tp_dealloc */
4405 0, /* tp_print */
4406 0, /* tp_getattr */
4407 0, /* tp_setattr */
4408 0, /* tp_reserved */
4409 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004410 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 0, /* tp_as_sequence */
4412 0, /* tp_as_mapping */
4413 (hashfunc)time_hash, /* tp_hash */
4414 0, /* tp_call */
4415 (reprfunc)time_str, /* tp_str */
4416 PyObject_GenericGetAttr, /* tp_getattro */
4417 0, /* tp_setattro */
4418 0, /* tp_as_buffer */
4419 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4420 time_doc, /* tp_doc */
4421 0, /* tp_traverse */
4422 0, /* tp_clear */
4423 time_richcompare, /* tp_richcompare */
4424 0, /* tp_weaklistoffset */
4425 0, /* tp_iter */
4426 0, /* tp_iternext */
4427 time_methods, /* tp_methods */
4428 0, /* tp_members */
4429 time_getset, /* tp_getset */
4430 0, /* tp_base */
4431 0, /* tp_dict */
4432 0, /* tp_descr_get */
4433 0, /* tp_descr_set */
4434 0, /* tp_dictoffset */
4435 0, /* tp_init */
4436 time_alloc, /* tp_alloc */
4437 time_new, /* tp_new */
4438 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004439};
4440
4441/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004442 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004443 */
4444
Tim Petersa9bc1682003-01-11 03:39:11 +00004445/* Accessor properties. Properties for day, month, and year are inherited
4446 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004447 */
4448
4449static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004450datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004452 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004453}
4454
Tim Petersa9bc1682003-01-11 03:39:11 +00004455static PyObject *
4456datetime_minute(PyDateTime_DateTime *self, void *unused)
4457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004458 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004459}
4460
4461static PyObject *
4462datetime_second(PyDateTime_DateTime *self, void *unused)
4463{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004464 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004465}
4466
4467static PyObject *
4468datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004470 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004471}
4472
4473static PyObject *
4474datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004476 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4477 Py_INCREF(result);
4478 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004479}
4480
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004481static PyObject *
4482datetime_fold(PyDateTime_DateTime *self, void *unused)
4483{
4484 return PyLong_FromLong(DATE_GET_FOLD(self));
4485}
4486
Tim Petersa9bc1682003-01-11 03:39:11 +00004487static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004488 {"hour", (getter)datetime_hour},
4489 {"minute", (getter)datetime_minute},
4490 {"second", (getter)datetime_second},
4491 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004492 {"tzinfo", (getter)datetime_tzinfo},
4493 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004494 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004495};
4496
4497/*
4498 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004499 */
4500
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004501static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004502 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004503 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004504};
4505
Tim Peters2a799bf2002-12-16 20:18:38 +00004506static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004507datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004508{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004509 PyObject *self = NULL;
4510 PyObject *state;
4511 int year;
4512 int month;
4513 int day;
4514 int hour = 0;
4515 int minute = 0;
4516 int second = 0;
4517 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004518 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004519 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004521 /* Check for invocation from pickle with __getstate__ state */
4522 if (PyTuple_GET_SIZE(args) >= 1 &&
4523 PyTuple_GET_SIZE(args) <= 2 &&
4524 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4525 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004526 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004527 {
4528 PyDateTime_DateTime *me;
4529 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004531 if (PyTuple_GET_SIZE(args) == 2) {
4532 tzinfo = PyTuple_GET_ITEM(args, 1);
4533 if (check_tzinfo_subclass(tzinfo) < 0) {
4534 PyErr_SetString(PyExc_TypeError, "bad "
4535 "tzinfo state arg");
4536 return NULL;
4537 }
4538 }
4539 aware = (char)(tzinfo != Py_None);
4540 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4541 if (me != NULL) {
4542 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4545 me->hashcode = -1;
4546 me->hastzinfo = aware;
4547 if (aware) {
4548 Py_INCREF(tzinfo);
4549 me->tzinfo = tzinfo;
4550 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004551 if (pdata[2] & (1 << 7)) {
4552 me->data[2] -= 128;
4553 me->fold = 1;
4554 }
4555 else {
4556 me->fold = 0;
4557 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004558 }
4559 return (PyObject *)me;
4560 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004561
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004562 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004563 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004564 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004565 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004566 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004567 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004568 }
4569 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004570}
4571
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004572/* TM_FUNC is the shared type of _PyTime_localtime() and
4573 * _PyTime_gmtime(). */
4574typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004575
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004576/* As of version 2015f max fold in IANA database is
4577 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004578static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004579/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004580static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004581
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004582static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004583utc_to_seconds(int year, int month, int day,
4584 int hour, int minute, int second)
4585{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004586 long long ordinal;
4587
4588 /* ymd_to_ord() doesn't support year <= 0 */
4589 if (year < MINYEAR || year > MAXYEAR) {
4590 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4591 return -1;
4592 }
4593
4594 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004595 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4596}
4597
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004598static long long
4599local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004600{
4601 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004602 time_t t;
4603 u -= epoch;
4604 t = u;
4605 if (t != u) {
4606 PyErr_SetString(PyExc_OverflowError,
4607 "timestamp out of range for platform time_t");
4608 return -1;
4609 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004610 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004611 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004612 return utc_to_seconds(local_time.tm_year + 1900,
4613 local_time.tm_mon + 1,
4614 local_time.tm_mday,
4615 local_time.tm_hour,
4616 local_time.tm_min,
4617 local_time.tm_sec);
4618}
4619
Tim Petersa9bc1682003-01-11 03:39:11 +00004620/* Internal helper.
4621 * Build datetime from a time_t and a distinct count of microseconds.
4622 * Pass localtime or gmtime for f, to control the interpretation of timet.
4623 */
4624static PyObject *
4625datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004626 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004627{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004628 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004629 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004630
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004631 if (f(timet, &tm) != 0)
4632 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004633
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004634 year = tm.tm_year + 1900;
4635 month = tm.tm_mon + 1;
4636 day = tm.tm_mday;
4637 hour = tm.tm_hour;
4638 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004639 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004640 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004641 * except to the extent that passing them on to the datetime
4642 * constructor would raise ValueError for a reason that
4643 * made no sense to the user.
4644 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004645 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004646
Victor Stinnerb67f0962017-02-10 10:34:02 +01004647 /* local timezone requires to compute fold */
Miss Islington (bot)97364932018-07-25 13:34:09 -07004648 if (tzinfo == Py_None && f == _PyTime_localtime
4649 /* On Windows, passing a negative value to local results
4650 * in an OSError because localtime_s on Windows does
4651 * not support negative timestamps. Unfortunately this
4652 * means that fold detection for time values between
4653 * 0 and max_fold_seconds will result in an identical
4654 * error since we subtract max_fold_seconds to detect a
4655 * fold. However, since we know there haven't been any
4656 * folds in the interval [0, max_fold_seconds) in any
4657 * timezone, we can hackily just forego fold detection
4658 * for this time range.
4659 */
4660#ifdef MS_WINDOWS
4661 && (timet - max_fold_seconds > 0)
4662#endif
4663 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004664 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004665
4666 result_seconds = utc_to_seconds(year, month, day,
4667 hour, minute, second);
4668 /* Probe max_fold_seconds to detect a fold. */
4669 probe_seconds = local(epoch + timet - max_fold_seconds);
4670 if (probe_seconds == -1)
4671 return NULL;
4672 transition = result_seconds - probe_seconds - max_fold_seconds;
4673 if (transition < 0) {
4674 probe_seconds = local(epoch + timet + transition);
4675 if (probe_seconds == -1)
4676 return NULL;
4677 if (probe_seconds == result_seconds)
4678 fold = 1;
4679 }
4680 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004681 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4682 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004683}
4684
4685/* Internal helper.
4686 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4687 * to control the interpretation of the timestamp. Since a double doesn't
4688 * have enough bits to cover a datetime's full range of precision, it's
4689 * better to call datetime_from_timet_and_us provided you have a way
4690 * to get that much precision (e.g., C time() isn't good enough).
4691 */
4692static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004693datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004694 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004695{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004696 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004697 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004698
Victor Stinnere4a994d2015-03-30 01:10:14 +02004699 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004700 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004701 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004702
Victor Stinner21f58932012-03-14 00:15:40 +01004703 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004704}
4705
4706/* Internal helper.
4707 * Build most accurate possible datetime for current time. Pass localtime or
4708 * gmtime for f as appropriate.
4709 */
4710static PyObject *
4711datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4712{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004713 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004714 time_t secs;
4715 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004716
Victor Stinner1e2b6882015-09-18 13:23:02 +02004717 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004718 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004719 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004720
Victor Stinner1e2b6882015-09-18 13:23:02 +02004721 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004722}
4723
Larry Hastings61272b72014-01-07 12:41:53 -08004724/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004725
4726@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004727datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004728
4729 tz: object = None
4730 Timezone object.
4731
4732Returns new datetime object representing current time local to tz.
4733
4734If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004735[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004736
Larry Hastings31826802013-10-19 00:09:25 -07004737static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004738datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004739/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004741 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004742
Larry Hastings31826802013-10-19 00:09:25 -07004743 /* Return best possible local time -- this isn't constrained by the
4744 * precision of a timestamp.
4745 */
4746 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004747 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004748
Larry Hastings5c661892014-01-24 06:17:25 -08004749 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004750 tz == Py_None ? _PyTime_localtime :
4751 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004752 tz);
4753 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004754 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004755 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004756 }
4757 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004758}
4759
Tim Petersa9bc1682003-01-11 03:39:11 +00004760/* Return best possible UTC time -- this isn't constrained by the
4761 * precision of a timestamp.
4762 */
4763static PyObject *
4764datetime_utcnow(PyObject *cls, PyObject *dummy)
4765{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004766 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004767}
4768
Tim Peters2a799bf2002-12-16 20:18:38 +00004769/* Return new local datetime from timestamp (Python timestamp -- a double). */
4770static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004771datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004773 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004774 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004775 PyObject *tzinfo = Py_None;
4776 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004777
Victor Stinner5d272cc2012-03-13 13:35:55 +01004778 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004779 keywords, &timestamp, &tzinfo))
4780 return NULL;
4781 if (check_tzinfo_subclass(tzinfo) < 0)
4782 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004784 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004785 tzinfo == Py_None ? _PyTime_localtime :
4786 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004787 timestamp,
4788 tzinfo);
4789 if (self != NULL && tzinfo != Py_None) {
4790 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004791 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004792 }
4793 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004794}
4795
Tim Petersa9bc1682003-01-11 03:39:11 +00004796/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4797static PyObject *
4798datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4799{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004800 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004801 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004802
Victor Stinner5d272cc2012-03-13 13:35:55 +01004803 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004804 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004805 Py_None);
4806 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004807}
4808
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004809/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004810static PyObject *
4811datetime_strptime(PyObject *cls, PyObject *args)
4812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004813 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004814 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004815 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004816
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004817 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004818 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004819
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004820 if (module == NULL) {
4821 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004822 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004823 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004824 }
Victor Stinner20401de2016-12-09 15:24:31 +01004825 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4826 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004827}
4828
Tim Petersa9bc1682003-01-11 03:39:11 +00004829/* Return new datetime from date/datetime and time arguments. */
4830static PyObject *
4831datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4832{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004833 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004834 PyObject *date;
4835 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004836 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004837 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004838
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004839 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004840 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004841 &PyDateTime_TimeType, &time, &tzinfo)) {
4842 if (tzinfo == NULL) {
4843 if (HASTZINFO(time))
4844 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4845 else
4846 tzinfo = Py_None;
4847 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004848 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
4849 GET_MONTH(date),
4850 GET_DAY(date),
4851 TIME_GET_HOUR(time),
4852 TIME_GET_MINUTE(time),
4853 TIME_GET_SECOND(time),
4854 TIME_GET_MICROSECOND(time),
4855 tzinfo,
4856 TIME_GET_FOLD(time),
4857 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004858 }
4859 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004860}
Tim Peters2a799bf2002-12-16 20:18:38 +00004861
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004862static PyObject *
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004863_sanitize_isoformat_str(PyObject *dtstr, int *needs_decref) {
4864 // `fromisoformat` allows surrogate characters in exactly one position,
4865 // the separator; to allow datetime_fromisoformat to make the simplifying
4866 // assumption that all valid strings can be encoded in UTF-8, this function
4867 // replaces any surrogate character separators with `T`.
4868 Py_ssize_t len = PyUnicode_GetLength(dtstr);
4869 *needs_decref = 0;
4870 if (len <= 10 || !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
4871 return dtstr;
4872 }
4873
4874 PyObject *str_out = PyUnicode_New(len, PyUnicode_MAX_CHAR_VALUE(dtstr));
4875 if (str_out == NULL) {
4876 return NULL;
4877 }
4878
4879 if (PyUnicode_CopyCharacters(str_out, 0, dtstr, 0, len) == -1 ||
4880 PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
4881 Py_DECREF(str_out);
4882 return NULL;
4883 }
4884
4885 *needs_decref = 1;
4886 return str_out;
4887}
4888
4889static PyObject *
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004890datetime_fromisoformat(PyObject* cls, PyObject *dtstr) {
4891 assert(dtstr != NULL);
4892
4893 if (!PyUnicode_Check(dtstr)) {
4894 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4895 return NULL;
4896 }
4897
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004898 int needs_decref = 0;
4899 dtstr = _sanitize_isoformat_str(dtstr, &needs_decref);
4900 if (dtstr == NULL) {
4901 goto error;
4902 }
4903
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004904 Py_ssize_t len;
4905 const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004906
4907 if (dt_ptr == NULL) {
4908 goto invalid_string_error;
4909 }
4910
4911 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004912
4913 int year = 0, month = 0, day = 0;
4914 int hour = 0, minute = 0, second = 0, microsecond = 0;
4915 int tzoffset = 0, tzusec = 0;
4916
4917 // date has a fixed length of 10
4918 int rv = parse_isoformat_date(p, &year, &month, &day);
4919
4920 if (!rv && len > 10) {
4921 // In UTF-8, the length of multi-byte characters is encoded in the MSB
4922 if ((p[10] & 0x80) == 0) {
4923 p += 11;
4924 } else {
4925 switch(p[10] & 0xf0) {
4926 case 0xe0:
4927 p += 13;
4928 break;
4929 case 0xf0:
4930 p += 14;
4931 break;
4932 default:
4933 p += 12;
4934 break;
4935 }
4936 }
4937
4938 len -= (p - dt_ptr);
4939 rv = parse_isoformat_time(p, len,
4940 &hour, &minute, &second, &microsecond,
4941 &tzoffset, &tzusec);
4942 }
4943 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004944 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004945 }
4946
4947 PyObject* tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
4948 if (tzinfo == NULL) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004949 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004950 }
4951
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004952 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
4953 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004954
4955 Py_DECREF(tzinfo);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004956 if (needs_decref) {
4957 Py_DECREF(dtstr);
4958 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004959 return dt;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004960
4961invalid_string_error:
4962 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
4963
4964error:
4965 if (needs_decref) {
4966 Py_DECREF(dtstr);
4967 }
4968
4969 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004970}
4971
4972
Tim Peters2a799bf2002-12-16 20:18:38 +00004973/*
4974 * Destructor.
4975 */
4976
4977static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004978datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004980 if (HASTZINFO(self)) {
4981 Py_XDECREF(self->tzinfo);
4982 }
4983 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004984}
4985
4986/*
4987 * Indirect access to tzinfo methods.
4988 */
4989
Tim Peters2a799bf2002-12-16 20:18:38 +00004990/* These are all METH_NOARGS, so don't need to check the arglist. */
4991static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004992datetime_utcoffset(PyObject *self, PyObject *unused) {
4993 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004994}
4995
4996static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004997datetime_dst(PyObject *self, PyObject *unused) {
4998 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004999}
5000
5001static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005002datetime_tzname(PyObject *self, PyObject *unused) {
5003 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005004}
5005
5006/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005007 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005008 */
5009
Tim Petersa9bc1682003-01-11 03:39:11 +00005010/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5011 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005012 */
5013static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005014add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005015 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005016{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005017 /* Note that the C-level additions can't overflow, because of
5018 * invariant bounds on the member values.
5019 */
5020 int year = GET_YEAR(date);
5021 int month = GET_MONTH(date);
5022 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5023 int hour = DATE_GET_HOUR(date);
5024 int minute = DATE_GET_MINUTE(date);
5025 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5026 int microsecond = DATE_GET_MICROSECOND(date) +
5027 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005029 assert(factor == 1 || factor == -1);
5030 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005031 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005032 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005033 }
5034
5035 return new_datetime(year, month, day,
5036 hour, minute, second, microsecond,
5037 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005038}
5039
5040static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005041datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005042{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005043 if (PyDateTime_Check(left)) {
5044 /* datetime + ??? */
5045 if (PyDelta_Check(right))
5046 /* datetime + delta */
5047 return add_datetime_timedelta(
5048 (PyDateTime_DateTime *)left,
5049 (PyDateTime_Delta *)right,
5050 1);
5051 }
5052 else if (PyDelta_Check(left)) {
5053 /* delta + datetime */
5054 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5055 (PyDateTime_Delta *) left,
5056 1);
5057 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005058 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005059}
5060
5061static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005062datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005063{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005064 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005066 if (PyDateTime_Check(left)) {
5067 /* datetime - ??? */
5068 if (PyDateTime_Check(right)) {
5069 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005070 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005071 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005072
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005073 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5074 offset2 = offset1 = Py_None;
5075 Py_INCREF(offset1);
5076 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005077 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005078 else {
5079 offset1 = datetime_utcoffset(left, NULL);
5080 if (offset1 == NULL)
5081 return NULL;
5082 offset2 = datetime_utcoffset(right, NULL);
5083 if (offset2 == NULL) {
5084 Py_DECREF(offset1);
5085 return NULL;
5086 }
5087 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5088 PyErr_SetString(PyExc_TypeError,
5089 "can't subtract offset-naive and "
5090 "offset-aware datetimes");
5091 Py_DECREF(offset1);
5092 Py_DECREF(offset2);
5093 return NULL;
5094 }
5095 }
5096 if ((offset1 != offset2) &&
5097 delta_cmp(offset1, offset2) != 0) {
5098 offdiff = delta_subtract(offset1, offset2);
5099 if (offdiff == NULL) {
5100 Py_DECREF(offset1);
5101 Py_DECREF(offset2);
5102 return NULL;
5103 }
5104 }
5105 Py_DECREF(offset1);
5106 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005107 delta_d = ymd_to_ord(GET_YEAR(left),
5108 GET_MONTH(left),
5109 GET_DAY(left)) -
5110 ymd_to_ord(GET_YEAR(right),
5111 GET_MONTH(right),
5112 GET_DAY(right));
5113 /* These can't overflow, since the values are
5114 * normalized. At most this gives the number of
5115 * seconds in one day.
5116 */
5117 delta_s = (DATE_GET_HOUR(left) -
5118 DATE_GET_HOUR(right)) * 3600 +
5119 (DATE_GET_MINUTE(left) -
5120 DATE_GET_MINUTE(right)) * 60 +
5121 (DATE_GET_SECOND(left) -
5122 DATE_GET_SECOND(right));
5123 delta_us = DATE_GET_MICROSECOND(left) -
5124 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005125 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005126 if (result == NULL)
5127 return NULL;
5128
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005129 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005130 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005131 Py_DECREF(offdiff);
5132 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005133 }
5134 else if (PyDelta_Check(right)) {
5135 /* datetime - delta */
5136 result = add_datetime_timedelta(
5137 (PyDateTime_DateTime *)left,
5138 (PyDateTime_Delta *)right,
5139 -1);
5140 }
5141 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005143 if (result == Py_NotImplemented)
5144 Py_INCREF(result);
5145 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005146}
5147
5148/* Various ways to turn a datetime into a string. */
5149
5150static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005151datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005153 const char *type_name = Py_TYPE(self)->tp_name;
5154 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005156 if (DATE_GET_MICROSECOND(self)) {
5157 baserepr = PyUnicode_FromFormat(
5158 "%s(%d, %d, %d, %d, %d, %d, %d)",
5159 type_name,
5160 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5161 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5162 DATE_GET_SECOND(self),
5163 DATE_GET_MICROSECOND(self));
5164 }
5165 else if (DATE_GET_SECOND(self)) {
5166 baserepr = PyUnicode_FromFormat(
5167 "%s(%d, %d, %d, %d, %d, %d)",
5168 type_name,
5169 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5170 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5171 DATE_GET_SECOND(self));
5172 }
5173 else {
5174 baserepr = PyUnicode_FromFormat(
5175 "%s(%d, %d, %d, %d, %d)",
5176 type_name,
5177 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5178 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5179 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005180 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5181 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005182 if (baserepr == NULL || ! HASTZINFO(self))
5183 return baserepr;
5184 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005185}
5186
Tim Petersa9bc1682003-01-11 03:39:11 +00005187static PyObject *
5188datetime_str(PyDateTime_DateTime *self)
5189{
Victor Stinner4c381542016-12-09 00:33:39 +01005190 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005191}
Tim Peters2a799bf2002-12-16 20:18:38 +00005192
5193static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005194datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005196 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005197 char *timespec = NULL;
5198 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005199 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005200 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005201 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005202 static char *specs[][2] = {
5203 {"hours", "%04d-%02d-%02d%c%02d"},
5204 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5205 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5206 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5207 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5208 };
5209 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005210
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005211 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005212 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005213
5214 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5215 if (us == 0) {
5216 /* seconds */
5217 given_spec = 2;
5218 }
5219 else {
5220 /* microseconds */
5221 given_spec = 4;
5222 }
5223 }
5224 else {
5225 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5226 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5227 if (given_spec == 3) {
5228 us = us / 1000;
5229 }
5230 break;
5231 }
5232 }
5233 }
5234
5235 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5236 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5237 return NULL;
5238 }
5239 else {
5240 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005241 GET_YEAR(self), GET_MONTH(self),
5242 GET_DAY(self), (int)sep,
5243 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5244 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005245 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005247 if (!result || !HASTZINFO(self))
5248 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005250 /* We need to append the UTC offset. */
5251 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5252 (PyObject *)self) < 0) {
5253 Py_DECREF(result);
5254 return NULL;
5255 }
5256 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5257 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005258}
5259
Tim Petersa9bc1682003-01-11 03:39:11 +00005260static PyObject *
5261datetime_ctime(PyDateTime_DateTime *self)
5262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005263 return format_ctime((PyDateTime_Date *)self,
5264 DATE_GET_HOUR(self),
5265 DATE_GET_MINUTE(self),
5266 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005267}
5268
Tim Peters2a799bf2002-12-16 20:18:38 +00005269/* Miscellaneous methods. */
5270
Tim Petersa9bc1682003-01-11 03:39:11 +00005271static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005272flip_fold(PyObject *dt)
5273{
5274 return new_datetime_ex2(GET_YEAR(dt),
5275 GET_MONTH(dt),
5276 GET_DAY(dt),
5277 DATE_GET_HOUR(dt),
5278 DATE_GET_MINUTE(dt),
5279 DATE_GET_SECOND(dt),
5280 DATE_GET_MICROSECOND(dt),
5281 HASTZINFO(dt) ?
5282 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5283 !DATE_GET_FOLD(dt),
5284 Py_TYPE(dt));
5285}
5286
5287static PyObject *
5288get_flip_fold_offset(PyObject *dt)
5289{
5290 PyObject *result, *flip_dt;
5291
5292 flip_dt = flip_fold(dt);
5293 if (flip_dt == NULL)
5294 return NULL;
5295 result = datetime_utcoffset(flip_dt, NULL);
5296 Py_DECREF(flip_dt);
5297 return result;
5298}
5299
5300/* PEP 495 exception: Whenever one or both of the operands in
5301 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakafd936662018-03-28 23:05:24 +03005302 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005303 *
5304 * Return 1 if exception applies, 0 if not, and -1 on error.
5305 */
5306static int
5307pep495_eq_exception(PyObject *self, PyObject *other,
5308 PyObject *offset_self, PyObject *offset_other)
5309{
5310 int result = 0;
5311 PyObject *flip_offset;
5312
5313 flip_offset = get_flip_fold_offset(self);
5314 if (flip_offset == NULL)
5315 return -1;
5316 if (flip_offset != offset_self &&
5317 delta_cmp(flip_offset, offset_self))
5318 {
5319 result = 1;
5320 goto done;
5321 }
5322 Py_DECREF(flip_offset);
5323
5324 flip_offset = get_flip_fold_offset(other);
5325 if (flip_offset == NULL)
5326 return -1;
5327 if (flip_offset != offset_other &&
5328 delta_cmp(flip_offset, offset_other))
5329 result = 1;
5330 done:
5331 Py_DECREF(flip_offset);
5332 return result;
5333}
5334
5335static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005336datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005337{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005338 PyObject *result = NULL;
5339 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005340 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005342 if (! PyDateTime_Check(other)) {
5343 if (PyDate_Check(other)) {
5344 /* Prevent invocation of date_richcompare. We want to
5345 return NotImplemented here to give the other object
5346 a chance. But since DateTime is a subclass of
5347 Date, if the other object is a Date, it would
5348 compute an ordering based on the date part alone,
5349 and we don't want that. So force unequal or
5350 uncomparable here in that case. */
5351 if (op == Py_EQ)
5352 Py_RETURN_FALSE;
5353 if (op == Py_NE)
5354 Py_RETURN_TRUE;
5355 return cmperror(self, other);
5356 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005357 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005358 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005359
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005360 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005361 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5362 ((PyDateTime_DateTime *)other)->data,
5363 _PyDateTime_DATETIME_DATASIZE);
5364 return diff_to_bool(diff, op);
5365 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005366 offset1 = datetime_utcoffset(self, NULL);
5367 if (offset1 == NULL)
5368 return NULL;
5369 offset2 = datetime_utcoffset(other, NULL);
5370 if (offset2 == NULL)
5371 goto done;
5372 /* If they're both naive, or both aware and have the same offsets,
5373 * we get off cheap. Note that if they're both naive, offset1 ==
5374 * offset2 == Py_None at this point.
5375 */
5376 if ((offset1 == offset2) ||
5377 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5378 delta_cmp(offset1, offset2) == 0)) {
5379 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5380 ((PyDateTime_DateTime *)other)->data,
5381 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005382 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5383 int ex = pep495_eq_exception(self, other, offset1, offset2);
5384 if (ex == -1)
5385 goto done;
5386 if (ex)
5387 diff = 1;
5388 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005389 result = diff_to_bool(diff, op);
5390 }
5391 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005392 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005393
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005394 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005395 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5396 other);
5397 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005398 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005399 diff = GET_TD_DAYS(delta);
5400 if (diff == 0)
5401 diff = GET_TD_SECONDS(delta) |
5402 GET_TD_MICROSECONDS(delta);
5403 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005404 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5405 int ex = pep495_eq_exception(self, other, offset1, offset2);
5406 if (ex == -1)
5407 goto done;
5408 if (ex)
5409 diff = 1;
5410 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005411 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005412 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005413 else if (op == Py_EQ) {
5414 result = Py_False;
5415 Py_INCREF(result);
5416 }
5417 else if (op == Py_NE) {
5418 result = Py_True;
5419 Py_INCREF(result);
5420 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005421 else {
5422 PyErr_SetString(PyExc_TypeError,
5423 "can't compare offset-naive and "
5424 "offset-aware datetimes");
5425 }
5426 done:
5427 Py_DECREF(offset1);
5428 Py_XDECREF(offset2);
5429 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005430}
5431
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005432static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005433datetime_hash(PyDateTime_DateTime *self)
5434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005435 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005436 PyObject *offset, *self0;
5437 if (DATE_GET_FOLD(self)) {
5438 self0 = new_datetime_ex2(GET_YEAR(self),
5439 GET_MONTH(self),
5440 GET_DAY(self),
5441 DATE_GET_HOUR(self),
5442 DATE_GET_MINUTE(self),
5443 DATE_GET_SECOND(self),
5444 DATE_GET_MICROSECOND(self),
5445 HASTZINFO(self) ? self->tzinfo : Py_None,
5446 0, Py_TYPE(self));
5447 if (self0 == NULL)
5448 return -1;
5449 }
5450 else {
5451 self0 = (PyObject *)self;
5452 Py_INCREF(self0);
5453 }
5454 offset = datetime_utcoffset(self0, NULL);
5455 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005456
5457 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005458 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005460 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005461 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005462 self->hashcode = generic_hash(
5463 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005464 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005465 PyObject *temp1, *temp2;
5466 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005468 assert(HASTZINFO(self));
5469 days = ymd_to_ord(GET_YEAR(self),
5470 GET_MONTH(self),
5471 GET_DAY(self));
5472 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005473 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005474 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005475 temp1 = new_delta(days, seconds,
5476 DATE_GET_MICROSECOND(self),
5477 1);
5478 if (temp1 == NULL) {
5479 Py_DECREF(offset);
5480 return -1;
5481 }
5482 temp2 = delta_subtract(temp1, offset);
5483 Py_DECREF(temp1);
5484 if (temp2 == NULL) {
5485 Py_DECREF(offset);
5486 return -1;
5487 }
5488 self->hashcode = PyObject_Hash(temp2);
5489 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005490 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005491 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005492 }
5493 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005494}
Tim Peters2a799bf2002-12-16 20:18:38 +00005495
5496static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005497datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005499 PyObject *clone;
5500 PyObject *tuple;
5501 int y = GET_YEAR(self);
5502 int m = GET_MONTH(self);
5503 int d = GET_DAY(self);
5504 int hh = DATE_GET_HOUR(self);
5505 int mm = DATE_GET_MINUTE(self);
5506 int ss = DATE_GET_SECOND(self);
5507 int us = DATE_GET_MICROSECOND(self);
5508 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005509 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005510
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005511 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005512 datetime_kws,
5513 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005514 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005515 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005516 if (fold != 0 && fold != 1) {
5517 PyErr_SetString(PyExc_ValueError,
5518 "fold must be either 0 or 1");
5519 return NULL;
5520 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005521 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5522 if (tuple == NULL)
5523 return NULL;
5524 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005525 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005526 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005527 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005528 Py_DECREF(tuple);
5529 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005530}
5531
5532static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005533local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005534{
5535 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005536 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005537 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005538 PyObject *nameo = NULL;
5539 const char *zone = NULL;
5540
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005541 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005542 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005543#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005544 zone = local_time_tm.tm_zone;
5545 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005546#else /* HAVE_STRUCT_TM_TM_ZONE */
5547 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005548 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005549 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005550 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005551 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005552 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005553 local_time = new_datetime(local_time_tm.tm_year + 1900,
5554 local_time_tm.tm_mon + 1,
5555 local_time_tm.tm_mday,
5556 local_time_tm.tm_hour,
5557 local_time_tm.tm_min,
5558 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005559 if (local_time == NULL) {
5560 return NULL;
5561 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005562 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005563 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005564 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5565 utc_time_tm.tm_mon + 1,
5566 utc_time_tm.tm_mday,
5567 utc_time_tm.tm_hour,
5568 utc_time_tm.tm_min,
5569 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005570 if (utc_time == NULL) {
5571 Py_DECREF(local_time);
5572 return NULL;
5573 }
5574 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005575 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005576 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005577 }
5578#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005579 if (delta == NULL) {
5580 return NULL;
5581 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005582 if (zone != NULL) {
5583 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5584 if (nameo == NULL)
5585 goto error;
5586 }
5587 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005588 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005589 error:
5590 Py_DECREF(delta);
5591 return result;
5592}
5593
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005594static PyObject *
5595local_timezone(PyDateTime_DateTime *utc_time)
5596{
5597 time_t timestamp;
5598 PyObject *delta;
5599 PyObject *one_second;
5600 PyObject *seconds;
5601
5602 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5603 if (delta == NULL)
5604 return NULL;
5605 one_second = new_delta(0, 1, 0, 0);
5606 if (one_second == NULL) {
5607 Py_DECREF(delta);
5608 return NULL;
5609 }
5610 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5611 (PyDateTime_Delta *)one_second);
5612 Py_DECREF(one_second);
5613 Py_DECREF(delta);
5614 if (seconds == NULL)
5615 return NULL;
5616 timestamp = _PyLong_AsTime_t(seconds);
5617 Py_DECREF(seconds);
5618 if (timestamp == -1 && PyErr_Occurred())
5619 return NULL;
5620 return local_timezone_from_timestamp(timestamp);
5621}
5622
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005623static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005624local_to_seconds(int year, int month, int day,
5625 int hour, int minute, int second, int fold);
5626
5627static PyObject *
5628local_timezone_from_local(PyDateTime_DateTime *local_dt)
5629{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005630 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005631 time_t timestamp;
5632 seconds = local_to_seconds(GET_YEAR(local_dt),
5633 GET_MONTH(local_dt),
5634 GET_DAY(local_dt),
5635 DATE_GET_HOUR(local_dt),
5636 DATE_GET_MINUTE(local_dt),
5637 DATE_GET_SECOND(local_dt),
5638 DATE_GET_FOLD(local_dt));
5639 if (seconds == -1)
5640 return NULL;
5641 /* XXX: add bounds check */
5642 timestamp = seconds - epoch;
5643 return local_timezone_from_timestamp(timestamp);
5644}
5645
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005646static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005647datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005648{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005649 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005650 PyObject *offset;
5651 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005652 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005653 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005654 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005655
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005656 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005657 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005658 return NULL;
5659
5660 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005661 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005662
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005663 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005664 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005665 self_tzinfo = local_timezone_from_local(self);
5666 if (self_tzinfo == NULL)
5667 return NULL;
5668 } else {
5669 self_tzinfo = self->tzinfo;
5670 Py_INCREF(self_tzinfo);
5671 }
Tim Peters521fc152002-12-31 17:36:56 +00005672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005673 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005674 if (self_tzinfo == tzinfo) {
5675 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005676 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005677 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005678 }
Tim Peters521fc152002-12-31 17:36:56 +00005679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005680 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005681 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5682 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005683 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005684 return NULL;
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005685 else if(offset == Py_None) {
5686 Py_DECREF(offset);
5687 goto naive;
5688 }
5689 else if (!PyDelta_Check(offset)) {
5690 Py_DECREF(offset);
5691 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5692 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5693 return NULL;
5694 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005695 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005696 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5697 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005698 Py_DECREF(offset);
5699 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005700 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005701
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005702 /* Make sure result is aware and UTC. */
5703 if (!HASTZINFO(result)) {
5704 temp = (PyObject *)result;
5705 result = (PyDateTime_DateTime *)
5706 new_datetime_ex2(GET_YEAR(result),
5707 GET_MONTH(result),
5708 GET_DAY(result),
5709 DATE_GET_HOUR(result),
5710 DATE_GET_MINUTE(result),
5711 DATE_GET_SECOND(result),
5712 DATE_GET_MICROSECOND(result),
5713 PyDateTime_TimeZone_UTC,
5714 DATE_GET_FOLD(result),
5715 Py_TYPE(result));
5716 Py_DECREF(temp);
5717 if (result == NULL)
5718 return NULL;
5719 }
5720 else {
5721 /* Result is already aware - just replace tzinfo. */
5722 temp = result->tzinfo;
5723 result->tzinfo = PyDateTime_TimeZone_UTC;
5724 Py_INCREF(result->tzinfo);
5725 Py_DECREF(temp);
5726 }
5727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005728 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005729 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005730 if (tzinfo == Py_None) {
5731 tzinfo = local_timezone(result);
5732 if (tzinfo == NULL) {
5733 Py_DECREF(result);
5734 return NULL;
5735 }
5736 }
5737 else
5738 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005739 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005740 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005741
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005742 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005743 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005744 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005745 Py_DECREF(temp);
5746
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005747 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005748}
5749
5750static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005751datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005753 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005755 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005756 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005757
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005758 dst = call_dst(self->tzinfo, (PyObject *)self);
5759 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005760 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005761
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005762 if (dst != Py_None)
5763 dstflag = delta_bool((PyDateTime_Delta *)dst);
5764 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005765 }
5766 return build_struct_time(GET_YEAR(self),
5767 GET_MONTH(self),
5768 GET_DAY(self),
5769 DATE_GET_HOUR(self),
5770 DATE_GET_MINUTE(self),
5771 DATE_GET_SECOND(self),
5772 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005773}
5774
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005775static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005776local_to_seconds(int year, int month, int day,
5777 int hour, int minute, int second, int fold)
5778{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005779 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005780 t = utc_to_seconds(year, month, day, hour, minute, second);
5781 /* Our goal is to solve t = local(u) for u. */
5782 lt = local(t);
5783 if (lt == -1)
5784 return -1;
5785 a = lt - t;
5786 u1 = t - a;
5787 t1 = local(u1);
5788 if (t1 == -1)
5789 return -1;
5790 if (t1 == t) {
5791 /* We found one solution, but it may not be the one we need.
5792 * Look for an earlier solution (if `fold` is 0), or a
5793 * later one (if `fold` is 1). */
5794 if (fold)
5795 u2 = u1 + max_fold_seconds;
5796 else
5797 u2 = u1 - max_fold_seconds;
5798 lt = local(u2);
5799 if (lt == -1)
5800 return -1;
5801 b = lt - u2;
5802 if (a == b)
5803 return u1;
5804 }
5805 else {
5806 b = t1 - u1;
5807 assert(a != b);
5808 }
5809 u2 = t - b;
5810 t2 = local(u2);
5811 if (t2 == -1)
5812 return -1;
5813 if (t2 == t)
5814 return u2;
5815 if (t1 == t)
5816 return u1;
5817 /* We have found both offsets a and b, but neither t - a nor t - b is
5818 * a solution. This means t is in the gap. */
5819 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5820}
5821
5822/* date(1970,1,1).toordinal() == 719163 */
5823#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5824
Tim Peters2a799bf2002-12-16 20:18:38 +00005825static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005826datetime_timestamp(PyDateTime_DateTime *self)
5827{
5828 PyObject *result;
5829
5830 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5831 PyObject *delta;
5832 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5833 if (delta == NULL)
5834 return NULL;
5835 result = delta_total_seconds(delta);
5836 Py_DECREF(delta);
5837 }
5838 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005839 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005840 seconds = local_to_seconds(GET_YEAR(self),
5841 GET_MONTH(self),
5842 GET_DAY(self),
5843 DATE_GET_HOUR(self),
5844 DATE_GET_MINUTE(self),
5845 DATE_GET_SECOND(self),
5846 DATE_GET_FOLD(self));
5847 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005848 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005849 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5850 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005851 }
5852 return result;
5853}
5854
5855static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005856datetime_getdate(PyDateTime_DateTime *self)
5857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005858 return new_date(GET_YEAR(self),
5859 GET_MONTH(self),
5860 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005861}
5862
5863static PyObject *
5864datetime_gettime(PyDateTime_DateTime *self)
5865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005866 return new_time(DATE_GET_HOUR(self),
5867 DATE_GET_MINUTE(self),
5868 DATE_GET_SECOND(self),
5869 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005870 Py_None,
5871 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005872}
5873
5874static PyObject *
5875datetime_gettimetz(PyDateTime_DateTime *self)
5876{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005877 return new_time(DATE_GET_HOUR(self),
5878 DATE_GET_MINUTE(self),
5879 DATE_GET_SECOND(self),
5880 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005881 GET_DT_TZINFO(self),
5882 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005883}
5884
5885static PyObject *
5886datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005887{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005888 int y, m, d, hh, mm, ss;
5889 PyObject *tzinfo;
5890 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005891
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005892 tzinfo = GET_DT_TZINFO(self);
5893 if (tzinfo == Py_None) {
5894 utcself = self;
5895 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005896 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005897 else {
5898 PyObject *offset;
5899 offset = call_utcoffset(tzinfo, (PyObject *)self);
5900 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005901 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005902 if (offset == Py_None) {
5903 Py_DECREF(offset);
5904 utcself = self;
5905 Py_INCREF(utcself);
5906 }
5907 else {
5908 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5909 (PyDateTime_Delta *)offset, -1);
5910 Py_DECREF(offset);
5911 if (utcself == NULL)
5912 return NULL;
5913 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005914 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005915 y = GET_YEAR(utcself);
5916 m = GET_MONTH(utcself);
5917 d = GET_DAY(utcself);
5918 hh = DATE_GET_HOUR(utcself);
5919 mm = DATE_GET_MINUTE(utcself);
5920 ss = DATE_GET_SECOND(utcself);
5921
5922 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005923 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005924}
5925
Tim Peters371935f2003-02-01 01:52:50 +00005926/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005927
Tim Petersa9bc1682003-01-11 03:39:11 +00005928/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005929 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5930 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005931 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005932 */
5933static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005934datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005936 PyObject *basestate;
5937 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005939 basestate = PyBytes_FromStringAndSize((char *)self->data,
5940 _PyDateTime_DATETIME_DATASIZE);
5941 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005942 if (proto > 3 && DATE_GET_FOLD(self))
5943 /* Set the first bit of the third byte */
5944 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005945 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5946 result = PyTuple_Pack(1, basestate);
5947 else
5948 result = PyTuple_Pack(2, basestate, self->tzinfo);
5949 Py_DECREF(basestate);
5950 }
5951 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005952}
5953
5954static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005955datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005956{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005957 int proto;
5958 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005959 return NULL;
5960
5961 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005962}
5963
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005964static PyObject *
5965datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5966{
5967 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5968}
5969
Tim Petersa9bc1682003-01-11 03:39:11 +00005970static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005972 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005973
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005974 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005976 {"utcnow", (PyCFunction)datetime_utcnow,
5977 METH_NOARGS | METH_CLASS,
5978 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005980 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5981 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5982 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005984 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5985 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005986 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005988 {"strptime", (PyCFunction)datetime_strptime,
5989 METH_VARARGS | METH_CLASS,
5990 PyDoc_STR("string, format -> new datetime parsed from a string "
5991 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005993 {"combine", (PyCFunction)datetime_combine,
5994 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5995 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005996
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005997 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
5998 METH_O | METH_CLASS,
5999 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
6000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006001 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00006002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006003 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6004 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006006 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6007 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006009 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6010 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006012 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6013 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006015 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6016 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006017
Alexander Belopolskya4415142012-06-08 12:33:09 -04006018 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6019 PyDoc_STR("Return POSIX timestamp as float.")},
6020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006021 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6022 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006024 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
6025 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006026 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006027 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006028 "defaults to 'T'.\n"
6029 "timespec specifies what components of the time to include"
6030 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6031 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006033 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6034 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006036 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6037 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006039 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6040 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006042 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
6043 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006045 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
6046 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006047
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006048 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006049 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006050
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006051 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6052 PyDoc_STR("__reduce__() -> (cls, state)")},
6053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006054 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006055};
6056
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006057static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006058PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6059\n\
6060The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006061instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006062
Tim Petersa9bc1682003-01-11 03:39:11 +00006063static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006064 datetime_add, /* nb_add */
6065 datetime_subtract, /* nb_subtract */
6066 0, /* nb_multiply */
6067 0, /* nb_remainder */
6068 0, /* nb_divmod */
6069 0, /* nb_power */
6070 0, /* nb_negative */
6071 0, /* nb_positive */
6072 0, /* nb_absolute */
6073 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006074};
6075
Neal Norwitz227b5332006-03-22 09:28:35 +00006076static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006077 PyVarObject_HEAD_INIT(NULL, 0)
6078 "datetime.datetime", /* tp_name */
6079 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6080 0, /* tp_itemsize */
6081 (destructor)datetime_dealloc, /* tp_dealloc */
6082 0, /* tp_print */
6083 0, /* tp_getattr */
6084 0, /* tp_setattr */
6085 0, /* tp_reserved */
6086 (reprfunc)datetime_repr, /* tp_repr */
6087 &datetime_as_number, /* tp_as_number */
6088 0, /* tp_as_sequence */
6089 0, /* tp_as_mapping */
6090 (hashfunc)datetime_hash, /* tp_hash */
6091 0, /* tp_call */
6092 (reprfunc)datetime_str, /* tp_str */
6093 PyObject_GenericGetAttr, /* tp_getattro */
6094 0, /* tp_setattro */
6095 0, /* tp_as_buffer */
6096 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6097 datetime_doc, /* tp_doc */
6098 0, /* tp_traverse */
6099 0, /* tp_clear */
6100 datetime_richcompare, /* tp_richcompare */
6101 0, /* tp_weaklistoffset */
6102 0, /* tp_iter */
6103 0, /* tp_iternext */
6104 datetime_methods, /* tp_methods */
6105 0, /* tp_members */
6106 datetime_getset, /* tp_getset */
6107 &PyDateTime_DateType, /* tp_base */
6108 0, /* tp_dict */
6109 0, /* tp_descr_get */
6110 0, /* tp_descr_set */
6111 0, /* tp_dictoffset */
6112 0, /* tp_init */
6113 datetime_alloc, /* tp_alloc */
6114 datetime_new, /* tp_new */
6115 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006116};
6117
6118/* ---------------------------------------------------------------------------
6119 * Module methods and initialization.
6120 */
6121
6122static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006123 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006124};
6125
Tim Peters9ddf40b2004-06-20 22:41:32 +00006126/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6127 * datetime.h.
6128 */
6129static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006130 &PyDateTime_DateType,
6131 &PyDateTime_DateTimeType,
6132 &PyDateTime_TimeType,
6133 &PyDateTime_DeltaType,
6134 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006135 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006136 new_date_ex,
6137 new_datetime_ex,
6138 new_time_ex,
6139 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006140 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006141 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006142 date_fromtimestamp,
6143 new_datetime_ex2,
6144 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006145};
6146
6147
Martin v. Löwis1a214512008-06-11 05:26:20 +00006148
6149static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006150 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006151 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006152 "Fast implementation of the datetime type.",
6153 -1,
6154 module_methods,
6155 NULL,
6156 NULL,
6157 NULL,
6158 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006159};
6160
Tim Peters2a799bf2002-12-16 20:18:38 +00006161PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006162PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006164 PyObject *m; /* a module object */
6165 PyObject *d; /* its dict */
6166 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006167 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006169 m = PyModule_Create(&datetimemodule);
6170 if (m == NULL)
6171 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006173 if (PyType_Ready(&PyDateTime_DateType) < 0)
6174 return NULL;
6175 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6176 return NULL;
6177 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6178 return NULL;
6179 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6180 return NULL;
6181 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6182 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006183 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6184 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006186 /* timedelta values */
6187 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006189 x = new_delta(0, 0, 1, 0);
6190 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6191 return NULL;
6192 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006194 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6195 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6196 return NULL;
6197 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006199 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6200 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6201 return NULL;
6202 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006204 /* date values */
6205 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006207 x = new_date(1, 1, 1);
6208 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6209 return NULL;
6210 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006212 x = new_date(MAXYEAR, 12, 31);
6213 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6214 return NULL;
6215 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006217 x = new_delta(1, 0, 0, 0);
6218 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6219 return NULL;
6220 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006222 /* time values */
6223 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006224
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006225 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006226 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6227 return NULL;
6228 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006229
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006230 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006231 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6232 return NULL;
6233 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006235 x = new_delta(0, 0, 1, 0);
6236 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6237 return NULL;
6238 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006240 /* datetime values */
6241 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006242
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006243 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006244 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6245 return NULL;
6246 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006247
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006248 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006249 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6250 return NULL;
6251 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006253 x = new_delta(0, 0, 1, 0);
6254 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6255 return NULL;
6256 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006257
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006258 /* timezone values */
6259 d = PyDateTime_TimeZoneType.tp_dict;
6260
6261 delta = new_delta(0, 0, 0, 0);
6262 if (delta == NULL)
6263 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006264 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006265 Py_DECREF(delta);
6266 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6267 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006268 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006269 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006270
6271 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6272 if (delta == NULL)
6273 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006274 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006275 Py_DECREF(delta);
6276 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6277 return NULL;
6278 Py_DECREF(x);
6279
6280 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6281 if (delta == NULL)
6282 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006283 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006284 Py_DECREF(delta);
6285 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6286 return NULL;
6287 Py_DECREF(x);
6288
Alexander Belopolskya4415142012-06-08 12:33:09 -04006289 /* Epoch */
6290 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006291 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006292 if (PyDateTime_Epoch == NULL)
6293 return NULL;
6294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006295 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006296 PyModule_AddIntMacro(m, MINYEAR);
6297 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006299 Py_INCREF(&PyDateTime_DateType);
6300 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006302 Py_INCREF(&PyDateTime_DateTimeType);
6303 PyModule_AddObject(m, "datetime",
6304 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006306 Py_INCREF(&PyDateTime_TimeType);
6307 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006309 Py_INCREF(&PyDateTime_DeltaType);
6310 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006312 Py_INCREF(&PyDateTime_TZInfoType);
6313 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006314
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006315 Py_INCREF(&PyDateTime_TimeZoneType);
6316 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006318 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6319 if (x == NULL)
6320 return NULL;
6321 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006323 /* A 4-year cycle has an extra leap day over what we'd get from
6324 * pasting together 4 single years.
6325 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006326 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006327 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006329 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6330 * get from pasting together 4 100-year cycles.
6331 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006332 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006333 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006335 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6336 * pasting together 25 4-year cycles.
6337 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006338 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006339 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006341 us_per_ms = PyLong_FromLong(1000);
6342 us_per_second = PyLong_FromLong(1000000);
6343 us_per_minute = PyLong_FromLong(60000000);
6344 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006345 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006346 us_per_minute == NULL || seconds_per_day == NULL)
6347 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006349 /* The rest are too big for 32-bit ints, but even
6350 * us_per_week fits in 40 bits, so doubles should be exact.
6351 */
6352 us_per_hour = PyLong_FromDouble(3600000000.0);
6353 us_per_day = PyLong_FromDouble(86400000000.0);
6354 us_per_week = PyLong_FromDouble(604800000000.0);
6355 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6356 return NULL;
6357 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006358}
Tim Petersf3615152003-01-01 21:51:37 +00006359
6360/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006361Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006362 x.n = x stripped of its timezone -- its naive time.
6363 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006364 return None
Tim Petersf3615152003-01-01 21:51:37 +00006365 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006366 return None
Tim Petersf3615152003-01-01 21:51:37 +00006367 x.s = x's standard offset, x.o - x.d
6368
6369Now some derived rules, where k is a duration (timedelta).
6370
63711. x.o = x.s + x.d
6372 This follows from the definition of x.s.
6373
Tim Petersc5dc4da2003-01-02 17:55:03 +000063742. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006375 This is actually a requirement, an assumption we need to make about
6376 sane tzinfo classes.
6377
63783. The naive UTC time corresponding to x is x.n - x.o.
6379 This is again a requirement for a sane tzinfo class.
6380
63814. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006382 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006383
Tim Petersc5dc4da2003-01-02 17:55:03 +000063845. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006385 Again follows from how arithmetic is defined.
6386
Tim Peters8bb5ad22003-01-24 02:44:45 +00006387Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006388(meaning that the various tzinfo methods exist, and don't blow up or return
6389None when called).
6390
Tim Petersa9bc1682003-01-11 03:39:11 +00006391The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006392x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006393
6394By #3, we want
6395
Tim Peters8bb5ad22003-01-24 02:44:45 +00006396 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006397
6398The algorithm starts by attaching tz to x.n, and calling that y. So
6399x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6400becomes true; in effect, we want to solve [2] for k:
6401
Tim Peters8bb5ad22003-01-24 02:44:45 +00006402 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006403
6404By #1, this is the same as
6405
Tim Peters8bb5ad22003-01-24 02:44:45 +00006406 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006407
6408By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6409Substituting that into [3],
6410
Tim Peters8bb5ad22003-01-24 02:44:45 +00006411 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6412 k - (y+k).s - (y+k).d = 0; rearranging,
6413 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6414 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006415
Tim Peters8bb5ad22003-01-24 02:44:45 +00006416On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6417approximate k by ignoring the (y+k).d term at first. Note that k can't be
6418very large, since all offset-returning methods return a duration of magnitude
6419less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6420be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006421
6422In any case, the new value is
6423
Tim Peters8bb5ad22003-01-24 02:44:45 +00006424 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006425
Tim Peters8bb5ad22003-01-24 02:44:45 +00006426It's helpful to step back at look at [4] from a higher level: it's simply
6427mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006428
6429At this point, if
6430
Tim Peters8bb5ad22003-01-24 02:44:45 +00006431 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006432
6433we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006434at the start of daylight time. Picture US Eastern for concreteness. The wall
6435time 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 +00006436sense then. The docs ask that an Eastern tzinfo class consider such a time to
6437be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6438on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006439the only spelling that makes sense on the local wall clock.
6440
Tim Petersc5dc4da2003-01-02 17:55:03 +00006441In fact, if [5] holds at this point, we do have the standard-time spelling,
6442but that takes a bit of proof. We first prove a stronger result. What's the
6443difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006444
Tim Peters8bb5ad22003-01-24 02:44:45 +00006445 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006446
Tim Petersc5dc4da2003-01-02 17:55:03 +00006447Now
6448 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006449 (y + y.s).n = by #5
6450 y.n + y.s = since y.n = x.n
6451 x.n + y.s = since z and y are have the same tzinfo member,
6452 y.s = z.s by #2
6453 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006454
Tim Petersc5dc4da2003-01-02 17:55:03 +00006455Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006456
Tim Petersc5dc4da2003-01-02 17:55:03 +00006457 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006458 x.n - ((x.n + z.s) - z.o) = expanding
6459 x.n - x.n - z.s + z.o = cancelling
6460 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006461 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006462
Tim Petersc5dc4da2003-01-02 17:55:03 +00006463So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006464
Tim Petersc5dc4da2003-01-02 17:55:03 +00006465If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006466spelling we wanted in the endcase described above. We're done. Contrarily,
6467if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006468
Tim Petersc5dc4da2003-01-02 17:55:03 +00006469If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6470add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006471local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006472
Tim Petersc5dc4da2003-01-02 17:55:03 +00006473Let
Tim Petersf3615152003-01-01 21:51:37 +00006474
Tim Peters4fede1a2003-01-04 00:26:59 +00006475 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006476
Tim Peters4fede1a2003-01-04 00:26:59 +00006477and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006478
Tim Peters8bb5ad22003-01-24 02:44:45 +00006479 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006480
Tim Peters8bb5ad22003-01-24 02:44:45 +00006481If so, we're done. If not, the tzinfo class is insane, according to the
6482assumptions we've made. This also requires a bit of proof. As before, let's
6483compute the difference between the LHS and RHS of [8] (and skipping some of
6484the justifications for the kinds of substitutions we've done several times
6485already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006486
Tim Peters8bb5ad22003-01-24 02:44:45 +00006487 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006488 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6489 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6490 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6491 - z.n + z.n - z.o + z'.o = cancel z.n
6492 - z.o + z'.o = #1 twice
6493 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6494 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006495
6496So 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 +00006497we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6498return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006499
Tim Peters8bb5ad22003-01-24 02:44:45 +00006500How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6501a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6502would have to change the result dst() returns: we start in DST, and moving
6503a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006504
Tim Peters8bb5ad22003-01-24 02:44:45 +00006505There isn't a sane case where this can happen. The closest it gets is at
6506the end of DST, where there's an hour in UTC with no spelling in a hybrid
6507tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6508that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6509UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6510time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6511clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6512standard time. Since that's what the local clock *does*, we want to map both
6513UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006514in local time, but so it goes -- it's the way the local clock works.
6515
Tim Peters8bb5ad22003-01-24 02:44:45 +00006516When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6517so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6518z' = 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 +00006519(correctly) concludes that z' is not UTC-equivalent to x.
6520
6521Because we know z.d said z was in daylight time (else [5] would have held and
6522we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006523and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006524return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6525but the reasoning doesn't depend on the example -- it depends on there being
6526two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006527z' must be in standard time, and is the spelling we want in this case.
6528
6529Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6530concerned (because it takes z' as being in standard time rather than the
6531daylight time we intend here), but returning it gives the real-life "local
6532clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6533tz.
6534
6535When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6536the 1:MM standard time spelling we want.
6537
6538So how can this break? One of the assumptions must be violated. Two
6539possibilities:
6540
65411) [2] effectively says that y.s is invariant across all y belong to a given
6542 time zone. This isn't true if, for political reasons or continental drift,
6543 a region decides to change its base offset from UTC.
6544
65452) There may be versions of "double daylight" time where the tail end of
6546 the analysis gives up a step too early. I haven't thought about that
6547 enough to say.
6548
6549In any case, it's clear that the default fromutc() is strong enough to handle
6550"almost all" time zones: so long as the standard offset is invariant, it
6551doesn't matter if daylight time transition points change from year to year, or
6552if daylight time is skipped in some years; it doesn't matter how large or
6553small dst() may get within its bounds; and it doesn't even matter if some
6554perverse time zone returns a negative dst()). So a breaking case must be
6555pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006556--------------------------------------------------------------------------- */