blob: 076912d58f4af82a13b70498e89673f392b52396 [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);
1293 tzinfo = new_timezone(delta, NULL);
1294 Py_XDECREF(delta);
1295 } else {
1296 tzinfo = Py_None;
1297 Py_INCREF(Py_None);
1298 }
1299
1300 return tzinfo;
1301}
1302
Tim Peters2a799bf2002-12-16 20:18:38 +00001303/* ---------------------------------------------------------------------------
1304 * String format helpers.
1305 */
1306
1307static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001308format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001309{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001310 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1312 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001313 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1315 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1316 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1321 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1322 GET_DAY(date), hours, minutes, seconds,
1323 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001324}
1325
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001326static PyObject *delta_negative(PyDateTime_Delta *self);
1327
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001328/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001329 * buflen bytes remaining. The UTC offset is gotten by calling
1330 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1331 * *buf, and that's all. Else the returned value is checked for sanity (an
1332 * integer in range), and if that's OK it's converted to an hours & minutes
1333 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001334 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001335 * Returns 0 if everything is OK. If the return value from utcoffset() is
1336 * bogus, an appropriate exception is set and -1 is returned.
1337 */
1338static int
Tim Peters328fff72002-12-20 01:31:27 +00001339format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001341{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001342 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001343 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001347
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001348 offset = call_utcoffset(tzinfo, tzinfoarg);
1349 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001351 if (offset == Py_None) {
1352 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 *buf = '\0';
1354 return 0;
1355 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001356 /* Offset is normalized, so it is negative if days < 0 */
1357 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001359 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001360 if (offset == NULL)
1361 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001363 else {
1364 sign = '+';
1365 }
1366 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001367 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001368 seconds = GET_TD_SECONDS(offset);
1369 Py_DECREF(offset);
1370 minutes = divmod(seconds, 60, &seconds);
1371 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001372 if (microseconds) {
1373 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1374 hours, sep, minutes, sep, seconds, microseconds);
1375 return 0;
1376 }
1377 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001378 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1379 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001380 return 0;
1381 }
1382 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001384}
1385
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001386static PyObject *
1387make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 PyObject *temp;
1390 PyObject *tzinfo = get_tzinfo_member(object);
1391 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001392 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 if (Zreplacement == NULL)
1395 return NULL;
1396 if (tzinfo == Py_None || tzinfo == NULL)
1397 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 assert(tzinfoarg != NULL);
1400 temp = call_tzname(tzinfo, tzinfoarg);
1401 if (temp == NULL)
1402 goto Error;
1403 if (temp == Py_None) {
1404 Py_DECREF(temp);
1405 return Zreplacement;
1406 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 assert(PyUnicode_Check(temp));
1409 /* Since the tzname is getting stuffed into the
1410 * format, we have to double any % signs so that
1411 * strftime doesn't treat them as format codes.
1412 */
1413 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001414 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 Py_DECREF(temp);
1416 if (Zreplacement == NULL)
1417 return NULL;
1418 if (!PyUnicode_Check(Zreplacement)) {
1419 PyErr_SetString(PyExc_TypeError,
1420 "tzname.replace() did not return a string");
1421 goto Error;
1422 }
1423 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001424
1425 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 Py_DECREF(Zreplacement);
1427 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001428}
1429
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001430static PyObject *
1431make_freplacement(PyObject *object)
1432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 char freplacement[64];
1434 if (PyTime_Check(object))
1435 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1436 else if (PyDateTime_Check(object))
1437 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1438 else
1439 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001442}
1443
Tim Peters2a799bf2002-12-16 20:18:38 +00001444/* I sure don't want to reproduce the strftime code from the time module,
1445 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001446 * giving special meanings to the %z, %Z and %f format codes via a
1447 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001448 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1449 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001450 */
1451static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001452wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001454{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1458 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1459 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 const char *pin; /* pointer to next char in input format */
1462 Py_ssize_t flen; /* length of input format */
1463 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 PyObject *newfmt = NULL; /* py string, the output format */
1466 char *pnew; /* pointer to available byte in output format */
1467 size_t totalnew; /* number bytes total in output format buffer,
1468 exclusive of trailing \0 */
1469 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 const char *ptoappend; /* ptr to string to append to output buffer */
1472 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 assert(object && format && timetuple);
1475 assert(PyUnicode_Check(format));
1476 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001477 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 if (!pin)
1479 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 /* Scan the input format, looking for %z/%Z/%f escapes, building
1482 * a new format. Since computing the replacements for those codes
1483 * is expensive, don't unless they're actually used.
1484 */
1485 if (flen > INT_MAX - 1) {
1486 PyErr_NoMemory();
1487 goto Done;
1488 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 totalnew = flen + 1; /* realistic if no %z/%Z */
1491 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1492 if (newfmt == NULL) goto Done;
1493 pnew = PyBytes_AsString(newfmt);
1494 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 while ((ch = *pin++) != '\0') {
1497 if (ch != '%') {
1498 ptoappend = pin - 1;
1499 ntoappend = 1;
1500 }
1501 else if ((ch = *pin++) == '\0') {
1502 /* There's a lone trailing %; doesn't make sense. */
1503 PyErr_SetString(PyExc_ValueError, "strftime format "
1504 "ends with raw %");
1505 goto Done;
1506 }
1507 /* A % has been seen and ch is the character after it. */
1508 else if (ch == 'z') {
1509 if (zreplacement == NULL) {
1510 /* format utcoffset */
1511 char buf[100];
1512 PyObject *tzinfo = get_tzinfo_member(object);
1513 zreplacement = PyBytes_FromStringAndSize("", 0);
1514 if (zreplacement == NULL) goto Done;
1515 if (tzinfo != Py_None && tzinfo != NULL) {
1516 assert(tzinfoarg != NULL);
1517 if (format_utcoffset(buf,
1518 sizeof(buf),
1519 "",
1520 tzinfo,
1521 tzinfoarg) < 0)
1522 goto Done;
1523 Py_DECREF(zreplacement);
1524 zreplacement =
1525 PyBytes_FromStringAndSize(buf,
1526 strlen(buf));
1527 if (zreplacement == NULL)
1528 goto Done;
1529 }
1530 }
1531 assert(zreplacement != NULL);
1532 ptoappend = PyBytes_AS_STRING(zreplacement);
1533 ntoappend = PyBytes_GET_SIZE(zreplacement);
1534 }
1535 else if (ch == 'Z') {
1536 /* format tzname */
1537 if (Zreplacement == NULL) {
1538 Zreplacement = make_Zreplacement(object,
1539 tzinfoarg);
1540 if (Zreplacement == NULL)
1541 goto Done;
1542 }
1543 assert(Zreplacement != NULL);
1544 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001545 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001547 if (ptoappend == NULL)
1548 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 }
1550 else if (ch == 'f') {
1551 /* format microseconds */
1552 if (freplacement == NULL) {
1553 freplacement = make_freplacement(object);
1554 if (freplacement == NULL)
1555 goto Done;
1556 }
1557 assert(freplacement != NULL);
1558 assert(PyBytes_Check(freplacement));
1559 ptoappend = PyBytes_AS_STRING(freplacement);
1560 ntoappend = PyBytes_GET_SIZE(freplacement);
1561 }
1562 else {
1563 /* percent followed by neither z nor Z */
1564 ptoappend = pin - 2;
1565 ntoappend = 2;
1566 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 /* Append the ntoappend chars starting at ptoappend to
1569 * the new format.
1570 */
1571 if (ntoappend == 0)
1572 continue;
1573 assert(ptoappend != NULL);
1574 assert(ntoappend > 0);
1575 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001576 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 PyErr_NoMemory();
1578 goto Done;
1579 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001580 totalnew <<= 1;
1581 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 pnew = PyBytes_AsString(newfmt) + usednew;
1584 }
1585 memcpy(pnew, ptoappend, ntoappend);
1586 pnew += ntoappend;
1587 usednew += ntoappend;
1588 assert(usednew <= totalnew);
1589 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1592 goto Done;
1593 {
1594 PyObject *format;
1595 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 if (time == NULL)
1598 goto Done;
1599 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1600 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001601 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1602 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 Py_DECREF(format);
1604 }
1605 Py_DECREF(time);
1606 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001607 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 Py_XDECREF(freplacement);
1609 Py_XDECREF(zreplacement);
1610 Py_XDECREF(Zreplacement);
1611 Py_XDECREF(newfmt);
1612 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001613}
1614
Tim Peters2a799bf2002-12-16 20:18:38 +00001615/* ---------------------------------------------------------------------------
1616 * Wrap functions from the time module. These aren't directly available
1617 * from C. Perhaps they should be.
1618 */
1619
1620/* Call time.time() and return its result (a Python float). */
1621static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001622time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 PyObject *result = NULL;
1625 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001628 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001629
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001630 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 Py_DECREF(time);
1632 }
1633 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001634}
1635
1636/* Build a time.struct_time. The weekday and day number are automatically
1637 * computed from the y,m,d args.
1638 */
1639static PyObject *
1640build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001643 PyObject *result;
1644 _Py_IDENTIFIER(struct_time);
1645 PyObject *args;
1646
Tim Peters2a799bf2002-12-16 20:18:38 +00001647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001649 if (time == NULL) {
1650 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 }
Victor Stinner2b635972016-12-09 00:38:16 +01001652
1653 args = Py_BuildValue("iiiiiiiii",
1654 y, m, d,
1655 hh, mm, ss,
1656 weekday(y, m, d),
1657 days_before_month(y, m) + d,
1658 dstflag);
1659 if (args == NULL) {
1660 Py_DECREF(time);
1661 return NULL;
1662 }
1663
1664 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1665 args, NULL);
1666 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001667 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001669}
1670
1671/* ---------------------------------------------------------------------------
1672 * Miscellaneous helpers.
1673 */
1674
Mark Dickinsone94c6792009-02-02 20:36:42 +00001675/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001676 * The comparisons here all most naturally compute a cmp()-like result.
1677 * This little helper turns that into a bool result for rich comparisons.
1678 */
1679static PyObject *
1680diff_to_bool(int diff, int op)
1681{
stratakise8b19652017-11-02 11:32:54 +01001682 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001683}
1684
Tim Peters07534a62003-02-07 22:50:28 +00001685/* Raises a "can't compare" TypeError and returns NULL. */
1686static PyObject *
1687cmperror(PyObject *a, PyObject *b)
1688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 PyErr_Format(PyExc_TypeError,
1690 "can't compare %s to %s",
1691 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1692 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001693}
1694
Tim Peters2a799bf2002-12-16 20:18:38 +00001695/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001696 * Cached Python objects; these are set by the module init function.
1697 */
1698
1699/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700static PyObject *us_per_ms = NULL; /* 1000 */
1701static PyObject *us_per_second = NULL; /* 1000000 */
1702static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001703static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1704static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1705static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001706static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1707
Tim Peters2a799bf2002-12-16 20:18:38 +00001708/* ---------------------------------------------------------------------------
1709 * Class implementations.
1710 */
1711
1712/*
1713 * PyDateTime_Delta implementation.
1714 */
1715
1716/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001718 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001719 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1720 * due to ubiquitous overflow possibilities.
1721 */
1722static PyObject *
1723delta_to_microseconds(PyDateTime_Delta *self)
1724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 PyObject *x1 = NULL;
1726 PyObject *x2 = NULL;
1727 PyObject *x3 = NULL;
1728 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1731 if (x1 == NULL)
1732 goto Done;
1733 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1734 if (x2 == NULL)
1735 goto Done;
1736 Py_DECREF(x1);
1737 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 /* x2 has days in seconds */
1740 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1741 if (x1 == NULL)
1742 goto Done;
1743 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1744 if (x3 == NULL)
1745 goto Done;
1746 Py_DECREF(x1);
1747 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001748 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 /* x3 has days+seconds in seconds */
1751 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1752 if (x1 == NULL)
1753 goto Done;
1754 Py_DECREF(x3);
1755 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 /* x1 has days+seconds in us */
1758 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1759 if (x2 == NULL)
1760 goto Done;
1761 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001762 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001763
1764Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 Py_XDECREF(x1);
1766 Py_XDECREF(x2);
1767 Py_XDECREF(x3);
1768 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001769}
1770
Serhiy Storchaka95949422013-08-27 19:40:23 +03001771/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001772 */
1773static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001774microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 int us;
1777 int s;
1778 int d;
1779 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 PyObject *tuple = NULL;
1782 PyObject *num = NULL;
1783 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001784
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001785 assert(PyLong_CheckExact(pyus));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 tuple = PyNumber_Divmod(pyus, us_per_second);
1787 if (tuple == NULL)
1788 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 num = PyTuple_GetItem(tuple, 1); /* us */
1791 if (num == NULL)
1792 goto Done;
1793 temp = PyLong_AsLong(num);
1794 num = NULL;
1795 if (temp == -1 && PyErr_Occurred())
1796 goto Done;
1797 assert(0 <= temp && temp < 1000000);
1798 us = (int)temp;
1799 if (us < 0) {
1800 /* The divisor was positive, so this must be an error. */
1801 assert(PyErr_Occurred());
1802 goto Done;
1803 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1806 if (num == NULL)
1807 goto Done;
1808 Py_INCREF(num);
1809 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001810
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 tuple = PyNumber_Divmod(num, seconds_per_day);
1812 if (tuple == NULL)
1813 goto Done;
1814 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 num = PyTuple_GetItem(tuple, 1); /* seconds */
1817 if (num == NULL)
1818 goto Done;
1819 temp = PyLong_AsLong(num);
1820 num = NULL;
1821 if (temp == -1 && PyErr_Occurred())
1822 goto Done;
1823 assert(0 <= temp && temp < 24*3600);
1824 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 if (s < 0) {
1827 /* The divisor was positive, so this must be an error. */
1828 assert(PyErr_Occurred());
1829 goto Done;
1830 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1833 if (num == NULL)
1834 goto Done;
1835 Py_INCREF(num);
1836 temp = PyLong_AsLong(num);
1837 if (temp == -1 && PyErr_Occurred())
1838 goto Done;
1839 d = (int)temp;
1840 if ((long)d != temp) {
1841 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1842 "large to fit in a C int");
1843 goto Done;
1844 }
1845 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001846
1847Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 Py_XDECREF(tuple);
1849 Py_XDECREF(num);
1850 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001851}
1852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853#define microseconds_to_delta(pymicros) \
1854 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001855
Tim Peters2a799bf2002-12-16 20:18:38 +00001856static PyObject *
1857multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1858{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 PyObject *pyus_in;
1860 PyObject *pyus_out;
1861 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 pyus_in = delta_to_microseconds(delta);
1864 if (pyus_in == NULL)
1865 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1868 Py_DECREF(pyus_in);
1869 if (pyus_out == NULL)
1870 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 result = microseconds_to_delta(pyus_out);
1873 Py_DECREF(pyus_out);
1874 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001875}
1876
1877static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001878get_float_as_integer_ratio(PyObject *floatobj)
1879{
1880 PyObject *ratio;
1881
1882 assert(floatobj && PyFloat_Check(floatobj));
1883 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1884 if (ratio == NULL) {
1885 return NULL;
1886 }
1887 if (!PyTuple_Check(ratio)) {
1888 PyErr_Format(PyExc_TypeError,
1889 "unexpected return type from as_integer_ratio(): "
1890 "expected tuple, got '%.200s'",
1891 Py_TYPE(ratio)->tp_name);
1892 Py_DECREF(ratio);
1893 return NULL;
1894 }
1895 if (PyTuple_Size(ratio) != 2) {
1896 PyErr_SetString(PyExc_ValueError,
1897 "as_integer_ratio() must return a 2-tuple");
1898 Py_DECREF(ratio);
1899 return NULL;
1900 }
1901 return ratio;
1902}
1903
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001904/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001905static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001906multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001907{
1908 PyObject *result = NULL;
1909 PyObject *pyus_in = NULL, *temp, *pyus_out;
1910 PyObject *ratio = NULL;
1911
1912 pyus_in = delta_to_microseconds(delta);
1913 if (pyus_in == NULL)
1914 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001915 ratio = get_float_as_integer_ratio(floatobj);
1916 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001917 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001918 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001919 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001920 Py_DECREF(pyus_in);
1921 pyus_in = NULL;
1922 if (temp == NULL)
1923 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001924 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001925 Py_DECREF(temp);
1926 if (pyus_out == NULL)
1927 goto error;
1928 result = microseconds_to_delta(pyus_out);
1929 Py_DECREF(pyus_out);
1930 error:
1931 Py_XDECREF(pyus_in);
1932 Py_XDECREF(ratio);
1933
1934 return result;
1935}
1936
1937static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001938divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 PyObject *pyus_in;
1941 PyObject *pyus_out;
1942 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 pyus_in = delta_to_microseconds(delta);
1945 if (pyus_in == NULL)
1946 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1949 Py_DECREF(pyus_in);
1950 if (pyus_out == NULL)
1951 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 result = microseconds_to_delta(pyus_out);
1954 Py_DECREF(pyus_out);
1955 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001956}
1957
1958static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001959divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 PyObject *pyus_left;
1962 PyObject *pyus_right;
1963 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 pyus_left = delta_to_microseconds(left);
1966 if (pyus_left == NULL)
1967 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 pyus_right = delta_to_microseconds(right);
1970 if (pyus_right == NULL) {
1971 Py_DECREF(pyus_left);
1972 return NULL;
1973 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1976 Py_DECREF(pyus_left);
1977 Py_DECREF(pyus_right);
1978 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001979}
1980
1981static PyObject *
1982truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001984 PyObject *pyus_left;
1985 PyObject *pyus_right;
1986 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 pyus_left = delta_to_microseconds(left);
1989 if (pyus_left == NULL)
1990 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 pyus_right = delta_to_microseconds(right);
1993 if (pyus_right == NULL) {
1994 Py_DECREF(pyus_left);
1995 return NULL;
1996 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1999 Py_DECREF(pyus_left);
2000 Py_DECREF(pyus_right);
2001 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002}
2003
2004static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002005truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2006{
2007 PyObject *result;
2008 PyObject *pyus_in, *pyus_out;
2009 pyus_in = delta_to_microseconds(delta);
2010 if (pyus_in == NULL)
2011 return NULL;
2012 pyus_out = divide_nearest(pyus_in, i);
2013 Py_DECREF(pyus_in);
2014 if (pyus_out == NULL)
2015 return NULL;
2016 result = microseconds_to_delta(pyus_out);
2017 Py_DECREF(pyus_out);
2018
2019 return result;
2020}
2021
2022static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002023delta_add(PyObject *left, PyObject *right)
2024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2028 /* delta + delta */
2029 /* The C-level additions can't overflow because of the
2030 * invariant bounds.
2031 */
2032 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2033 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2034 int microseconds = GET_TD_MICROSECONDS(left) +
2035 GET_TD_MICROSECONDS(right);
2036 result = new_delta(days, seconds, microseconds, 1);
2037 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 if (result == Py_NotImplemented)
2040 Py_INCREF(result);
2041 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002042}
2043
2044static PyObject *
2045delta_negative(PyDateTime_Delta *self)
2046{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 return new_delta(-GET_TD_DAYS(self),
2048 -GET_TD_SECONDS(self),
2049 -GET_TD_MICROSECONDS(self),
2050 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002051}
2052
2053static PyObject *
2054delta_positive(PyDateTime_Delta *self)
2055{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 /* Could optimize this (by returning self) if this isn't a
2057 * subclass -- but who uses unary + ? Approximately nobody.
2058 */
2059 return new_delta(GET_TD_DAYS(self),
2060 GET_TD_SECONDS(self),
2061 GET_TD_MICROSECONDS(self),
2062 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002063}
2064
2065static PyObject *
2066delta_abs(PyDateTime_Delta *self)
2067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 assert(GET_TD_MICROSECONDS(self) >= 0);
2071 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 if (GET_TD_DAYS(self) < 0)
2074 result = delta_negative(self);
2075 else
2076 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002079}
2080
2081static PyObject *
2082delta_subtract(PyObject *left, PyObject *right)
2083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2087 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002088 /* The C-level additions can't overflow because of the
2089 * invariant bounds.
2090 */
2091 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2092 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2093 int microseconds = GET_TD_MICROSECONDS(left) -
2094 GET_TD_MICROSECONDS(right);
2095 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 if (result == Py_NotImplemented)
2099 Py_INCREF(result);
2100 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002101}
2102
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002103static int
2104delta_cmp(PyObject *self, PyObject *other)
2105{
2106 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2107 if (diff == 0) {
2108 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2109 if (diff == 0)
2110 diff = GET_TD_MICROSECONDS(self) -
2111 GET_TD_MICROSECONDS(other);
2112 }
2113 return diff;
2114}
2115
Tim Peters2a799bf2002-12-16 20:18:38 +00002116static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002117delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002118{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002120 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 return diff_to_bool(diff, op);
2122 }
2123 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002124 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002125 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002126}
2127
2128static PyObject *delta_getstate(PyDateTime_Delta *self);
2129
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002130static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002131delta_hash(PyDateTime_Delta *self)
2132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 if (self->hashcode == -1) {
2134 PyObject *temp = delta_getstate(self);
2135 if (temp != NULL) {
2136 self->hashcode = PyObject_Hash(temp);
2137 Py_DECREF(temp);
2138 }
2139 }
2140 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002141}
2142
2143static PyObject *
2144delta_multiply(PyObject *left, PyObject *right)
2145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 if (PyDelta_Check(left)) {
2149 /* delta * ??? */
2150 if (PyLong_Check(right))
2151 result = multiply_int_timedelta(right,
2152 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002153 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002154 result = multiply_truedivide_timedelta_float(
2155 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 }
2157 else if (PyLong_Check(left))
2158 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002159 (PyDateTime_Delta *) right);
2160 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002161 result = multiply_truedivide_timedelta_float(
2162 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 if (result == Py_NotImplemented)
2165 Py_INCREF(result);
2166 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002167}
2168
2169static PyObject *
2170delta_divide(PyObject *left, PyObject *right)
2171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 if (PyDelta_Check(left)) {
2175 /* delta * ??? */
2176 if (PyLong_Check(right))
2177 result = divide_timedelta_int(
2178 (PyDateTime_Delta *)left,
2179 right);
2180 else if (PyDelta_Check(right))
2181 result = divide_timedelta_timedelta(
2182 (PyDateTime_Delta *)left,
2183 (PyDateTime_Delta *)right);
2184 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 if (result == Py_NotImplemented)
2187 Py_INCREF(result);
2188 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002189}
2190
Mark Dickinson7c186e22010-04-20 22:32:49 +00002191static PyObject *
2192delta_truedivide(PyObject *left, PyObject *right)
2193{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 if (PyDelta_Check(left)) {
2197 if (PyDelta_Check(right))
2198 result = truedivide_timedelta_timedelta(
2199 (PyDateTime_Delta *)left,
2200 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002201 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002202 result = multiply_truedivide_timedelta_float(
2203 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002204 else if (PyLong_Check(right))
2205 result = truedivide_timedelta_int(
2206 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002207 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 if (result == Py_NotImplemented)
2210 Py_INCREF(result);
2211 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002212}
2213
2214static PyObject *
2215delta_remainder(PyObject *left, PyObject *right)
2216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 PyObject *pyus_left;
2218 PyObject *pyus_right;
2219 PyObject *pyus_remainder;
2220 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002221
Brian Curtindfc80e32011-08-10 20:28:54 -05002222 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2223 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2226 if (pyus_left == NULL)
2227 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2230 if (pyus_right == NULL) {
2231 Py_DECREF(pyus_left);
2232 return NULL;
2233 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2236 Py_DECREF(pyus_left);
2237 Py_DECREF(pyus_right);
2238 if (pyus_remainder == NULL)
2239 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 remainder = microseconds_to_delta(pyus_remainder);
2242 Py_DECREF(pyus_remainder);
2243 if (remainder == NULL)
2244 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002247}
2248
2249static PyObject *
2250delta_divmod(PyObject *left, PyObject *right)
2251{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002252 PyObject *pyus_left;
2253 PyObject *pyus_right;
2254 PyObject *divmod;
2255 PyObject *delta;
2256 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002257
Brian Curtindfc80e32011-08-10 20:28:54 -05002258 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2259 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2262 if (pyus_left == NULL)
2263 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2266 if (pyus_right == NULL) {
2267 Py_DECREF(pyus_left);
2268 return NULL;
2269 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2272 Py_DECREF(pyus_left);
2273 Py_DECREF(pyus_right);
2274 if (divmod == NULL)
2275 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 assert(PyTuple_Size(divmod) == 2);
2278 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2279 if (delta == NULL) {
2280 Py_DECREF(divmod);
2281 return NULL;
2282 }
2283 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2284 Py_DECREF(delta);
2285 Py_DECREF(divmod);
2286 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002287}
2288
Tim Peters2a799bf2002-12-16 20:18:38 +00002289/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2290 * timedelta constructor. sofar is the # of microseconds accounted for
2291 * so far, and there are factor microseconds per current unit, the number
2292 * of which is given by num. num * factor is added to sofar in a
2293 * numerically careful way, and that's the result. Any fractional
2294 * microseconds left over (this can happen if num is a float type) are
2295 * added into *leftover.
2296 * Note that there are many ways this can give an error (NULL) return.
2297 */
2298static PyObject *
2299accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2300 double *leftover)
2301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 PyObject *prod;
2303 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 if (PyLong_Check(num)) {
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002308 prod = PyNumber_Multiply(factor, num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002309 if (prod == NULL)
2310 return NULL;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002311 assert(PyLong_CheckExact(prod));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 sum = PyNumber_Add(sofar, prod);
2313 Py_DECREF(prod);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002314 assert(sum == NULL || PyLong_CheckExact(sum));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 return sum;
2316 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 if (PyFloat_Check(num)) {
2319 double dnum;
2320 double fracpart;
2321 double intpart;
2322 PyObject *x;
2323 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 /* The Plan: decompose num into an integer part and a
2326 * fractional part, num = intpart + fracpart.
2327 * Then num * factor ==
2328 * intpart * factor + fracpart * factor
2329 * and the LHS can be computed exactly in long arithmetic.
2330 * The RHS is again broken into an int part and frac part.
2331 * and the frac part is added into *leftover.
2332 */
2333 dnum = PyFloat_AsDouble(num);
2334 if (dnum == -1.0 && PyErr_Occurred())
2335 return NULL;
2336 fracpart = modf(dnum, &intpart);
2337 x = PyLong_FromDouble(intpart);
2338 if (x == NULL)
2339 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 prod = PyNumber_Multiply(x, factor);
2342 Py_DECREF(x);
2343 if (prod == NULL)
2344 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346 sum = PyNumber_Add(sofar, prod);
2347 Py_DECREF(prod);
2348 if (sum == NULL)
2349 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 if (fracpart == 0.0)
2352 return sum;
2353 /* So far we've lost no information. Dealing with the
2354 * fractional part requires float arithmetic, and may
2355 * lose a little info.
2356 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002357 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002358 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 dnum *= fracpart;
2361 fracpart = modf(dnum, &intpart);
2362 x = PyLong_FromDouble(intpart);
2363 if (x == NULL) {
2364 Py_DECREF(sum);
2365 return NULL;
2366 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 y = PyNumber_Add(sum, x);
2369 Py_DECREF(sum);
2370 Py_DECREF(x);
2371 *leftover += fracpart;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002372 assert(y == NULL || PyLong_CheckExact(y));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 return y;
2374 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 PyErr_Format(PyExc_TypeError,
2377 "unsupported type for timedelta %s component: %s",
2378 tag, Py_TYPE(num)->tp_name);
2379 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002380}
2381
2382static PyObject *
2383delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 /* Argument objects. */
2388 PyObject *day = NULL;
2389 PyObject *second = NULL;
2390 PyObject *us = NULL;
2391 PyObject *ms = NULL;
2392 PyObject *minute = NULL;
2393 PyObject *hour = NULL;
2394 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 PyObject *x = NULL; /* running sum of microseconds */
2397 PyObject *y = NULL; /* temp sum of microseconds */
2398 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 static char *keywords[] = {
2401 "days", "seconds", "microseconds", "milliseconds",
2402 "minutes", "hours", "weeks", NULL
2403 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2406 keywords,
2407 &day, &second, &us,
2408 &ms, &minute, &hour, &week) == 0)
2409 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 x = PyLong_FromLong(0);
2412 if (x == NULL)
2413 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415#define CLEANUP \
2416 Py_DECREF(x); \
2417 x = y; \
2418 if (x == NULL) \
2419 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002422 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 CLEANUP;
2424 }
2425 if (ms) {
2426 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2427 CLEANUP;
2428 }
2429 if (second) {
2430 y = accum("seconds", x, second, us_per_second, &leftover_us);
2431 CLEANUP;
2432 }
2433 if (minute) {
2434 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2435 CLEANUP;
2436 }
2437 if (hour) {
2438 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2439 CLEANUP;
2440 }
2441 if (day) {
2442 y = accum("days", x, day, us_per_day, &leftover_us);
2443 CLEANUP;
2444 }
2445 if (week) {
2446 y = accum("weeks", x, week, us_per_week, &leftover_us);
2447 CLEANUP;
2448 }
2449 if (leftover_us) {
2450 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002451 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002452 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002453 PyObject *temp;
2454
Victor Stinner69cc4872015-09-08 23:58:54 +02002455 whole_us = round(leftover_us);
2456 if (fabs(whole_us - leftover_us) == 0.5) {
2457 /* We're exactly halfway between two integers. In order
2458 * to do round-half-to-even, we must determine whether x
2459 * is odd. Note that x is odd when it's last bit is 1. The
2460 * code below uses bitwise and operation to check the last
2461 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002462 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002463 if (temp == NULL) {
2464 Py_DECREF(x);
2465 goto Done;
2466 }
2467 x_is_odd = PyObject_IsTrue(temp);
2468 Py_DECREF(temp);
2469 if (x_is_odd == -1) {
2470 Py_DECREF(x);
2471 goto Done;
2472 }
2473 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2474 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002475
Victor Stinner36a5a062013-08-28 01:53:39 +02002476 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 if (temp == NULL) {
2479 Py_DECREF(x);
2480 goto Done;
2481 }
2482 y = PyNumber_Add(x, temp);
2483 Py_DECREF(temp);
2484 CLEANUP;
2485 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 self = microseconds_to_delta_ex(x, type);
2488 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002489Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002491
2492#undef CLEANUP
2493}
2494
2495static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002496delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 return (GET_TD_DAYS(self) != 0
2499 || GET_TD_SECONDS(self) != 0
2500 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002501}
2502
2503static PyObject *
2504delta_repr(PyDateTime_Delta *self)
2505{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002506 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002507
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002508 if (args == NULL) {
2509 return NULL;
2510 }
2511
2512 const char *sep = "";
2513
2514 if (GET_TD_DAYS(self) != 0) {
2515 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2516 if (args == NULL) {
2517 return NULL;
2518 }
2519 sep = ", ";
2520 }
2521
2522 if (GET_TD_SECONDS(self) != 0) {
2523 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2524 GET_TD_SECONDS(self)));
2525 if (args == NULL) {
2526 return NULL;
2527 }
2528 sep = ", ";
2529 }
2530
2531 if (GET_TD_MICROSECONDS(self) != 0) {
2532 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2533 GET_TD_MICROSECONDS(self)));
2534 if (args == NULL) {
2535 return NULL;
2536 }
2537 }
2538
2539 if (PyUnicode_GET_LENGTH(args) == 0) {
2540 Py_SETREF(args, PyUnicode_FromString("0"));
2541 if (args == NULL) {
2542 return NULL;
2543 }
2544 }
2545
2546 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2547 args);
2548 Py_DECREF(args);
2549 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002550}
2551
2552static PyObject *
2553delta_str(PyDateTime_Delta *self)
2554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002555 int us = GET_TD_MICROSECONDS(self);
2556 int seconds = GET_TD_SECONDS(self);
2557 int minutes = divmod(seconds, 60, &seconds);
2558 int hours = divmod(minutes, 60, &minutes);
2559 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 if (days) {
2562 if (us)
2563 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2564 days, (days == 1 || days == -1) ? "" : "s",
2565 hours, minutes, seconds, us);
2566 else
2567 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2568 days, (days == 1 || days == -1) ? "" : "s",
2569 hours, minutes, seconds);
2570 } else {
2571 if (us)
2572 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2573 hours, minutes, seconds, us);
2574 else
2575 return PyUnicode_FromFormat("%d:%02d:%02d",
2576 hours, minutes, seconds);
2577 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002578
Tim Peters2a799bf2002-12-16 20:18:38 +00002579}
2580
Tim Peters371935f2003-02-01 01:52:50 +00002581/* Pickle support, a simple use of __reduce__. */
2582
Tim Petersb57f8f02003-02-01 02:54:15 +00002583/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002584static PyObject *
2585delta_getstate(PyDateTime_Delta *self)
2586{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 return Py_BuildValue("iii", GET_TD_DAYS(self),
2588 GET_TD_SECONDS(self),
2589 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002590}
2591
Tim Peters2a799bf2002-12-16 20:18:38 +00002592static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302593delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitroube6859d2009-11-25 23:02:32 +00002594{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002595 PyObject *total_seconds;
2596 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2599 if (total_microseconds == NULL)
2600 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002601
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002602 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002604 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002605 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002606}
2607
2608static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302609delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00002610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002612}
2613
2614#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2615
2616static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002618 {"days", T_INT, OFFSET(days), READONLY,
2619 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 {"seconds", T_INT, OFFSET(seconds), READONLY,
2622 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2625 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2626 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002627};
2628
2629static PyMethodDef delta_methods[] = {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302630 {"total_seconds", delta_total_seconds, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2634 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002637};
2638
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002639static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002640PyDoc_STR("Difference between two datetime values.");
2641
2642static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643 delta_add, /* nb_add */
2644 delta_subtract, /* nb_subtract */
2645 delta_multiply, /* nb_multiply */
2646 delta_remainder, /* nb_remainder */
2647 delta_divmod, /* nb_divmod */
2648 0, /* nb_power */
2649 (unaryfunc)delta_negative, /* nb_negative */
2650 (unaryfunc)delta_positive, /* nb_positive */
2651 (unaryfunc)delta_abs, /* nb_absolute */
2652 (inquiry)delta_bool, /* nb_bool */
2653 0, /*nb_invert*/
2654 0, /*nb_lshift*/
2655 0, /*nb_rshift*/
2656 0, /*nb_and*/
2657 0, /*nb_xor*/
2658 0, /*nb_or*/
2659 0, /*nb_int*/
2660 0, /*nb_reserved*/
2661 0, /*nb_float*/
2662 0, /*nb_inplace_add*/
2663 0, /*nb_inplace_subtract*/
2664 0, /*nb_inplace_multiply*/
2665 0, /*nb_inplace_remainder*/
2666 0, /*nb_inplace_power*/
2667 0, /*nb_inplace_lshift*/
2668 0, /*nb_inplace_rshift*/
2669 0, /*nb_inplace_and*/
2670 0, /*nb_inplace_xor*/
2671 0, /*nb_inplace_or*/
2672 delta_divide, /* nb_floor_divide */
2673 delta_truedivide, /* nb_true_divide */
2674 0, /* nb_inplace_floor_divide */
2675 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002676};
2677
2678static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002679 PyVarObject_HEAD_INIT(NULL, 0)
2680 "datetime.timedelta", /* tp_name */
2681 sizeof(PyDateTime_Delta), /* tp_basicsize */
2682 0, /* tp_itemsize */
2683 0, /* tp_dealloc */
2684 0, /* tp_print */
2685 0, /* tp_getattr */
2686 0, /* tp_setattr */
2687 0, /* tp_reserved */
2688 (reprfunc)delta_repr, /* tp_repr */
2689 &delta_as_number, /* tp_as_number */
2690 0, /* tp_as_sequence */
2691 0, /* tp_as_mapping */
2692 (hashfunc)delta_hash, /* tp_hash */
2693 0, /* tp_call */
2694 (reprfunc)delta_str, /* tp_str */
2695 PyObject_GenericGetAttr, /* tp_getattro */
2696 0, /* tp_setattro */
2697 0, /* tp_as_buffer */
2698 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2699 delta_doc, /* tp_doc */
2700 0, /* tp_traverse */
2701 0, /* tp_clear */
2702 delta_richcompare, /* tp_richcompare */
2703 0, /* tp_weaklistoffset */
2704 0, /* tp_iter */
2705 0, /* tp_iternext */
2706 delta_methods, /* tp_methods */
2707 delta_members, /* tp_members */
2708 0, /* tp_getset */
2709 0, /* tp_base */
2710 0, /* tp_dict */
2711 0, /* tp_descr_get */
2712 0, /* tp_descr_set */
2713 0, /* tp_dictoffset */
2714 0, /* tp_init */
2715 0, /* tp_alloc */
2716 delta_new, /* tp_new */
2717 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002718};
2719
2720/*
2721 * PyDateTime_Date implementation.
2722 */
2723
2724/* Accessor properties. */
2725
2726static PyObject *
2727date_year(PyDateTime_Date *self, void *unused)
2728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002729 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002730}
2731
2732static PyObject *
2733date_month(PyDateTime_Date *self, void *unused)
2734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002735 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002736}
2737
2738static PyObject *
2739date_day(PyDateTime_Date *self, void *unused)
2740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002741 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002742}
2743
2744static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002745 {"year", (getter)date_year},
2746 {"month", (getter)date_month},
2747 {"day", (getter)date_day},
2748 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002749};
2750
2751/* Constructors. */
2752
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002753static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002754
Tim Peters2a799bf2002-12-16 20:18:38 +00002755static PyObject *
2756date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002758 PyObject *self = NULL;
2759 PyObject *state;
2760 int year;
2761 int month;
2762 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002764 /* Check for invocation from pickle with __getstate__ state */
2765 if (PyTuple_GET_SIZE(args) == 1 &&
2766 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2767 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2768 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2769 {
2770 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2773 if (me != NULL) {
2774 char *pdata = PyBytes_AS_STRING(state);
2775 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2776 me->hashcode = -1;
2777 }
2778 return (PyObject *)me;
2779 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002781 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2782 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002783 self = new_date_ex(year, month, day, type);
2784 }
2785 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002786}
2787
2788/* Return new date from localtime(t). */
2789static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002790date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002791{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002792 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002793 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002794
Victor Stinnere4a994d2015-03-30 01:10:14 +02002795 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002797
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002798 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002799 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002800
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002801 return new_date_subclass_ex(tm.tm_year + 1900,
2802 tm.tm_mon + 1,
2803 tm.tm_mday,
2804 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002805}
2806
2807/* Return new date from current time.
2808 * We say this is equivalent to fromtimestamp(time.time()), and the
2809 * only way to be sure of that is to *call* time.time(). That's not
2810 * generally the same as calling C's time.
2811 */
2812static PyObject *
2813date_today(PyObject *cls, PyObject *dummy)
2814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 PyObject *time;
2816 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002817 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002819 time = time_time();
2820 if (time == NULL)
2821 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002822
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002823 /* Note well: today() is a class method, so this may not call
2824 * date.fromtimestamp. For example, it may call
2825 * datetime.fromtimestamp. That's why we need all the accuracy
2826 * time.time() delivers; if someone were gonzo about optimization,
2827 * date.today() could get away with plain C time().
2828 */
Victor Stinner20401de2016-12-09 15:24:31 +01002829 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2830 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 Py_DECREF(time);
2832 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002833}
2834
2835/* Return new date from given timestamp (Python timestamp -- a double). */
2836static PyObject *
2837date_fromtimestamp(PyObject *cls, PyObject *args)
2838{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002839 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002840 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002841
Victor Stinner5d272cc2012-03-13 13:35:55 +01002842 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2843 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002845}
2846
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002847
Tim Peters2a799bf2002-12-16 20:18:38 +00002848/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2849 * the ordinal is out of range.
2850 */
2851static PyObject *
2852date_fromordinal(PyObject *cls, PyObject *args)
2853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 PyObject *result = NULL;
2855 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002857 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2858 int year;
2859 int month;
2860 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 if (ordinal < 1)
2863 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2864 ">= 1");
2865 else {
2866 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002867 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 }
2869 }
2870 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002871}
2872
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002873/* Return the new date from a string as generated by date.isoformat() */
2874static PyObject *
2875date_fromisoformat(PyObject *cls, PyObject *dtstr) {
2876 assert(dtstr != NULL);
2877
2878 if (!PyUnicode_Check(dtstr)) {
2879 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
2880 return NULL;
2881 }
2882
2883 Py_ssize_t len;
2884
2885 const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
2886
2887 int year = 0, month = 0, day = 0;
2888
2889 int rv;
2890 if (len == 10) {
2891 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
2892 } else {
2893 rv = -1;
2894 }
2895
2896 if (rv < 0) {
2897 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %s",
2898 dt_ptr);
2899 return NULL;
2900 }
2901
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002902 return new_date_subclass_ex(year, month, day, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002903}
2904
2905
Tim Peters2a799bf2002-12-16 20:18:38 +00002906/*
2907 * Date arithmetic.
2908 */
2909
2910/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2911 * instead.
2912 */
2913static PyObject *
2914add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002916 PyObject *result = NULL;
2917 int year = GET_YEAR(date);
2918 int month = GET_MONTH(date);
2919 int deltadays = GET_TD_DAYS(delta);
2920 /* C-level overflow is impossible because |deltadays| < 1e9. */
2921 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002923 if (normalize_date(&year, &month, &day) >= 0)
2924 result = new_date(year, month, day);
2925 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002926}
2927
2928static PyObject *
2929date_add(PyObject *left, PyObject *right)
2930{
Brian Curtindfc80e32011-08-10 20:28:54 -05002931 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2932 Py_RETURN_NOTIMPLEMENTED;
2933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002934 if (PyDate_Check(left)) {
2935 /* date + ??? */
2936 if (PyDelta_Check(right))
2937 /* date + delta */
2938 return add_date_timedelta((PyDateTime_Date *) left,
2939 (PyDateTime_Delta *) right,
2940 0);
2941 }
2942 else {
2943 /* ??? + date
2944 * 'right' must be one of us, or we wouldn't have been called
2945 */
2946 if (PyDelta_Check(left))
2947 /* delta + date */
2948 return add_date_timedelta((PyDateTime_Date *) right,
2949 (PyDateTime_Delta *) left,
2950 0);
2951 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002952 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002953}
2954
2955static PyObject *
2956date_subtract(PyObject *left, PyObject *right)
2957{
Brian Curtindfc80e32011-08-10 20:28:54 -05002958 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2959 Py_RETURN_NOTIMPLEMENTED;
2960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002961 if (PyDate_Check(left)) {
2962 if (PyDate_Check(right)) {
2963 /* date - date */
2964 int left_ord = ymd_to_ord(GET_YEAR(left),
2965 GET_MONTH(left),
2966 GET_DAY(left));
2967 int right_ord = ymd_to_ord(GET_YEAR(right),
2968 GET_MONTH(right),
2969 GET_DAY(right));
2970 return new_delta(left_ord - right_ord, 0, 0, 0);
2971 }
2972 if (PyDelta_Check(right)) {
2973 /* date - delta */
2974 return add_date_timedelta((PyDateTime_Date *) left,
2975 (PyDateTime_Delta *) right,
2976 1);
2977 }
2978 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002979 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002980}
2981
2982
2983/* Various ways to turn a date into a string. */
2984
2985static PyObject *
2986date_repr(PyDateTime_Date *self)
2987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002988 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2989 Py_TYPE(self)->tp_name,
2990 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002991}
2992
2993static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302994date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00002995{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002996 return PyUnicode_FromFormat("%04d-%02d-%02d",
2997 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002998}
2999
Tim Peterse2df5ff2003-05-02 18:39:55 +00003000/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003001static PyObject *
3002date_str(PyDateTime_Date *self)
3003{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003004 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003005}
3006
3007
3008static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303009date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003010{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003011 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003012}
3013
3014static PyObject *
3015date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3016{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003017 /* This method can be inherited, and needs to call the
3018 * timetuple() method appropriate to self's class.
3019 */
3020 PyObject *result;
3021 PyObject *tuple;
3022 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003023 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003024 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003026 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3027 &format))
3028 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003029
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003030 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003031 if (tuple == NULL)
3032 return NULL;
3033 result = wrap_strftime((PyObject *)self, format, tuple,
3034 (PyObject *)self);
3035 Py_DECREF(tuple);
3036 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003037}
3038
Eric Smith1ba31142007-09-11 18:06:02 +00003039static PyObject *
3040date_format(PyDateTime_Date *self, PyObject *args)
3041{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003042 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003044 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3045 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003047 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003048 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003049 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003050
Victor Stinner20401de2016-12-09 15:24:31 +01003051 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3052 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003053}
3054
Tim Peters2a799bf2002-12-16 20:18:38 +00003055/* ISO methods. */
3056
3057static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303058date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003059{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003060 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003063}
3064
3065static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303066date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003068 int year = GET_YEAR(self);
3069 int week1_monday = iso_week1_monday(year);
3070 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3071 int week;
3072 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003074 week = divmod(today - week1_monday, 7, &day);
3075 if (week < 0) {
3076 --year;
3077 week1_monday = iso_week1_monday(year);
3078 week = divmod(today - week1_monday, 7, &day);
3079 }
3080 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3081 ++year;
3082 week = 0;
3083 }
3084 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003085}
3086
3087/* Miscellaneous methods. */
3088
Tim Peters2a799bf2002-12-16 20:18:38 +00003089static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003090date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003091{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003092 if (PyDate_Check(other)) {
3093 int diff = memcmp(((PyDateTime_Date *)self)->data,
3094 ((PyDateTime_Date *)other)->data,
3095 _PyDateTime_DATE_DATASIZE);
3096 return diff_to_bool(diff, op);
3097 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003098 else
3099 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003100}
3101
3102static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303103date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003104{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003105 return build_struct_time(GET_YEAR(self),
3106 GET_MONTH(self),
3107 GET_DAY(self),
3108 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003109}
3110
Tim Peters12bf3392002-12-24 05:41:27 +00003111static PyObject *
3112date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3113{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003114 PyObject *clone;
3115 PyObject *tuple;
3116 int year = GET_YEAR(self);
3117 int month = GET_MONTH(self);
3118 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003120 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3121 &year, &month, &day))
3122 return NULL;
3123 tuple = Py_BuildValue("iii", year, month, day);
3124 if (tuple == NULL)
3125 return NULL;
3126 clone = date_new(Py_TYPE(self), tuple, NULL);
3127 Py_DECREF(tuple);
3128 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003129}
3130
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003131static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003132generic_hash(unsigned char *data, int len)
3133{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003134 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003135}
3136
3137
3138static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003139
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003140static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003141date_hash(PyDateTime_Date *self)
3142{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003143 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003144 self->hashcode = generic_hash(
3145 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003146 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003148 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003149}
3150
3151static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303152date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003154 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3155 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003156}
3157
3158static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303159date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00003160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003161 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003163 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003164}
3165
Tim Peters371935f2003-02-01 01:52:50 +00003166/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003167
Tim Petersb57f8f02003-02-01 02:54:15 +00003168/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003169static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003170date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 PyObject* field;
3173 field = PyBytes_FromStringAndSize((char*)self->data,
3174 _PyDateTime_DATE_DATASIZE);
3175 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003176}
3177
3178static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003179date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003181 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003182}
3183
3184static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003186 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00003187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003188 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
3189 METH_CLASS,
3190 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
3191 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003193 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3194 METH_CLASS,
3195 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3196 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003197
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003198 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3199 METH_CLASS,
3200 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003202 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3203 PyDoc_STR("Current date or datetime: same as "
3204 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003206 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3209 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003211 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
3212 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003214 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3215 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3218 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003220 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3221 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3222 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003224 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3225 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003227 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3228 PyDoc_STR("Return the day of the week represented by the date.\n"
3229 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003231 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3232 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3233 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003235 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3236 PyDoc_STR("Return the day of the week represented by the date.\n"
3237 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003239 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3240 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003242 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3243 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003245 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003246};
3247
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003248static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003249PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003250
3251static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003252 date_add, /* nb_add */
3253 date_subtract, /* nb_subtract */
3254 0, /* nb_multiply */
3255 0, /* nb_remainder */
3256 0, /* nb_divmod */
3257 0, /* nb_power */
3258 0, /* nb_negative */
3259 0, /* nb_positive */
3260 0, /* nb_absolute */
3261 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003262};
3263
3264static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003265 PyVarObject_HEAD_INIT(NULL, 0)
3266 "datetime.date", /* tp_name */
3267 sizeof(PyDateTime_Date), /* tp_basicsize */
3268 0, /* tp_itemsize */
3269 0, /* tp_dealloc */
3270 0, /* tp_print */
3271 0, /* tp_getattr */
3272 0, /* tp_setattr */
3273 0, /* tp_reserved */
3274 (reprfunc)date_repr, /* tp_repr */
3275 &date_as_number, /* tp_as_number */
3276 0, /* tp_as_sequence */
3277 0, /* tp_as_mapping */
3278 (hashfunc)date_hash, /* tp_hash */
3279 0, /* tp_call */
3280 (reprfunc)date_str, /* tp_str */
3281 PyObject_GenericGetAttr, /* tp_getattro */
3282 0, /* tp_setattro */
3283 0, /* tp_as_buffer */
3284 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3285 date_doc, /* tp_doc */
3286 0, /* tp_traverse */
3287 0, /* tp_clear */
3288 date_richcompare, /* tp_richcompare */
3289 0, /* tp_weaklistoffset */
3290 0, /* tp_iter */
3291 0, /* tp_iternext */
3292 date_methods, /* tp_methods */
3293 0, /* tp_members */
3294 date_getset, /* tp_getset */
3295 0, /* tp_base */
3296 0, /* tp_dict */
3297 0, /* tp_descr_get */
3298 0, /* tp_descr_set */
3299 0, /* tp_dictoffset */
3300 0, /* tp_init */
3301 0, /* tp_alloc */
3302 date_new, /* tp_new */
3303 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003304};
3305
3306/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003307 * PyDateTime_TZInfo implementation.
3308 */
3309
3310/* This is a pure abstract base class, so doesn't do anything beyond
3311 * raising NotImplemented exceptions. Real tzinfo classes need
3312 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003313 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003314 * be subclasses of this tzinfo class, which is easy and quick to check).
3315 *
3316 * Note: For reasons having to do with pickling of subclasses, we have
3317 * to allow tzinfo objects to be instantiated. This wasn't an issue
3318 * in the Python implementation (__init__() could raise NotImplementedError
3319 * there without ill effect), but doing so in the C implementation hit a
3320 * brick wall.
3321 */
3322
3323static PyObject *
3324tzinfo_nogo(const char* methodname)
3325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003326 PyErr_Format(PyExc_NotImplementedError,
3327 "a tzinfo subclass must implement %s()",
3328 methodname);
3329 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003330}
3331
3332/* Methods. A subclass must implement these. */
3333
Tim Peters52dcce22003-01-23 16:36:11 +00003334static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003335tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003337 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003338}
3339
Tim Peters52dcce22003-01-23 16:36:11 +00003340static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003341tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003343 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003344}
3345
Tim Peters52dcce22003-01-23 16:36:11 +00003346static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003347tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003349 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003350}
3351
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003352
3353static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3354 PyDateTime_Delta *delta,
3355 int factor);
3356static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3357static PyObject *datetime_dst(PyObject *self, PyObject *);
3358
Tim Peters52dcce22003-01-23 16:36:11 +00003359static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003360tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003361{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003362 PyObject *result = NULL;
3363 PyObject *off = NULL, *dst = NULL;
3364 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003365
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003366 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003367 PyErr_SetString(PyExc_TypeError,
3368 "fromutc: argument must be a datetime");
3369 return NULL;
3370 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003371 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003372 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3373 "is not self");
3374 return NULL;
3375 }
Tim Peters52dcce22003-01-23 16:36:11 +00003376
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003377 off = datetime_utcoffset(dt, NULL);
3378 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003379 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003380 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003381 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3382 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003383 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003384 }
Tim Peters52dcce22003-01-23 16:36:11 +00003385
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003386 dst = datetime_dst(dt, NULL);
3387 if (dst == NULL)
3388 goto Fail;
3389 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003390 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3391 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003392 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003393 }
Tim Peters52dcce22003-01-23 16:36:11 +00003394
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003395 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3396 if (delta == NULL)
3397 goto Fail;
3398 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003399 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003400 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003401
3402 Py_DECREF(dst);
3403 dst = call_dst(GET_DT_TZINFO(dt), result);
3404 if (dst == NULL)
3405 goto Fail;
3406 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003407 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003408 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003409 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003410 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003411 if (result == NULL)
3412 goto Fail;
3413 }
3414 Py_DECREF(delta);
3415 Py_DECREF(dst);
3416 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003417 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003418
3419Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003420 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3421 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003422
Leo Ariasc3d95082018-02-03 18:36:10 -06003423 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003424Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003425 Py_XDECREF(off);
3426 Py_XDECREF(dst);
3427 Py_XDECREF(delta);
3428 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003429 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003430}
3431
Tim Peters2a799bf2002-12-16 20:18:38 +00003432/*
3433 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003434 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003435 */
3436
Guido van Rossum177e41a2003-01-30 22:06:23 +00003437static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303438tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003439{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003440 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003441 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003442 _Py_IDENTIFIER(__getinitargs__);
3443 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003444
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003445 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003446 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003447 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003448 Py_DECREF(getinitargs);
3449 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003450 return NULL;
3451 }
3452 }
3453 else {
3454 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003455
3456 args = PyTuple_New(0);
3457 if (args == NULL) {
3458 return NULL;
3459 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003460 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003461
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003462 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003463 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003464 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003465 Py_DECREF(getstate);
3466 if (state == NULL) {
3467 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003468 return NULL;
3469 }
3470 }
3471 else {
3472 PyObject **dictptr;
3473 PyErr_Clear();
3474 state = Py_None;
3475 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003476 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003477 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003478 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003479 Py_INCREF(state);
3480 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003482 if (state == Py_None) {
3483 Py_DECREF(state);
3484 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3485 }
3486 else
3487 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003488}
Tim Peters2a799bf2002-12-16 20:18:38 +00003489
3490static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003492 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3493 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003495 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003496 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3497 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003499 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003500 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003502 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003503 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003504
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303505 {"__reduce__", tzinfo_reduce, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003506 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003509};
3510
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003511static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003512PyDoc_STR("Abstract base class for time zone info objects.");
3513
Neal Norwitz227b5332006-03-22 09:28:35 +00003514static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003515 PyVarObject_HEAD_INIT(NULL, 0)
3516 "datetime.tzinfo", /* tp_name */
3517 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3518 0, /* tp_itemsize */
3519 0, /* tp_dealloc */
3520 0, /* tp_print */
3521 0, /* tp_getattr */
3522 0, /* tp_setattr */
3523 0, /* tp_reserved */
3524 0, /* tp_repr */
3525 0, /* tp_as_number */
3526 0, /* tp_as_sequence */
3527 0, /* tp_as_mapping */
3528 0, /* tp_hash */
3529 0, /* tp_call */
3530 0, /* tp_str */
3531 PyObject_GenericGetAttr, /* tp_getattro */
3532 0, /* tp_setattro */
3533 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003534 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003535 tzinfo_doc, /* tp_doc */
3536 0, /* tp_traverse */
3537 0, /* tp_clear */
3538 0, /* tp_richcompare */
3539 0, /* tp_weaklistoffset */
3540 0, /* tp_iter */
3541 0, /* tp_iternext */
3542 tzinfo_methods, /* tp_methods */
3543 0, /* tp_members */
3544 0, /* tp_getset */
3545 0, /* tp_base */
3546 0, /* tp_dict */
3547 0, /* tp_descr_get */
3548 0, /* tp_descr_set */
3549 0, /* tp_dictoffset */
3550 0, /* tp_init */
3551 0, /* tp_alloc */
3552 PyType_GenericNew, /* tp_new */
3553 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003554};
3555
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003556static char *timezone_kws[] = {"offset", "name", NULL};
3557
3558static PyObject *
3559timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3560{
3561 PyObject *offset;
3562 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003563 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3564 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003565 return new_timezone(offset, name);
3566
3567 return NULL;
3568}
3569
3570static void
3571timezone_dealloc(PyDateTime_TimeZone *self)
3572{
3573 Py_CLEAR(self->offset);
3574 Py_CLEAR(self->name);
3575 Py_TYPE(self)->tp_free((PyObject *)self);
3576}
3577
3578static PyObject *
3579timezone_richcompare(PyDateTime_TimeZone *self,
3580 PyDateTime_TimeZone *other, int op)
3581{
Brian Curtindfc80e32011-08-10 20:28:54 -05003582 if (op != Py_EQ && op != Py_NE)
3583 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003584 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003585 if (op == Py_EQ)
3586 Py_RETURN_FALSE;
3587 else
3588 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003589 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003590 return delta_richcompare(self->offset, other->offset, op);
3591}
3592
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003593static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003594timezone_hash(PyDateTime_TimeZone *self)
3595{
3596 return delta_hash((PyDateTime_Delta *)self->offset);
3597}
3598
3599/* Check argument type passed to tzname, utcoffset, or dst methods.
3600 Returns 0 for good argument. Returns -1 and sets exception info
3601 otherwise.
3602 */
3603static int
3604_timezone_check_argument(PyObject *dt, const char *meth)
3605{
3606 if (dt == Py_None || PyDateTime_Check(dt))
3607 return 0;
3608 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3609 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3610 return -1;
3611}
3612
3613static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003614timezone_repr(PyDateTime_TimeZone *self)
3615{
3616 /* Note that although timezone is not subclassable, it is convenient
3617 to use Py_TYPE(self)->tp_name here. */
3618 const char *type_name = Py_TYPE(self)->tp_name;
3619
3620 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3621 return PyUnicode_FromFormat("%s.utc", type_name);
3622
3623 if (self->name == NULL)
3624 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3625
3626 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3627 self->name);
3628}
3629
3630
3631static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003632timezone_str(PyDateTime_TimeZone *self)
3633{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003634 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003635 PyObject *offset;
3636 char sign;
3637
3638 if (self->name != NULL) {
3639 Py_INCREF(self->name);
3640 return self->name;
3641 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003642 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003643 (GET_TD_DAYS(self->offset) == 0 &&
3644 GET_TD_SECONDS(self->offset) == 0 &&
3645 GET_TD_MICROSECONDS(self->offset) == 0))
3646 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003647 /* Offset is normalized, so it is negative if days < 0 */
3648 if (GET_TD_DAYS(self->offset) < 0) {
3649 sign = '-';
3650 offset = delta_negative((PyDateTime_Delta *)self->offset);
3651 if (offset == NULL)
3652 return NULL;
3653 }
3654 else {
3655 sign = '+';
3656 offset = self->offset;
3657 Py_INCREF(offset);
3658 }
3659 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003660 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003661 seconds = GET_TD_SECONDS(offset);
3662 Py_DECREF(offset);
3663 minutes = divmod(seconds, 60, &seconds);
3664 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003665 if (microseconds != 0) {
3666 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3667 sign, hours, minutes,
3668 seconds, microseconds);
3669 }
3670 if (seconds != 0) {
3671 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3672 sign, hours, minutes, seconds);
3673 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003674 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003675}
3676
3677static PyObject *
3678timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3679{
3680 if (_timezone_check_argument(dt, "tzname") == -1)
3681 return NULL;
3682
3683 return timezone_str(self);
3684}
3685
3686static PyObject *
3687timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3688{
3689 if (_timezone_check_argument(dt, "utcoffset") == -1)
3690 return NULL;
3691
3692 Py_INCREF(self->offset);
3693 return self->offset;
3694}
3695
3696static PyObject *
3697timezone_dst(PyObject *self, PyObject *dt)
3698{
3699 if (_timezone_check_argument(dt, "dst") == -1)
3700 return NULL;
3701
3702 Py_RETURN_NONE;
3703}
3704
3705static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003706timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3707{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003708 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003709 PyErr_SetString(PyExc_TypeError,
3710 "fromutc: argument must be a datetime");
3711 return NULL;
3712 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003713 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003714 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3715 "is not self");
3716 return NULL;
3717 }
3718
3719 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3720}
3721
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003722static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303723timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003724{
3725 if (self->name == NULL)
3726 return Py_BuildValue("(O)", self->offset);
3727 return Py_BuildValue("(OO)", self->offset, self->name);
3728}
3729
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003730static PyMethodDef timezone_methods[] = {
3731 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3732 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003733 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003734
3735 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003736 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003737
3738 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003739 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003740
3741 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3742 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3743
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003744 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3745 PyDoc_STR("pickle support")},
3746
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003747 {NULL, NULL}
3748};
3749
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003750static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003751PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3752
3753static PyTypeObject PyDateTime_TimeZoneType = {
3754 PyVarObject_HEAD_INIT(NULL, 0)
3755 "datetime.timezone", /* tp_name */
3756 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3757 0, /* tp_itemsize */
3758 (destructor)timezone_dealloc, /* tp_dealloc */
3759 0, /* tp_print */
3760 0, /* tp_getattr */
3761 0, /* tp_setattr */
3762 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003763 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003764 0, /* tp_as_number */
3765 0, /* tp_as_sequence */
3766 0, /* tp_as_mapping */
3767 (hashfunc)timezone_hash, /* tp_hash */
3768 0, /* tp_call */
3769 (reprfunc)timezone_str, /* tp_str */
3770 0, /* tp_getattro */
3771 0, /* tp_setattro */
3772 0, /* tp_as_buffer */
3773 Py_TPFLAGS_DEFAULT, /* tp_flags */
3774 timezone_doc, /* tp_doc */
3775 0, /* tp_traverse */
3776 0, /* tp_clear */
3777 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3778 0, /* tp_weaklistoffset */
3779 0, /* tp_iter */
3780 0, /* tp_iternext */
3781 timezone_methods, /* tp_methods */
3782 0, /* tp_members */
3783 0, /* tp_getset */
3784 &PyDateTime_TZInfoType, /* tp_base */
3785 0, /* tp_dict */
3786 0, /* tp_descr_get */
3787 0, /* tp_descr_set */
3788 0, /* tp_dictoffset */
3789 0, /* tp_init */
3790 0, /* tp_alloc */
3791 timezone_new, /* tp_new */
3792};
3793
Tim Peters2a799bf2002-12-16 20:18:38 +00003794/*
Tim Peters37f39822003-01-10 03:49:02 +00003795 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003796 */
3797
Tim Peters37f39822003-01-10 03:49:02 +00003798/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003799 */
3800
3801static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003802time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003803{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003804 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003805}
3806
Tim Peters37f39822003-01-10 03:49:02 +00003807static PyObject *
3808time_minute(PyDateTime_Time *self, void *unused)
3809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003810 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003811}
3812
3813/* The name time_second conflicted with some platform header file. */
3814static PyObject *
3815py_time_second(PyDateTime_Time *self, void *unused)
3816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003817 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003818}
3819
3820static PyObject *
3821time_microsecond(PyDateTime_Time *self, void *unused)
3822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003823 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003824}
3825
3826static PyObject *
3827time_tzinfo(PyDateTime_Time *self, void *unused)
3828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003829 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3830 Py_INCREF(result);
3831 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003832}
3833
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003834static PyObject *
3835time_fold(PyDateTime_Time *self, void *unused)
3836{
3837 return PyLong_FromLong(TIME_GET_FOLD(self));
3838}
3839
Tim Peters37f39822003-01-10 03:49:02 +00003840static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003841 {"hour", (getter)time_hour},
3842 {"minute", (getter)time_minute},
3843 {"second", (getter)py_time_second},
3844 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003845 {"tzinfo", (getter)time_tzinfo},
3846 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003847 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003848};
3849
3850/*
3851 * Constructors.
3852 */
3853
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003854static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003855 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003856
Tim Peters2a799bf2002-12-16 20:18:38 +00003857static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003858time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003859{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003860 PyObject *self = NULL;
3861 PyObject *state;
3862 int hour = 0;
3863 int minute = 0;
3864 int second = 0;
3865 int usecond = 0;
3866 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003867 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003869 /* Check for invocation from pickle with __getstate__ state */
3870 if (PyTuple_GET_SIZE(args) >= 1 &&
3871 PyTuple_GET_SIZE(args) <= 2 &&
3872 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3873 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003874 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003875 {
3876 PyDateTime_Time *me;
3877 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003879 if (PyTuple_GET_SIZE(args) == 2) {
3880 tzinfo = PyTuple_GET_ITEM(args, 1);
3881 if (check_tzinfo_subclass(tzinfo) < 0) {
3882 PyErr_SetString(PyExc_TypeError, "bad "
3883 "tzinfo state arg");
3884 return NULL;
3885 }
3886 }
3887 aware = (char)(tzinfo != Py_None);
3888 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3889 if (me != NULL) {
3890 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003892 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3893 me->hashcode = -1;
3894 me->hastzinfo = aware;
3895 if (aware) {
3896 Py_INCREF(tzinfo);
3897 me->tzinfo = tzinfo;
3898 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003899 if (pdata[0] & (1 << 7)) {
3900 me->data[0] -= 128;
3901 me->fold = 1;
3902 }
3903 else {
3904 me->fold = 0;
3905 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003906 }
3907 return (PyObject *)me;
3908 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003909
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003910 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003911 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003912 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003913 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3914 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003915 }
3916 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003917}
3918
3919/*
3920 * Destructor.
3921 */
3922
3923static void
Tim Peters37f39822003-01-10 03:49:02 +00003924time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003926 if (HASTZINFO(self)) {
3927 Py_XDECREF(self->tzinfo);
3928 }
3929 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003930}
3931
3932/*
Tim Peters855fe882002-12-22 03:43:39 +00003933 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003934 */
3935
Tim Peters2a799bf2002-12-16 20:18:38 +00003936/* These are all METH_NOARGS, so don't need to check the arglist. */
3937static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003938time_utcoffset(PyObject *self, PyObject *unused) {
3939 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003940}
3941
3942static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003943time_dst(PyObject *self, PyObject *unused) {
3944 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003945}
3946
3947static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003948time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003949 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003950}
3951
3952/*
Tim Peters37f39822003-01-10 03:49:02 +00003953 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003954 */
3955
3956static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003957time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003959 const char *type_name = Py_TYPE(self)->tp_name;
3960 int h = TIME_GET_HOUR(self);
3961 int m = TIME_GET_MINUTE(self);
3962 int s = TIME_GET_SECOND(self);
3963 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003964 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003965 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003967 if (us)
3968 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3969 type_name, h, m, s, us);
3970 else if (s)
3971 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3972 type_name, h, m, s);
3973 else
3974 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3975 if (result != NULL && HASTZINFO(self))
3976 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003977 if (result != NULL && fold)
3978 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003979 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003980}
3981
Tim Peters37f39822003-01-10 03:49:02 +00003982static PyObject *
3983time_str(PyDateTime_Time *self)
3984{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003985 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003986}
Tim Peters2a799bf2002-12-16 20:18:38 +00003987
3988static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003989time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003990{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003991 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003992 char *timespec = NULL;
3993 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003994 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003995 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003996 static char *specs[][2] = {
3997 {"hours", "%02d"},
3998 {"minutes", "%02d:%02d"},
3999 {"seconds", "%02d:%02d:%02d"},
4000 {"milliseconds", "%02d:%02d:%02d.%03d"},
4001 {"microseconds", "%02d:%02d:%02d.%06d"},
4002 };
4003 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004004
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004005 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4006 return NULL;
4007
4008 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4009 if (us == 0) {
4010 /* seconds */
4011 given_spec = 2;
4012 }
4013 else {
4014 /* microseconds */
4015 given_spec = 4;
4016 }
4017 }
4018 else {
4019 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4020 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4021 if (given_spec == 3) {
4022 /* milliseconds */
4023 us = us / 1000;
4024 }
4025 break;
4026 }
4027 }
4028 }
4029
4030 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4031 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4032 return NULL;
4033 }
4034 else {
4035 result = PyUnicode_FromFormat(specs[given_spec][1],
4036 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4037 TIME_GET_SECOND(self), us);
4038 }
Tim Peters37f39822003-01-10 03:49:02 +00004039
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004040 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004041 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004043 /* We need to append the UTC offset. */
4044 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4045 Py_None) < 0) {
4046 Py_DECREF(result);
4047 return NULL;
4048 }
4049 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4050 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004051}
4052
Tim Peters37f39822003-01-10 03:49:02 +00004053static PyObject *
4054time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4055{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004056 PyObject *result;
4057 PyObject *tuple;
4058 PyObject *format;
4059 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004061 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4062 &format))
4063 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004065 /* Python's strftime does insane things with the year part of the
4066 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004067 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004068 */
4069 tuple = Py_BuildValue("iiiiiiiii",
4070 1900, 1, 1, /* year, month, day */
4071 TIME_GET_HOUR(self),
4072 TIME_GET_MINUTE(self),
4073 TIME_GET_SECOND(self),
4074 0, 1, -1); /* weekday, daynum, dst */
4075 if (tuple == NULL)
4076 return NULL;
4077 assert(PyTuple_Size(tuple) == 9);
4078 result = wrap_strftime((PyObject *)self, format, tuple,
4079 Py_None);
4080 Py_DECREF(tuple);
4081 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004082}
Tim Peters2a799bf2002-12-16 20:18:38 +00004083
4084/*
4085 * Miscellaneous methods.
4086 */
4087
Tim Peters37f39822003-01-10 03:49:02 +00004088static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004089time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004090{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004091 PyObject *result = NULL;
4092 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004093 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004094
Brian Curtindfc80e32011-08-10 20:28:54 -05004095 if (! PyTime_Check(other))
4096 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004097
4098 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 diff = memcmp(((PyDateTime_Time *)self)->data,
4100 ((PyDateTime_Time *)other)->data,
4101 _PyDateTime_TIME_DATASIZE);
4102 return diff_to_bool(diff, op);
4103 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004104 offset1 = time_utcoffset(self, NULL);
4105 if (offset1 == NULL)
4106 return NULL;
4107 offset2 = time_utcoffset(other, NULL);
4108 if (offset2 == NULL)
4109 goto done;
4110 /* If they're both naive, or both aware and have the same offsets,
4111 * we get off cheap. Note that if they're both naive, offset1 ==
4112 * offset2 == Py_None at this point.
4113 */
4114 if ((offset1 == offset2) ||
4115 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4116 delta_cmp(offset1, offset2) == 0)) {
4117 diff = memcmp(((PyDateTime_Time *)self)->data,
4118 ((PyDateTime_Time *)other)->data,
4119 _PyDateTime_TIME_DATASIZE);
4120 result = diff_to_bool(diff, op);
4121 }
4122 /* The hard case: both aware with different UTC offsets */
4123 else if (offset1 != Py_None && offset2 != Py_None) {
4124 int offsecs1, offsecs2;
4125 assert(offset1 != offset2); /* else last "if" handled it */
4126 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4127 TIME_GET_MINUTE(self) * 60 +
4128 TIME_GET_SECOND(self) -
4129 GET_TD_DAYS(offset1) * 86400 -
4130 GET_TD_SECONDS(offset1);
4131 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4132 TIME_GET_MINUTE(other) * 60 +
4133 TIME_GET_SECOND(other) -
4134 GET_TD_DAYS(offset2) * 86400 -
4135 GET_TD_SECONDS(offset2);
4136 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004137 if (diff == 0)
4138 diff = TIME_GET_MICROSECOND(self) -
4139 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004140 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004141 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004142 else if (op == Py_EQ) {
4143 result = Py_False;
4144 Py_INCREF(result);
4145 }
4146 else if (op == Py_NE) {
4147 result = Py_True;
4148 Py_INCREF(result);
4149 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004150 else {
4151 PyErr_SetString(PyExc_TypeError,
4152 "can't compare offset-naive and "
4153 "offset-aware times");
4154 }
4155 done:
4156 Py_DECREF(offset1);
4157 Py_XDECREF(offset2);
4158 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004159}
4160
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004161static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004162time_hash(PyDateTime_Time *self)
4163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004164 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004165 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004166 if (TIME_GET_FOLD(self)) {
4167 self0 = new_time_ex2(TIME_GET_HOUR(self),
4168 TIME_GET_MINUTE(self),
4169 TIME_GET_SECOND(self),
4170 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004171 HASTZINFO(self) ? self->tzinfo : Py_None,
4172 0, Py_TYPE(self));
4173 if (self0 == NULL)
4174 return -1;
4175 }
4176 else {
4177 self0 = (PyObject *)self;
4178 Py_INCREF(self0);
4179 }
4180 offset = time_utcoffset(self0, NULL);
4181 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004182
4183 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004184 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004186 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004187 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004188 self->hashcode = generic_hash(
4189 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004190 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004191 PyObject *temp1, *temp2;
4192 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004194 seconds = TIME_GET_HOUR(self) * 3600 +
4195 TIME_GET_MINUTE(self) * 60 +
4196 TIME_GET_SECOND(self);
4197 microseconds = TIME_GET_MICROSECOND(self);
4198 temp1 = new_delta(0, seconds, microseconds, 1);
4199 if (temp1 == NULL) {
4200 Py_DECREF(offset);
4201 return -1;
4202 }
4203 temp2 = delta_subtract(temp1, offset);
4204 Py_DECREF(temp1);
4205 if (temp2 == NULL) {
4206 Py_DECREF(offset);
4207 return -1;
4208 }
4209 self->hashcode = PyObject_Hash(temp2);
4210 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004211 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004212 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004213 }
4214 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004215}
Tim Peters2a799bf2002-12-16 20:18:38 +00004216
Tim Peters12bf3392002-12-24 05:41:27 +00004217static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004218time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004220 PyObject *clone;
4221 PyObject *tuple;
4222 int hh = TIME_GET_HOUR(self);
4223 int mm = TIME_GET_MINUTE(self);
4224 int ss = TIME_GET_SECOND(self);
4225 int us = TIME_GET_MICROSECOND(self);
4226 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004227 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004228
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004229 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004230 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004231 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004233 if (fold != 0 && fold != 1) {
4234 PyErr_SetString(PyExc_ValueError,
4235 "fold must be either 0 or 1");
4236 return NULL;
4237 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004238 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4239 if (tuple == NULL)
4240 return NULL;
4241 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004242 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004243 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004244 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004245 Py_DECREF(tuple);
4246 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004247}
4248
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004249static PyObject *
4250time_fromisoformat(PyObject *cls, PyObject *tstr) {
4251 assert(tstr != NULL);
4252
4253 if (!PyUnicode_Check(tstr)) {
4254 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4255 return NULL;
4256 }
4257
4258 Py_ssize_t len;
4259 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4260
4261 int hour = 0, minute = 0, second = 0, microsecond = 0;
4262 int tzoffset, tzimicrosecond = 0;
4263 int rv = parse_isoformat_time(p, len,
4264 &hour, &minute, &second, &microsecond,
4265 &tzoffset, &tzimicrosecond);
4266
4267 if (rv < 0) {
4268 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %s", p);
4269 return NULL;
4270 }
4271
4272 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4273 tzimicrosecond);
4274
4275 if (tzinfo == NULL) {
4276 return NULL;
4277 }
4278
4279 PyObject *t;
4280 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4281 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4282 } else {
4283 t = PyObject_CallFunction(cls, "iiiiO",
4284 hour, minute, second, microsecond, tzinfo);
4285 }
4286
4287 Py_DECREF(tzinfo);
4288 return t;
4289}
4290
4291
Tim Peters371935f2003-02-01 01:52:50 +00004292/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004293
Tim Peters33e0f382003-01-10 02:05:14 +00004294/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004295 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4296 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004297 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004298 */
4299static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004300time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004302 PyObject *basestate;
4303 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004305 basestate = PyBytes_FromStringAndSize((char *)self->data,
4306 _PyDateTime_TIME_DATASIZE);
4307 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004308 if (proto > 3 && TIME_GET_FOLD(self))
4309 /* Set the first bit of the first byte */
4310 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004311 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4312 result = PyTuple_Pack(1, basestate);
4313 else
4314 result = PyTuple_Pack(2, basestate, self->tzinfo);
4315 Py_DECREF(basestate);
4316 }
4317 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004318}
4319
4320static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004321time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004322{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004323 int proto;
4324 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004325 return NULL;
4326
4327 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004328}
4329
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004330static PyObject *
4331time_reduce(PyDateTime_Time *self, PyObject *arg)
4332{
4333 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4334}
4335
Tim Peters37f39822003-01-10 03:49:02 +00004336static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004337
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004338 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4339 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4340 "[+HH:MM].\n\n"
4341 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004343 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4344 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004346 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4347 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004349 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4350 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004352 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4353 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004355 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4356 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004358 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4359 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004360
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004361 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4362 PyDoc_STR("string -> time from time.isoformat() output")},
4363
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004364 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004365 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004366
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004367 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4368 PyDoc_STR("__reduce__() -> (cls, state)")},
4369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004370 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004371};
4372
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004373static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004374PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4375\n\
4376All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004377a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004378
Neal Norwitz227b5332006-03-22 09:28:35 +00004379static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004380 PyVarObject_HEAD_INIT(NULL, 0)
4381 "datetime.time", /* tp_name */
4382 sizeof(PyDateTime_Time), /* tp_basicsize */
4383 0, /* tp_itemsize */
4384 (destructor)time_dealloc, /* tp_dealloc */
4385 0, /* tp_print */
4386 0, /* tp_getattr */
4387 0, /* tp_setattr */
4388 0, /* tp_reserved */
4389 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004390 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004391 0, /* tp_as_sequence */
4392 0, /* tp_as_mapping */
4393 (hashfunc)time_hash, /* tp_hash */
4394 0, /* tp_call */
4395 (reprfunc)time_str, /* tp_str */
4396 PyObject_GenericGetAttr, /* tp_getattro */
4397 0, /* tp_setattro */
4398 0, /* tp_as_buffer */
4399 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4400 time_doc, /* tp_doc */
4401 0, /* tp_traverse */
4402 0, /* tp_clear */
4403 time_richcompare, /* tp_richcompare */
4404 0, /* tp_weaklistoffset */
4405 0, /* tp_iter */
4406 0, /* tp_iternext */
4407 time_methods, /* tp_methods */
4408 0, /* tp_members */
4409 time_getset, /* tp_getset */
4410 0, /* tp_base */
4411 0, /* tp_dict */
4412 0, /* tp_descr_get */
4413 0, /* tp_descr_set */
4414 0, /* tp_dictoffset */
4415 0, /* tp_init */
4416 time_alloc, /* tp_alloc */
4417 time_new, /* tp_new */
4418 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004419};
4420
4421/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004422 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004423 */
4424
Tim Petersa9bc1682003-01-11 03:39:11 +00004425/* Accessor properties. Properties for day, month, and year are inherited
4426 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004427 */
4428
4429static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004430datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004432 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004433}
4434
Tim Petersa9bc1682003-01-11 03:39:11 +00004435static PyObject *
4436datetime_minute(PyDateTime_DateTime *self, void *unused)
4437{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004438 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004439}
4440
4441static PyObject *
4442datetime_second(PyDateTime_DateTime *self, void *unused)
4443{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004444 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004445}
4446
4447static PyObject *
4448datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4449{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004450 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004451}
4452
4453static PyObject *
4454datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004456 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4457 Py_INCREF(result);
4458 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004459}
4460
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004461static PyObject *
4462datetime_fold(PyDateTime_DateTime *self, void *unused)
4463{
4464 return PyLong_FromLong(DATE_GET_FOLD(self));
4465}
4466
Tim Petersa9bc1682003-01-11 03:39:11 +00004467static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004468 {"hour", (getter)datetime_hour},
4469 {"minute", (getter)datetime_minute},
4470 {"second", (getter)datetime_second},
4471 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004472 {"tzinfo", (getter)datetime_tzinfo},
4473 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004474 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004475};
4476
4477/*
4478 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004479 */
4480
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004481static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004482 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004483 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004484};
4485
Tim Peters2a799bf2002-12-16 20:18:38 +00004486static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004487datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004489 PyObject *self = NULL;
4490 PyObject *state;
4491 int year;
4492 int month;
4493 int day;
4494 int hour = 0;
4495 int minute = 0;
4496 int second = 0;
4497 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004498 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004499 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004501 /* Check for invocation from pickle with __getstate__ state */
4502 if (PyTuple_GET_SIZE(args) >= 1 &&
4503 PyTuple_GET_SIZE(args) <= 2 &&
4504 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4505 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004506 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004507 {
4508 PyDateTime_DateTime *me;
4509 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004511 if (PyTuple_GET_SIZE(args) == 2) {
4512 tzinfo = PyTuple_GET_ITEM(args, 1);
4513 if (check_tzinfo_subclass(tzinfo) < 0) {
4514 PyErr_SetString(PyExc_TypeError, "bad "
4515 "tzinfo state arg");
4516 return NULL;
4517 }
4518 }
4519 aware = (char)(tzinfo != Py_None);
4520 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4521 if (me != NULL) {
4522 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004524 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4525 me->hashcode = -1;
4526 me->hastzinfo = aware;
4527 if (aware) {
4528 Py_INCREF(tzinfo);
4529 me->tzinfo = tzinfo;
4530 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004531 if (pdata[2] & (1 << 7)) {
4532 me->data[2] -= 128;
4533 me->fold = 1;
4534 }
4535 else {
4536 me->fold = 0;
4537 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004538 }
4539 return (PyObject *)me;
4540 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004541
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004542 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004543 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004544 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004545 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004546 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004547 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004548 }
4549 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004550}
4551
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004552/* TM_FUNC is the shared type of _PyTime_localtime() and
4553 * _PyTime_gmtime(). */
4554typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004555
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004556/* As of version 2015f max fold in IANA database is
4557 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004558static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004559/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004560static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004561
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004562static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004563utc_to_seconds(int year, int month, int day,
4564 int hour, int minute, int second)
4565{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004566 long long ordinal;
4567
4568 /* ymd_to_ord() doesn't support year <= 0 */
4569 if (year < MINYEAR || year > MAXYEAR) {
4570 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4571 return -1;
4572 }
4573
4574 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004575 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4576}
4577
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004578static long long
4579local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004580{
4581 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004582 time_t t;
4583 u -= epoch;
4584 t = u;
4585 if (t != u) {
4586 PyErr_SetString(PyExc_OverflowError,
4587 "timestamp out of range for platform time_t");
4588 return -1;
4589 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004590 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004591 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004592 return utc_to_seconds(local_time.tm_year + 1900,
4593 local_time.tm_mon + 1,
4594 local_time.tm_mday,
4595 local_time.tm_hour,
4596 local_time.tm_min,
4597 local_time.tm_sec);
4598}
4599
Tim Petersa9bc1682003-01-11 03:39:11 +00004600/* Internal helper.
4601 * Build datetime from a time_t and a distinct count of microseconds.
4602 * Pass localtime or gmtime for f, to control the interpretation of timet.
4603 */
4604static PyObject *
4605datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004606 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004607{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004608 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004609 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004610
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004611 if (f(timet, &tm) != 0)
4612 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004613
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004614 year = tm.tm_year + 1900;
4615 month = tm.tm_mon + 1;
4616 day = tm.tm_mday;
4617 hour = tm.tm_hour;
4618 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004619 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004620 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004621 * except to the extent that passing them on to the datetime
4622 * constructor would raise ValueError for a reason that
4623 * made no sense to the user.
4624 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004625 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004626
Victor Stinnerb67f0962017-02-10 10:34:02 +01004627 /* local timezone requires to compute fold */
Ammar Askar96d1e692018-07-25 09:54:58 -07004628 if (tzinfo == Py_None && f == _PyTime_localtime
4629 /* On Windows, passing a negative value to local results
4630 * in an OSError because localtime_s on Windows does
4631 * not support negative timestamps. Unfortunately this
4632 * means that fold detection for time values between
4633 * 0 and max_fold_seconds will result in an identical
4634 * error since we subtract max_fold_seconds to detect a
4635 * fold. However, since we know there haven't been any
4636 * folds in the interval [0, max_fold_seconds) in any
4637 * timezone, we can hackily just forego fold detection
4638 * for this time range.
4639 */
4640#ifdef MS_WINDOWS
4641 && (timet - max_fold_seconds > 0)
4642#endif
4643 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004644 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004645
4646 result_seconds = utc_to_seconds(year, month, day,
4647 hour, minute, second);
4648 /* Probe max_fold_seconds to detect a fold. */
4649 probe_seconds = local(epoch + timet - max_fold_seconds);
4650 if (probe_seconds == -1)
4651 return NULL;
4652 transition = result_seconds - probe_seconds - max_fold_seconds;
4653 if (transition < 0) {
4654 probe_seconds = local(epoch + timet + transition);
4655 if (probe_seconds == -1)
4656 return NULL;
4657 if (probe_seconds == result_seconds)
4658 fold = 1;
4659 }
4660 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004661 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4662 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004663}
4664
4665/* Internal helper.
4666 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4667 * to control the interpretation of the timestamp. Since a double doesn't
4668 * have enough bits to cover a datetime's full range of precision, it's
4669 * better to call datetime_from_timet_and_us provided you have a way
4670 * to get that much precision (e.g., C time() isn't good enough).
4671 */
4672static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004673datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004674 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004676 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004677 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004678
Victor Stinnere4a994d2015-03-30 01:10:14 +02004679 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004680 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004682
Victor Stinner21f58932012-03-14 00:15:40 +01004683 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004684}
4685
4686/* Internal helper.
4687 * Build most accurate possible datetime for current time. Pass localtime or
4688 * gmtime for f as appropriate.
4689 */
4690static PyObject *
4691datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4692{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004693 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004694 time_t secs;
4695 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004696
Victor Stinner1e2b6882015-09-18 13:23:02 +02004697 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004698 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004699 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004700
Victor Stinner1e2b6882015-09-18 13:23:02 +02004701 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004702}
4703
Larry Hastings61272b72014-01-07 12:41:53 -08004704/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004705
4706@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004707datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004708
4709 tz: object = None
4710 Timezone object.
4711
4712Returns new datetime object representing current time local to tz.
4713
4714If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004715[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004716
Larry Hastings31826802013-10-19 00:09:25 -07004717static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004718datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004719/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004720{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004721 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004722
Larry Hastings31826802013-10-19 00:09:25 -07004723 /* Return best possible local time -- this isn't constrained by the
4724 * precision of a timestamp.
4725 */
4726 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004727 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004728
Larry Hastings5c661892014-01-24 06:17:25 -08004729 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004730 tz == Py_None ? _PyTime_localtime :
4731 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004732 tz);
4733 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004734 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004735 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004736 }
4737 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004738}
4739
Tim Petersa9bc1682003-01-11 03:39:11 +00004740/* Return best possible UTC time -- this isn't constrained by the
4741 * precision of a timestamp.
4742 */
4743static PyObject *
4744datetime_utcnow(PyObject *cls, PyObject *dummy)
4745{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004746 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004747}
4748
Tim Peters2a799bf2002-12-16 20:18:38 +00004749/* Return new local datetime from timestamp (Python timestamp -- a double). */
4750static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004751datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004753 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004754 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004755 PyObject *tzinfo = Py_None;
4756 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004757
Victor Stinner5d272cc2012-03-13 13:35:55 +01004758 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004759 keywords, &timestamp, &tzinfo))
4760 return NULL;
4761 if (check_tzinfo_subclass(tzinfo) < 0)
4762 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004764 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004765 tzinfo == Py_None ? _PyTime_localtime :
4766 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004767 timestamp,
4768 tzinfo);
4769 if (self != NULL && tzinfo != Py_None) {
4770 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004771 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004772 }
4773 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004774}
4775
Tim Petersa9bc1682003-01-11 03:39:11 +00004776/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4777static PyObject *
4778datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4779{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004780 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004781 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004782
Victor Stinner5d272cc2012-03-13 13:35:55 +01004783 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004784 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004785 Py_None);
4786 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004787}
4788
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004789/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004790static PyObject *
4791datetime_strptime(PyObject *cls, PyObject *args)
4792{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004793 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004794 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004795 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004796
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004797 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004798 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004799
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004800 if (module == NULL) {
4801 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004802 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004803 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004804 }
Victor Stinner20401de2016-12-09 15:24:31 +01004805 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4806 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004807}
4808
Tim Petersa9bc1682003-01-11 03:39:11 +00004809/* Return new datetime from date/datetime and time arguments. */
4810static PyObject *
4811datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4812{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004813 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004814 PyObject *date;
4815 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004816 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004817 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004818
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004819 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004820 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004821 &PyDateTime_TimeType, &time, &tzinfo)) {
4822 if (tzinfo == NULL) {
4823 if (HASTZINFO(time))
4824 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4825 else
4826 tzinfo = Py_None;
4827 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004828 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
4829 GET_MONTH(date),
4830 GET_DAY(date),
4831 TIME_GET_HOUR(time),
4832 TIME_GET_MINUTE(time),
4833 TIME_GET_SECOND(time),
4834 TIME_GET_MICROSECOND(time),
4835 tzinfo,
4836 TIME_GET_FOLD(time),
4837 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004838 }
4839 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004840}
Tim Peters2a799bf2002-12-16 20:18:38 +00004841
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004842static PyObject *
4843datetime_fromisoformat(PyObject* cls, PyObject *dtstr) {
4844 assert(dtstr != NULL);
4845
4846 if (!PyUnicode_Check(dtstr)) {
4847 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4848 return NULL;
4849 }
4850
4851 Py_ssize_t len;
4852 const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
4853 const char * p = dt_ptr;
4854
4855 int year = 0, month = 0, day = 0;
4856 int hour = 0, minute = 0, second = 0, microsecond = 0;
4857 int tzoffset = 0, tzusec = 0;
4858
4859 // date has a fixed length of 10
4860 int rv = parse_isoformat_date(p, &year, &month, &day);
4861
4862 if (!rv && len > 10) {
4863 // In UTF-8, the length of multi-byte characters is encoded in the MSB
4864 if ((p[10] & 0x80) == 0) {
4865 p += 11;
4866 } else {
4867 switch(p[10] & 0xf0) {
4868 case 0xe0:
4869 p += 13;
4870 break;
4871 case 0xf0:
4872 p += 14;
4873 break;
4874 default:
4875 p += 12;
4876 break;
4877 }
4878 }
4879
4880 len -= (p - dt_ptr);
4881 rv = parse_isoformat_time(p, len,
4882 &hour, &minute, &second, &microsecond,
4883 &tzoffset, &tzusec);
4884 }
4885 if (rv < 0) {
4886 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %s", dt_ptr);
4887 return NULL;
4888 }
4889
4890 PyObject* tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
4891 if (tzinfo == NULL) {
4892 return NULL;
4893 }
4894
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004895 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
4896 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004897
4898 Py_DECREF(tzinfo);
4899 return dt;
4900}
4901
4902
Tim Peters2a799bf2002-12-16 20:18:38 +00004903/*
4904 * Destructor.
4905 */
4906
4907static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004908datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004910 if (HASTZINFO(self)) {
4911 Py_XDECREF(self->tzinfo);
4912 }
4913 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004914}
4915
4916/*
4917 * Indirect access to tzinfo methods.
4918 */
4919
Tim Peters2a799bf2002-12-16 20:18:38 +00004920/* These are all METH_NOARGS, so don't need to check the arglist. */
4921static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004922datetime_utcoffset(PyObject *self, PyObject *unused) {
4923 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004924}
4925
4926static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004927datetime_dst(PyObject *self, PyObject *unused) {
4928 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004929}
4930
4931static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004932datetime_tzname(PyObject *self, PyObject *unused) {
4933 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004934}
4935
4936/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004937 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004938 */
4939
Tim Petersa9bc1682003-01-11 03:39:11 +00004940/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4941 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004942 */
4943static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004944add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004945 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004946{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004947 /* Note that the C-level additions can't overflow, because of
4948 * invariant bounds on the member values.
4949 */
4950 int year = GET_YEAR(date);
4951 int month = GET_MONTH(date);
4952 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4953 int hour = DATE_GET_HOUR(date);
4954 int minute = DATE_GET_MINUTE(date);
4955 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4956 int microsecond = DATE_GET_MICROSECOND(date) +
4957 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004959 assert(factor == 1 || factor == -1);
4960 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01004961 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004962 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01004963 }
4964
4965 return new_datetime(year, month, day,
4966 hour, minute, second, microsecond,
4967 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004968}
4969
4970static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004971datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004973 if (PyDateTime_Check(left)) {
4974 /* datetime + ??? */
4975 if (PyDelta_Check(right))
4976 /* datetime + delta */
4977 return add_datetime_timedelta(
4978 (PyDateTime_DateTime *)left,
4979 (PyDateTime_Delta *)right,
4980 1);
4981 }
4982 else if (PyDelta_Check(left)) {
4983 /* delta + datetime */
4984 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4985 (PyDateTime_Delta *) left,
4986 1);
4987 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004988 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004989}
4990
4991static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004992datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004993{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004994 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004996 if (PyDateTime_Check(left)) {
4997 /* datetime - ??? */
4998 if (PyDateTime_Check(right)) {
4999 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005000 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005001 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005002
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005003 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5004 offset2 = offset1 = Py_None;
5005 Py_INCREF(offset1);
5006 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005007 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005008 else {
5009 offset1 = datetime_utcoffset(left, NULL);
5010 if (offset1 == NULL)
5011 return NULL;
5012 offset2 = datetime_utcoffset(right, NULL);
5013 if (offset2 == NULL) {
5014 Py_DECREF(offset1);
5015 return NULL;
5016 }
5017 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5018 PyErr_SetString(PyExc_TypeError,
5019 "can't subtract offset-naive and "
5020 "offset-aware datetimes");
5021 Py_DECREF(offset1);
5022 Py_DECREF(offset2);
5023 return NULL;
5024 }
5025 }
5026 if ((offset1 != offset2) &&
5027 delta_cmp(offset1, offset2) != 0) {
5028 offdiff = delta_subtract(offset1, offset2);
5029 if (offdiff == NULL) {
5030 Py_DECREF(offset1);
5031 Py_DECREF(offset2);
5032 return NULL;
5033 }
5034 }
5035 Py_DECREF(offset1);
5036 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005037 delta_d = ymd_to_ord(GET_YEAR(left),
5038 GET_MONTH(left),
5039 GET_DAY(left)) -
5040 ymd_to_ord(GET_YEAR(right),
5041 GET_MONTH(right),
5042 GET_DAY(right));
5043 /* These can't overflow, since the values are
5044 * normalized. At most this gives the number of
5045 * seconds in one day.
5046 */
5047 delta_s = (DATE_GET_HOUR(left) -
5048 DATE_GET_HOUR(right)) * 3600 +
5049 (DATE_GET_MINUTE(left) -
5050 DATE_GET_MINUTE(right)) * 60 +
5051 (DATE_GET_SECOND(left) -
5052 DATE_GET_SECOND(right));
5053 delta_us = DATE_GET_MICROSECOND(left) -
5054 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005055 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005056 if (result == NULL)
5057 return NULL;
5058
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005059 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005060 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005061 Py_DECREF(offdiff);
5062 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005063 }
5064 else if (PyDelta_Check(right)) {
5065 /* datetime - delta */
5066 result = add_datetime_timedelta(
5067 (PyDateTime_DateTime *)left,
5068 (PyDateTime_Delta *)right,
5069 -1);
5070 }
5071 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005073 if (result == Py_NotImplemented)
5074 Py_INCREF(result);
5075 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005076}
5077
5078/* Various ways to turn a datetime into a string. */
5079
5080static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005081datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005083 const char *type_name = Py_TYPE(self)->tp_name;
5084 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005086 if (DATE_GET_MICROSECOND(self)) {
5087 baserepr = PyUnicode_FromFormat(
5088 "%s(%d, %d, %d, %d, %d, %d, %d)",
5089 type_name,
5090 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5091 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5092 DATE_GET_SECOND(self),
5093 DATE_GET_MICROSECOND(self));
5094 }
5095 else if (DATE_GET_SECOND(self)) {
5096 baserepr = PyUnicode_FromFormat(
5097 "%s(%d, %d, %d, %d, %d, %d)",
5098 type_name,
5099 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5100 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5101 DATE_GET_SECOND(self));
5102 }
5103 else {
5104 baserepr = PyUnicode_FromFormat(
5105 "%s(%d, %d, %d, %d, %d)",
5106 type_name,
5107 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5108 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5109 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005110 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5111 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005112 if (baserepr == NULL || ! HASTZINFO(self))
5113 return baserepr;
5114 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005115}
5116
Tim Petersa9bc1682003-01-11 03:39:11 +00005117static PyObject *
5118datetime_str(PyDateTime_DateTime *self)
5119{
Victor Stinner4c381542016-12-09 00:33:39 +01005120 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005121}
Tim Peters2a799bf2002-12-16 20:18:38 +00005122
5123static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005124datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005126 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005127 char *timespec = NULL;
5128 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005129 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005130 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005131 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005132 static char *specs[][2] = {
5133 {"hours", "%04d-%02d-%02d%c%02d"},
5134 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5135 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5136 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5137 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5138 };
5139 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005140
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005141 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005142 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005143
5144 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5145 if (us == 0) {
5146 /* seconds */
5147 given_spec = 2;
5148 }
5149 else {
5150 /* microseconds */
5151 given_spec = 4;
5152 }
5153 }
5154 else {
5155 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5156 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5157 if (given_spec == 3) {
5158 us = us / 1000;
5159 }
5160 break;
5161 }
5162 }
5163 }
5164
5165 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5166 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5167 return NULL;
5168 }
5169 else {
5170 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005171 GET_YEAR(self), GET_MONTH(self),
5172 GET_DAY(self), (int)sep,
5173 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5174 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005175 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005177 if (!result || !HASTZINFO(self))
5178 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005180 /* We need to append the UTC offset. */
5181 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5182 (PyObject *)self) < 0) {
5183 Py_DECREF(result);
5184 return NULL;
5185 }
5186 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5187 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005188}
5189
Tim Petersa9bc1682003-01-11 03:39:11 +00005190static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305191datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005193 return format_ctime((PyDateTime_Date *)self,
5194 DATE_GET_HOUR(self),
5195 DATE_GET_MINUTE(self),
5196 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005197}
5198
Tim Peters2a799bf2002-12-16 20:18:38 +00005199/* Miscellaneous methods. */
5200
Tim Petersa9bc1682003-01-11 03:39:11 +00005201static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005202flip_fold(PyObject *dt)
5203{
5204 return new_datetime_ex2(GET_YEAR(dt),
5205 GET_MONTH(dt),
5206 GET_DAY(dt),
5207 DATE_GET_HOUR(dt),
5208 DATE_GET_MINUTE(dt),
5209 DATE_GET_SECOND(dt),
5210 DATE_GET_MICROSECOND(dt),
5211 HASTZINFO(dt) ?
5212 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5213 !DATE_GET_FOLD(dt),
5214 Py_TYPE(dt));
5215}
5216
5217static PyObject *
5218get_flip_fold_offset(PyObject *dt)
5219{
5220 PyObject *result, *flip_dt;
5221
5222 flip_dt = flip_fold(dt);
5223 if (flip_dt == NULL)
5224 return NULL;
5225 result = datetime_utcoffset(flip_dt, NULL);
5226 Py_DECREF(flip_dt);
5227 return result;
5228}
5229
5230/* PEP 495 exception: Whenever one or both of the operands in
5231 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakabac2d5b2018-03-28 22:14:26 +03005232 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005233 *
5234 * Return 1 if exception applies, 0 if not, and -1 on error.
5235 */
5236static int
5237pep495_eq_exception(PyObject *self, PyObject *other,
5238 PyObject *offset_self, PyObject *offset_other)
5239{
5240 int result = 0;
5241 PyObject *flip_offset;
5242
5243 flip_offset = get_flip_fold_offset(self);
5244 if (flip_offset == NULL)
5245 return -1;
5246 if (flip_offset != offset_self &&
5247 delta_cmp(flip_offset, offset_self))
5248 {
5249 result = 1;
5250 goto done;
5251 }
5252 Py_DECREF(flip_offset);
5253
5254 flip_offset = get_flip_fold_offset(other);
5255 if (flip_offset == NULL)
5256 return -1;
5257 if (flip_offset != offset_other &&
5258 delta_cmp(flip_offset, offset_other))
5259 result = 1;
5260 done:
5261 Py_DECREF(flip_offset);
5262 return result;
5263}
5264
5265static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005266datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005267{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005268 PyObject *result = NULL;
5269 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005270 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005272 if (! PyDateTime_Check(other)) {
5273 if (PyDate_Check(other)) {
5274 /* Prevent invocation of date_richcompare. We want to
5275 return NotImplemented here to give the other object
5276 a chance. But since DateTime is a subclass of
5277 Date, if the other object is a Date, it would
5278 compute an ordering based on the date part alone,
5279 and we don't want that. So force unequal or
5280 uncomparable here in that case. */
5281 if (op == Py_EQ)
5282 Py_RETURN_FALSE;
5283 if (op == Py_NE)
5284 Py_RETURN_TRUE;
5285 return cmperror(self, other);
5286 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005287 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005288 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005289
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005290 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005291 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5292 ((PyDateTime_DateTime *)other)->data,
5293 _PyDateTime_DATETIME_DATASIZE);
5294 return diff_to_bool(diff, op);
5295 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005296 offset1 = datetime_utcoffset(self, NULL);
5297 if (offset1 == NULL)
5298 return NULL;
5299 offset2 = datetime_utcoffset(other, NULL);
5300 if (offset2 == NULL)
5301 goto done;
5302 /* If they're both naive, or both aware and have the same offsets,
5303 * we get off cheap. Note that if they're both naive, offset1 ==
5304 * offset2 == Py_None at this point.
5305 */
5306 if ((offset1 == offset2) ||
5307 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5308 delta_cmp(offset1, offset2) == 0)) {
5309 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5310 ((PyDateTime_DateTime *)other)->data,
5311 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005312 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5313 int ex = pep495_eq_exception(self, other, offset1, offset2);
5314 if (ex == -1)
5315 goto done;
5316 if (ex)
5317 diff = 1;
5318 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005319 result = diff_to_bool(diff, op);
5320 }
5321 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005322 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005323
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005324 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005325 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5326 other);
5327 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005328 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005329 diff = GET_TD_DAYS(delta);
5330 if (diff == 0)
5331 diff = GET_TD_SECONDS(delta) |
5332 GET_TD_MICROSECONDS(delta);
5333 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005334 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5335 int ex = pep495_eq_exception(self, other, offset1, offset2);
5336 if (ex == -1)
5337 goto done;
5338 if (ex)
5339 diff = 1;
5340 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005341 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005342 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005343 else if (op == Py_EQ) {
5344 result = Py_False;
5345 Py_INCREF(result);
5346 }
5347 else if (op == Py_NE) {
5348 result = Py_True;
5349 Py_INCREF(result);
5350 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005351 else {
5352 PyErr_SetString(PyExc_TypeError,
5353 "can't compare offset-naive and "
5354 "offset-aware datetimes");
5355 }
5356 done:
5357 Py_DECREF(offset1);
5358 Py_XDECREF(offset2);
5359 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005360}
5361
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005362static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005363datetime_hash(PyDateTime_DateTime *self)
5364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005365 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005366 PyObject *offset, *self0;
5367 if (DATE_GET_FOLD(self)) {
5368 self0 = new_datetime_ex2(GET_YEAR(self),
5369 GET_MONTH(self),
5370 GET_DAY(self),
5371 DATE_GET_HOUR(self),
5372 DATE_GET_MINUTE(self),
5373 DATE_GET_SECOND(self),
5374 DATE_GET_MICROSECOND(self),
5375 HASTZINFO(self) ? self->tzinfo : Py_None,
5376 0, Py_TYPE(self));
5377 if (self0 == NULL)
5378 return -1;
5379 }
5380 else {
5381 self0 = (PyObject *)self;
5382 Py_INCREF(self0);
5383 }
5384 offset = datetime_utcoffset(self0, NULL);
5385 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005386
5387 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005388 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005390 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005391 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005392 self->hashcode = generic_hash(
5393 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005394 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005395 PyObject *temp1, *temp2;
5396 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005398 assert(HASTZINFO(self));
5399 days = ymd_to_ord(GET_YEAR(self),
5400 GET_MONTH(self),
5401 GET_DAY(self));
5402 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005403 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005404 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005405 temp1 = new_delta(days, seconds,
5406 DATE_GET_MICROSECOND(self),
5407 1);
5408 if (temp1 == NULL) {
5409 Py_DECREF(offset);
5410 return -1;
5411 }
5412 temp2 = delta_subtract(temp1, offset);
5413 Py_DECREF(temp1);
5414 if (temp2 == NULL) {
5415 Py_DECREF(offset);
5416 return -1;
5417 }
5418 self->hashcode = PyObject_Hash(temp2);
5419 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005420 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005421 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005422 }
5423 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005424}
Tim Peters2a799bf2002-12-16 20:18:38 +00005425
5426static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005427datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005429 PyObject *clone;
5430 PyObject *tuple;
5431 int y = GET_YEAR(self);
5432 int m = GET_MONTH(self);
5433 int d = GET_DAY(self);
5434 int hh = DATE_GET_HOUR(self);
5435 int mm = DATE_GET_MINUTE(self);
5436 int ss = DATE_GET_SECOND(self);
5437 int us = DATE_GET_MICROSECOND(self);
5438 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005439 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005440
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005441 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005442 datetime_kws,
5443 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005444 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005445 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005446 if (fold != 0 && fold != 1) {
5447 PyErr_SetString(PyExc_ValueError,
5448 "fold must be either 0 or 1");
5449 return NULL;
5450 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005451 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5452 if (tuple == NULL)
5453 return NULL;
5454 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005455 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005456 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005457 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005458 Py_DECREF(tuple);
5459 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005460}
5461
5462static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005463local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005464{
5465 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005466 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005467 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005468 PyObject *nameo = NULL;
5469 const char *zone = NULL;
5470
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005471 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005472 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005473#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005474 zone = local_time_tm.tm_zone;
5475 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005476#else /* HAVE_STRUCT_TM_TM_ZONE */
5477 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005478 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005479 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005480 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005481 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005482 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005483 local_time = new_datetime(local_time_tm.tm_year + 1900,
5484 local_time_tm.tm_mon + 1,
5485 local_time_tm.tm_mday,
5486 local_time_tm.tm_hour,
5487 local_time_tm.tm_min,
5488 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005489 if (local_time == NULL) {
5490 return NULL;
5491 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005492 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005493 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005494 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5495 utc_time_tm.tm_mon + 1,
5496 utc_time_tm.tm_mday,
5497 utc_time_tm.tm_hour,
5498 utc_time_tm.tm_min,
5499 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005500 if (utc_time == NULL) {
5501 Py_DECREF(local_time);
5502 return NULL;
5503 }
5504 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005505 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005506 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005507 }
5508#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005509 if (delta == NULL) {
5510 return NULL;
5511 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005512 if (zone != NULL) {
5513 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5514 if (nameo == NULL)
5515 goto error;
5516 }
5517 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005518 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005519 error:
5520 Py_DECREF(delta);
5521 return result;
5522}
5523
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005524static PyObject *
5525local_timezone(PyDateTime_DateTime *utc_time)
5526{
5527 time_t timestamp;
5528 PyObject *delta;
5529 PyObject *one_second;
5530 PyObject *seconds;
5531
5532 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5533 if (delta == NULL)
5534 return NULL;
5535 one_second = new_delta(0, 1, 0, 0);
5536 if (one_second == NULL) {
5537 Py_DECREF(delta);
5538 return NULL;
5539 }
5540 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5541 (PyDateTime_Delta *)one_second);
5542 Py_DECREF(one_second);
5543 Py_DECREF(delta);
5544 if (seconds == NULL)
5545 return NULL;
5546 timestamp = _PyLong_AsTime_t(seconds);
5547 Py_DECREF(seconds);
5548 if (timestamp == -1 && PyErr_Occurred())
5549 return NULL;
5550 return local_timezone_from_timestamp(timestamp);
5551}
5552
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005553static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005554local_to_seconds(int year, int month, int day,
5555 int hour, int minute, int second, int fold);
5556
5557static PyObject *
5558local_timezone_from_local(PyDateTime_DateTime *local_dt)
5559{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005560 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005561 time_t timestamp;
5562 seconds = local_to_seconds(GET_YEAR(local_dt),
5563 GET_MONTH(local_dt),
5564 GET_DAY(local_dt),
5565 DATE_GET_HOUR(local_dt),
5566 DATE_GET_MINUTE(local_dt),
5567 DATE_GET_SECOND(local_dt),
5568 DATE_GET_FOLD(local_dt));
5569 if (seconds == -1)
5570 return NULL;
5571 /* XXX: add bounds check */
5572 timestamp = seconds - epoch;
5573 return local_timezone_from_timestamp(timestamp);
5574}
5575
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005576static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005577datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005578{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005579 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005580 PyObject *offset;
5581 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005582 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005583 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005584 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005585
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005586 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005587 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005588 return NULL;
5589
5590 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005591 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005592
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005593 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005594 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005595 self_tzinfo = local_timezone_from_local(self);
5596 if (self_tzinfo == NULL)
5597 return NULL;
5598 } else {
5599 self_tzinfo = self->tzinfo;
5600 Py_INCREF(self_tzinfo);
5601 }
Tim Peters521fc152002-12-31 17:36:56 +00005602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005603 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005604 if (self_tzinfo == tzinfo) {
5605 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005606 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005607 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005608 }
Tim Peters521fc152002-12-31 17:36:56 +00005609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005610 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005611 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5612 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005613 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005614 return NULL;
Alexander Belopolsky877b2322018-06-10 17:02:58 -04005615 else if(offset == Py_None) {
5616 Py_DECREF(offset);
5617 goto naive;
5618 }
5619 else if (!PyDelta_Check(offset)) {
5620 Py_DECREF(offset);
5621 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5622 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5623 return NULL;
5624 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005625 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005626 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5627 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005628 Py_DECREF(offset);
5629 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005630 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005631
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005632 /* Make sure result is aware and UTC. */
5633 if (!HASTZINFO(result)) {
5634 temp = (PyObject *)result;
5635 result = (PyDateTime_DateTime *)
5636 new_datetime_ex2(GET_YEAR(result),
5637 GET_MONTH(result),
5638 GET_DAY(result),
5639 DATE_GET_HOUR(result),
5640 DATE_GET_MINUTE(result),
5641 DATE_GET_SECOND(result),
5642 DATE_GET_MICROSECOND(result),
5643 PyDateTime_TimeZone_UTC,
5644 DATE_GET_FOLD(result),
5645 Py_TYPE(result));
5646 Py_DECREF(temp);
5647 if (result == NULL)
5648 return NULL;
5649 }
5650 else {
5651 /* Result is already aware - just replace tzinfo. */
5652 temp = result->tzinfo;
5653 result->tzinfo = PyDateTime_TimeZone_UTC;
5654 Py_INCREF(result->tzinfo);
5655 Py_DECREF(temp);
5656 }
5657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005658 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005659 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005660 if (tzinfo == Py_None) {
5661 tzinfo = local_timezone(result);
5662 if (tzinfo == NULL) {
5663 Py_DECREF(result);
5664 return NULL;
5665 }
5666 }
5667 else
5668 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005669 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005670 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005671
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005672 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005673 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005674 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005675 Py_DECREF(temp);
5676
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005677 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005678}
5679
5680static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305681datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00005682{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005683 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005685 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005686 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005687
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005688 dst = call_dst(self->tzinfo, (PyObject *)self);
5689 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005690 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005691
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005692 if (dst != Py_None)
5693 dstflag = delta_bool((PyDateTime_Delta *)dst);
5694 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005695 }
5696 return build_struct_time(GET_YEAR(self),
5697 GET_MONTH(self),
5698 GET_DAY(self),
5699 DATE_GET_HOUR(self),
5700 DATE_GET_MINUTE(self),
5701 DATE_GET_SECOND(self),
5702 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005703}
5704
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005705static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005706local_to_seconds(int year, int month, int day,
5707 int hour, int minute, int second, int fold)
5708{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005709 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005710 t = utc_to_seconds(year, month, day, hour, minute, second);
5711 /* Our goal is to solve t = local(u) for u. */
5712 lt = local(t);
5713 if (lt == -1)
5714 return -1;
5715 a = lt - t;
5716 u1 = t - a;
5717 t1 = local(u1);
5718 if (t1 == -1)
5719 return -1;
5720 if (t1 == t) {
5721 /* We found one solution, but it may not be the one we need.
5722 * Look for an earlier solution (if `fold` is 0), or a
5723 * later one (if `fold` is 1). */
5724 if (fold)
5725 u2 = u1 + max_fold_seconds;
5726 else
5727 u2 = u1 - max_fold_seconds;
5728 lt = local(u2);
5729 if (lt == -1)
5730 return -1;
5731 b = lt - u2;
5732 if (a == b)
5733 return u1;
5734 }
5735 else {
5736 b = t1 - u1;
5737 assert(a != b);
5738 }
5739 u2 = t - b;
5740 t2 = local(u2);
5741 if (t2 == -1)
5742 return -1;
5743 if (t2 == t)
5744 return u2;
5745 if (t1 == t)
5746 return u1;
5747 /* We have found both offsets a and b, but neither t - a nor t - b is
5748 * a solution. This means t is in the gap. */
5749 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5750}
5751
5752/* date(1970,1,1).toordinal() == 719163 */
5753#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5754
Tim Peters2a799bf2002-12-16 20:18:38 +00005755static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305756datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Alexander Belopolskya4415142012-06-08 12:33:09 -04005757{
5758 PyObject *result;
5759
5760 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5761 PyObject *delta;
5762 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5763 if (delta == NULL)
5764 return NULL;
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305765 result = delta_total_seconds(delta, NULL);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005766 Py_DECREF(delta);
5767 }
5768 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005769 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005770 seconds = local_to_seconds(GET_YEAR(self),
5771 GET_MONTH(self),
5772 GET_DAY(self),
5773 DATE_GET_HOUR(self),
5774 DATE_GET_MINUTE(self),
5775 DATE_GET_SECOND(self),
5776 DATE_GET_FOLD(self));
5777 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005778 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005779 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5780 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005781 }
5782 return result;
5783}
5784
5785static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305786datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005788 return new_date(GET_YEAR(self),
5789 GET_MONTH(self),
5790 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005791}
5792
5793static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305794datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005796 return new_time(DATE_GET_HOUR(self),
5797 DATE_GET_MINUTE(self),
5798 DATE_GET_SECOND(self),
5799 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005800 Py_None,
5801 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005802}
5803
5804static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305805datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Petersa9bc1682003-01-11 03:39:11 +00005806{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005807 return new_time(DATE_GET_HOUR(self),
5808 DATE_GET_MINUTE(self),
5809 DATE_GET_SECOND(self),
5810 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005811 GET_DT_TZINFO(self),
5812 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005813}
5814
5815static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05305816datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored))
Tim Peters2a799bf2002-12-16 20:18:38 +00005817{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005818 int y, m, d, hh, mm, ss;
5819 PyObject *tzinfo;
5820 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005821
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005822 tzinfo = GET_DT_TZINFO(self);
5823 if (tzinfo == Py_None) {
5824 utcself = self;
5825 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005826 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005827 else {
5828 PyObject *offset;
5829 offset = call_utcoffset(tzinfo, (PyObject *)self);
5830 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005831 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005832 if (offset == Py_None) {
5833 Py_DECREF(offset);
5834 utcself = self;
5835 Py_INCREF(utcself);
5836 }
5837 else {
5838 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5839 (PyDateTime_Delta *)offset, -1);
5840 Py_DECREF(offset);
5841 if (utcself == NULL)
5842 return NULL;
5843 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005844 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005845 y = GET_YEAR(utcself);
5846 m = GET_MONTH(utcself);
5847 d = GET_DAY(utcself);
5848 hh = DATE_GET_HOUR(utcself);
5849 mm = DATE_GET_MINUTE(utcself);
5850 ss = DATE_GET_SECOND(utcself);
5851
5852 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005853 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005854}
5855
Tim Peters371935f2003-02-01 01:52:50 +00005856/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005857
Tim Petersa9bc1682003-01-11 03:39:11 +00005858/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005859 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5860 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005861 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005862 */
5863static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005864datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005866 PyObject *basestate;
5867 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005869 basestate = PyBytes_FromStringAndSize((char *)self->data,
5870 _PyDateTime_DATETIME_DATASIZE);
5871 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005872 if (proto > 3 && DATE_GET_FOLD(self))
5873 /* Set the first bit of the third byte */
5874 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005875 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5876 result = PyTuple_Pack(1, basestate);
5877 else
5878 result = PyTuple_Pack(2, basestate, self->tzinfo);
5879 Py_DECREF(basestate);
5880 }
5881 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005882}
5883
5884static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005885datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005886{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005887 int proto;
5888 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005889 return NULL;
5890
5891 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005892}
5893
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005894static PyObject *
5895datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5896{
5897 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5898}
5899
Tim Petersa9bc1682003-01-11 03:39:11 +00005900static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005902 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005903
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005904 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005906 {"utcnow", (PyCFunction)datetime_utcnow,
5907 METH_NOARGS | METH_CLASS,
5908 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005910 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5911 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5912 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005914 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5915 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005916 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005918 {"strptime", (PyCFunction)datetime_strptime,
5919 METH_VARARGS | METH_CLASS,
5920 PyDoc_STR("string, format -> new datetime parsed from a string "
5921 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005923 {"combine", (PyCFunction)datetime_combine,
5924 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5925 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005926
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005927 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
5928 METH_O | METH_CLASS,
5929 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
5930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005931 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005933 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5934 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005936 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5937 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005939 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5940 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005942 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5943 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005945 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5946 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005947
Alexander Belopolskya4415142012-06-08 12:33:09 -04005948 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5949 PyDoc_STR("Return POSIX timestamp as float.")},
5950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005951 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5952 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005954 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5955 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005956 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005957 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005958 "defaults to 'T'.\n"
5959 "timespec specifies what components of the time to include"
5960 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5961 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005963 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5964 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005966 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5967 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005969 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5970 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005972 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5973 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005975 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5976 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005977
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005978 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005979 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005980
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005981 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5982 PyDoc_STR("__reduce__() -> (cls, state)")},
5983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005984 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005985};
5986
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005987static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005988PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5989\n\
5990The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005991instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005992
Tim Petersa9bc1682003-01-11 03:39:11 +00005993static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005994 datetime_add, /* nb_add */
5995 datetime_subtract, /* nb_subtract */
5996 0, /* nb_multiply */
5997 0, /* nb_remainder */
5998 0, /* nb_divmod */
5999 0, /* nb_power */
6000 0, /* nb_negative */
6001 0, /* nb_positive */
6002 0, /* nb_absolute */
6003 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006004};
6005
Neal Norwitz227b5332006-03-22 09:28:35 +00006006static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006007 PyVarObject_HEAD_INIT(NULL, 0)
6008 "datetime.datetime", /* tp_name */
6009 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6010 0, /* tp_itemsize */
6011 (destructor)datetime_dealloc, /* tp_dealloc */
6012 0, /* tp_print */
6013 0, /* tp_getattr */
6014 0, /* tp_setattr */
6015 0, /* tp_reserved */
6016 (reprfunc)datetime_repr, /* tp_repr */
6017 &datetime_as_number, /* tp_as_number */
6018 0, /* tp_as_sequence */
6019 0, /* tp_as_mapping */
6020 (hashfunc)datetime_hash, /* tp_hash */
6021 0, /* tp_call */
6022 (reprfunc)datetime_str, /* tp_str */
6023 PyObject_GenericGetAttr, /* tp_getattro */
6024 0, /* tp_setattro */
6025 0, /* tp_as_buffer */
6026 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6027 datetime_doc, /* tp_doc */
6028 0, /* tp_traverse */
6029 0, /* tp_clear */
6030 datetime_richcompare, /* tp_richcompare */
6031 0, /* tp_weaklistoffset */
6032 0, /* tp_iter */
6033 0, /* tp_iternext */
6034 datetime_methods, /* tp_methods */
6035 0, /* tp_members */
6036 datetime_getset, /* tp_getset */
6037 &PyDateTime_DateType, /* tp_base */
6038 0, /* tp_dict */
6039 0, /* tp_descr_get */
6040 0, /* tp_descr_set */
6041 0, /* tp_dictoffset */
6042 0, /* tp_init */
6043 datetime_alloc, /* tp_alloc */
6044 datetime_new, /* tp_new */
6045 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006046};
6047
6048/* ---------------------------------------------------------------------------
6049 * Module methods and initialization.
6050 */
6051
6052static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006053 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006054};
6055
Tim Peters9ddf40b2004-06-20 22:41:32 +00006056/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6057 * datetime.h.
6058 */
6059static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006060 &PyDateTime_DateType,
6061 &PyDateTime_DateTimeType,
6062 &PyDateTime_TimeType,
6063 &PyDateTime_DeltaType,
6064 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006065 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006066 new_date_ex,
6067 new_datetime_ex,
6068 new_time_ex,
6069 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006070 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006071 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006072 date_fromtimestamp,
6073 new_datetime_ex2,
6074 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006075};
6076
6077
Martin v. Löwis1a214512008-06-11 05:26:20 +00006078
6079static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006080 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006081 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006082 "Fast implementation of the datetime type.",
6083 -1,
6084 module_methods,
6085 NULL,
6086 NULL,
6087 NULL,
6088 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006089};
6090
Tim Peters2a799bf2002-12-16 20:18:38 +00006091PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006092PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006094 PyObject *m; /* a module object */
6095 PyObject *d; /* its dict */
6096 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006097 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006099 m = PyModule_Create(&datetimemodule);
6100 if (m == NULL)
6101 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006103 if (PyType_Ready(&PyDateTime_DateType) < 0)
6104 return NULL;
6105 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6106 return NULL;
6107 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6108 return NULL;
6109 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6110 return NULL;
6111 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6112 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006113 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6114 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006116 /* timedelta values */
6117 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006119 x = new_delta(0, 0, 1, 0);
6120 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6121 return NULL;
6122 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006124 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6125 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6126 return NULL;
6127 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006129 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6130 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6131 return NULL;
6132 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006134 /* date values */
6135 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006137 x = new_date(1, 1, 1);
6138 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6139 return NULL;
6140 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006142 x = new_date(MAXYEAR, 12, 31);
6143 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6144 return NULL;
6145 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006147 x = new_delta(1, 0, 0, 0);
6148 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6149 return NULL;
6150 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006152 /* time values */
6153 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006154
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006155 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006156 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6157 return NULL;
6158 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006159
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006160 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006161 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6162 return NULL;
6163 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006165 x = new_delta(0, 0, 1, 0);
6166 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6167 return NULL;
6168 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006170 /* datetime values */
6171 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006172
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006173 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006174 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6175 return NULL;
6176 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006177
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006178 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006179 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6180 return NULL;
6181 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006183 x = new_delta(0, 0, 1, 0);
6184 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6185 return NULL;
6186 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006187
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006188 /* timezone values */
6189 d = PyDateTime_TimeZoneType.tp_dict;
6190
6191 delta = new_delta(0, 0, 0, 0);
6192 if (delta == NULL)
6193 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006194 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006195 Py_DECREF(delta);
6196 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6197 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006198 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006199 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006200
6201 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6202 if (delta == NULL)
6203 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006204 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006205 Py_DECREF(delta);
6206 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6207 return NULL;
6208 Py_DECREF(x);
6209
6210 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6211 if (delta == NULL)
6212 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006213 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006214 Py_DECREF(delta);
6215 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6216 return NULL;
6217 Py_DECREF(x);
6218
Alexander Belopolskya4415142012-06-08 12:33:09 -04006219 /* Epoch */
6220 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006221 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006222 if (PyDateTime_Epoch == NULL)
6223 return NULL;
6224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006225 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006226 PyModule_AddIntMacro(m, MINYEAR);
6227 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006229 Py_INCREF(&PyDateTime_DateType);
6230 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006232 Py_INCREF(&PyDateTime_DateTimeType);
6233 PyModule_AddObject(m, "datetime",
6234 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006236 Py_INCREF(&PyDateTime_TimeType);
6237 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006239 Py_INCREF(&PyDateTime_DeltaType);
6240 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006242 Py_INCREF(&PyDateTime_TZInfoType);
6243 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006244
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006245 Py_INCREF(&PyDateTime_TimeZoneType);
6246 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006248 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6249 if (x == NULL)
6250 return NULL;
6251 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006253 /* A 4-year cycle has an extra leap day over what we'd get from
6254 * pasting together 4 single years.
6255 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006256 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006257 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006259 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6260 * get from pasting together 4 100-year cycles.
6261 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006262 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006263 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006265 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6266 * pasting together 25 4-year cycles.
6267 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006268 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006269 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006271 us_per_ms = PyLong_FromLong(1000);
6272 us_per_second = PyLong_FromLong(1000000);
6273 us_per_minute = PyLong_FromLong(60000000);
6274 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006275 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006276 us_per_minute == NULL || seconds_per_day == NULL)
6277 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006279 /* The rest are too big for 32-bit ints, but even
6280 * us_per_week fits in 40 bits, so doubles should be exact.
6281 */
6282 us_per_hour = PyLong_FromDouble(3600000000.0);
6283 us_per_day = PyLong_FromDouble(86400000000.0);
6284 us_per_week = PyLong_FromDouble(604800000000.0);
6285 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6286 return NULL;
6287 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006288}
Tim Petersf3615152003-01-01 21:51:37 +00006289
6290/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006291Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006292 x.n = x stripped of its timezone -- its naive time.
6293 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006294 return None
Tim Petersf3615152003-01-01 21:51:37 +00006295 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006296 return None
Tim Petersf3615152003-01-01 21:51:37 +00006297 x.s = x's standard offset, x.o - x.d
6298
6299Now some derived rules, where k is a duration (timedelta).
6300
63011. x.o = x.s + x.d
6302 This follows from the definition of x.s.
6303
Tim Petersc5dc4da2003-01-02 17:55:03 +000063042. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006305 This is actually a requirement, an assumption we need to make about
6306 sane tzinfo classes.
6307
63083. The naive UTC time corresponding to x is x.n - x.o.
6309 This is again a requirement for a sane tzinfo class.
6310
63114. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006312 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006313
Tim Petersc5dc4da2003-01-02 17:55:03 +000063145. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006315 Again follows from how arithmetic is defined.
6316
Tim Peters8bb5ad22003-01-24 02:44:45 +00006317Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006318(meaning that the various tzinfo methods exist, and don't blow up or return
6319None when called).
6320
Tim Petersa9bc1682003-01-11 03:39:11 +00006321The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006322x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006323
6324By #3, we want
6325
Tim Peters8bb5ad22003-01-24 02:44:45 +00006326 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006327
6328The algorithm starts by attaching tz to x.n, and calling that y. So
6329x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6330becomes true; in effect, we want to solve [2] for k:
6331
Tim Peters8bb5ad22003-01-24 02:44:45 +00006332 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006333
6334By #1, this is the same as
6335
Tim Peters8bb5ad22003-01-24 02:44:45 +00006336 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006337
6338By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6339Substituting that into [3],
6340
Tim Peters8bb5ad22003-01-24 02:44:45 +00006341 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6342 k - (y+k).s - (y+k).d = 0; rearranging,
6343 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6344 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006345
Tim Peters8bb5ad22003-01-24 02:44:45 +00006346On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6347approximate k by ignoring the (y+k).d term at first. Note that k can't be
6348very large, since all offset-returning methods return a duration of magnitude
6349less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6350be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006351
6352In any case, the new value is
6353
Tim Peters8bb5ad22003-01-24 02:44:45 +00006354 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006355
Tim Peters8bb5ad22003-01-24 02:44:45 +00006356It's helpful to step back at look at [4] from a higher level: it's simply
6357mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006358
6359At this point, if
6360
Tim Peters8bb5ad22003-01-24 02:44:45 +00006361 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006362
6363we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006364at the start of daylight time. Picture US Eastern for concreteness. The wall
6365time 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 +00006366sense then. The docs ask that an Eastern tzinfo class consider such a time to
6367be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6368on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006369the only spelling that makes sense on the local wall clock.
6370
Tim Petersc5dc4da2003-01-02 17:55:03 +00006371In fact, if [5] holds at this point, we do have the standard-time spelling,
6372but that takes a bit of proof. We first prove a stronger result. What's the
6373difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006374
Tim Peters8bb5ad22003-01-24 02:44:45 +00006375 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006376
Tim Petersc5dc4da2003-01-02 17:55:03 +00006377Now
6378 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006379 (y + y.s).n = by #5
6380 y.n + y.s = since y.n = x.n
6381 x.n + y.s = since z and y are have the same tzinfo member,
6382 y.s = z.s by #2
6383 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006384
Tim Petersc5dc4da2003-01-02 17:55:03 +00006385Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006386
Tim Petersc5dc4da2003-01-02 17:55:03 +00006387 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006388 x.n - ((x.n + z.s) - z.o) = expanding
6389 x.n - x.n - z.s + z.o = cancelling
6390 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006391 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006392
Tim Petersc5dc4da2003-01-02 17:55:03 +00006393So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006394
Tim Petersc5dc4da2003-01-02 17:55:03 +00006395If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006396spelling we wanted in the endcase described above. We're done. Contrarily,
6397if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006398
Tim Petersc5dc4da2003-01-02 17:55:03 +00006399If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6400add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006401local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006402
Tim Petersc5dc4da2003-01-02 17:55:03 +00006403Let
Tim Petersf3615152003-01-01 21:51:37 +00006404
Tim Peters4fede1a2003-01-04 00:26:59 +00006405 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006406
Tim Peters4fede1a2003-01-04 00:26:59 +00006407and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006408
Tim Peters8bb5ad22003-01-24 02:44:45 +00006409 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006410
Tim Peters8bb5ad22003-01-24 02:44:45 +00006411If so, we're done. If not, the tzinfo class is insane, according to the
6412assumptions we've made. This also requires a bit of proof. As before, let's
6413compute the difference between the LHS and RHS of [8] (and skipping some of
6414the justifications for the kinds of substitutions we've done several times
6415already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006416
Tim Peters8bb5ad22003-01-24 02:44:45 +00006417 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006418 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6419 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6420 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6421 - z.n + z.n - z.o + z'.o = cancel z.n
6422 - z.o + z'.o = #1 twice
6423 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6424 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006425
6426So 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 +00006427we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6428return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006429
Tim Peters8bb5ad22003-01-24 02:44:45 +00006430How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6431a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6432would have to change the result dst() returns: we start in DST, and moving
6433a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006434
Tim Peters8bb5ad22003-01-24 02:44:45 +00006435There isn't a sane case where this can happen. The closest it gets is at
6436the end of DST, where there's an hour in UTC with no spelling in a hybrid
6437tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6438that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6439UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6440time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6441clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6442standard time. Since that's what the local clock *does*, we want to map both
6443UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006444in local time, but so it goes -- it's the way the local clock works.
6445
Tim Peters8bb5ad22003-01-24 02:44:45 +00006446When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6447so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6448z' = 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 +00006449(correctly) concludes that z' is not UTC-equivalent to x.
6450
6451Because we know z.d said z was in daylight time (else [5] would have held and
6452we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006453and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006454return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6455but the reasoning doesn't depend on the example -- it depends on there being
6456two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006457z' must be in standard time, and is the spelling we want in this case.
6458
6459Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6460concerned (because it takes z' as being in standard time rather than the
6461daylight time we intend here), but returning it gives the real-life "local
6462clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6463tz.
6464
6465When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6466the 1:MM standard time spelling we want.
6467
6468So how can this break? One of the assumptions must be violated. Two
6469possibilities:
6470
64711) [2] effectively says that y.s is invariant across all y belong to a given
6472 time zone. This isn't true if, for political reasons or continental drift,
6473 a region decides to change its base offset from UTC.
6474
64752) There may be versions of "double daylight" time where the tail end of
6476 the analysis gives up a step too early. I haven't thought about that
6477 enough to say.
6478
6479In any case, it's clear that the default fromutc() is strong enough to handle
6480"almost all" time zones: so long as the standard offset is invariant, it
6481doesn't matter if daylight time transition points change from year to year, or
6482if daylight time is skipped in some years; it doesn't matter how large or
6483small dst() may get within its bounds; and it doesn't even matter if some
6484perverse time zone returns a negative dst()). So a breaking case must be
6485pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006486--------------------------------------------------------------------------- */