blob: 41b95b919394e039bb9b01db9d7fd8b559eefc75 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
Tim Peters2a799bf2002-12-16 20:18:38 +00006#include "structmember.h"
7
8#include <time.h>
9
Victor Stinner09e5cf22015-03-30 00:09:18 +020010#ifdef MS_WINDOWS
11# include <winsock2.h> /* struct timeval */
12#endif
13
Tim Peters9ddf40b2004-06-20 22:41:32 +000014/* Differentiate between building the core module and building extension
15 * modules.
16 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000017#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000018#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000019#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000020#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000021#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000022
Larry Hastings61272b72014-01-07 12:41:53 -080023/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080024module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080025class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Larry Hastings61272b72014-01-07 12:41:53 -080026[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -080027/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080028
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030029#include "clinic/_datetimemodule.c.h"
30
Tim Peters2a799bf2002-12-16 20:18:38 +000031/* We require that C int be at least 32 bits, and use int virtually
32 * everywhere. In just a few cases we use a temp long, where a Python
33 * API returns a C long. In such cases, we have to ensure that the
34 * final result fits in a C int (this can be an issue on 64-bit boxes).
35 */
36#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000037# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000038#endif
39
40#define MINYEAR 1
41#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000042#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000043
44/* Nine decimal digits is easy to communicate, and leaves enough room
45 * so that two delta days can be added w/o fear of overflowing a signed
46 * 32-bit int, and with plenty of room left over to absorb any possible
47 * carries from adding seconds.
48 */
49#define MAX_DELTA_DAYS 999999999
50
51/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define GET_YEAR PyDateTime_GET_YEAR
53#define GET_MONTH PyDateTime_GET_MONTH
54#define GET_DAY PyDateTime_GET_DAY
55#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
56#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
57#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
58#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040059#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000060
61/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
63 ((o)->data[1] = ((v) & 0x00ff)))
64#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
65#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000066
67/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
69#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
70#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
71#define DATE_SET_MICROSECOND(o, v) \
72 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
73 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
74 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040075#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000076
77/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
79#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
80#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
81#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040082#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
84#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
85#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
86#define TIME_SET_MICROSECOND(o, v) \
87 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
88 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
89 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040090#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000091
92/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
94#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
95#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097#define SET_TD_DAYS(o, v) ((o)->days = (v))
98#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000099#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
100
Tim Petersa032d2e2003-01-11 00:15:54 +0000101/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
102 * p->hastzinfo.
103 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000104#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
105#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
106 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
107#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
108 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000109/* M is a char or int claiming to be a valid month. The macro is equivalent
110 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000112 */
113#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
114
Tim Peters2a799bf2002-12-16 20:18:38 +0000115/* Forward declarations. */
116static PyTypeObject PyDateTime_DateType;
117static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000118static PyTypeObject PyDateTime_DeltaType;
119static PyTypeObject PyDateTime_TimeType;
120static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000121static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000122
Victor Stinnerb67f0962017-02-10 10:34:02 +0100123static int check_tzinfo_subclass(PyObject *p);
124
Martin v. Löwise75fc142013-11-07 18:46:53 +0100125_Py_IDENTIFIER(as_integer_ratio);
126_Py_IDENTIFIER(fromutc);
127_Py_IDENTIFIER(isoformat);
128_Py_IDENTIFIER(strftime);
129
Tim Peters2a799bf2002-12-16 20:18:38 +0000130/* ---------------------------------------------------------------------------
131 * Math utilities.
132 */
133
134/* k = i+j overflows iff k differs in sign from both inputs,
135 * iff k^i has sign bit set and k^j has sign bit set,
136 * iff (k^i)&(k^j) has sign bit set.
137 */
138#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000140
141/* Compute Python divmod(x, y), returning the quotient and storing the
142 * remainder into *r. The quotient is the floor of x/y, and that's
143 * the real point of this. C will probably truncate instead (C99
144 * requires truncation; C89 left it implementation-defined).
145 * Simplification: we *require* that y > 0 here. That's appropriate
146 * for all the uses made of it. This simplifies the code and makes
147 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
148 * overflow case).
149 */
150static int
151divmod(int x, int y, int *r)
152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 assert(y > 0);
156 quo = x / y;
157 *r = x - quo * y;
158 if (*r < 0) {
159 --quo;
160 *r += y;
161 }
162 assert(0 <= *r && *r < y);
163 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000164}
165
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000166/* Nearest integer to m / n for integers m and n. Half-integer results
167 * are rounded to even.
168 */
169static PyObject *
170divide_nearest(PyObject *m, PyObject *n)
171{
172 PyObject *result;
173 PyObject *temp;
174
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000175 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000176 if (temp == NULL)
177 return NULL;
178 result = PyTuple_GET_ITEM(temp, 0);
179 Py_INCREF(result);
180 Py_DECREF(temp);
181
182 return result;
183}
184
Tim Peters2a799bf2002-12-16 20:18:38 +0000185/* ---------------------------------------------------------------------------
186 * General calendrical helper functions
187 */
188
189/* For each month ordinal in 1..12, the number of days in that month,
190 * and the number of days before that month in the same year. These
191 * are correct for non-leap years only.
192 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200193static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 0, /* unused; this vector uses 1-based indexing */
195 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000196};
197
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200198static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 0, /* unused; this vector uses 1-based indexing */
200 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000201};
202
203/* year -> 1 if leap year, else 0. */
204static int
205is_leap(int year)
206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* Cast year to unsigned. The result is the same either way, but
208 * C can generate faster code for unsigned mod than for signed
209 * mod (especially for % 4 -- a good compiler should just grab
210 * the last 2 bits when the LHS is unsigned).
211 */
212 const unsigned int ayear = (unsigned int)year;
213 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000214}
215
216/* year, month -> number of days in that month in that year */
217static int
218days_in_month(int year, int month)
219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 assert(month >= 1);
221 assert(month <= 12);
222 if (month == 2 && is_leap(year))
223 return 29;
224 else
225 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000226}
227
Martin Panter46f50722016-05-26 05:35:26 +0000228/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000229static int
230days_before_month(int year, int month)
231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 assert(month >= 1);
235 assert(month <= 12);
236 days = _days_before_month[month];
237 if (month > 2 && is_leap(year))
238 ++days;
239 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000240}
241
242/* year -> number of days before January 1st of year. Remember that we
243 * start with year 1, so days_before_year(1) == 0.
244 */
245static int
246days_before_year(int year)
247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 int y = year - 1;
249 /* This is incorrect if year <= 0; we really want the floor
250 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000251 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000253 assert (year >= 1);
254 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000255}
256
257/* Number of days in 4, 100, and 400 year cycles. That these have
258 * the correct values is asserted in the module init function.
259 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260#define DI4Y 1461 /* days_before_year(5); days in 4 years */
261#define DI100Y 36524 /* days_before_year(101); days in 100 years */
262#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000263
264/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
265static void
266ord_to_ymd(int ordinal, int *year, int *month, int *day)
267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
271 * leap years repeats exactly every 400 years. The basic strategy is
272 * to find the closest 400-year boundary at or before ordinal, then
273 * work with the offset from that boundary to ordinal. Life is much
274 * clearer if we subtract 1 from ordinal first -- then the values
275 * of ordinal at 400-year boundaries are exactly those divisible
276 * by DI400Y:
277 *
278 * D M Y n n-1
279 * -- --- ---- ---------- ----------------
280 * 31 Dec -400 -DI400Y -DI400Y -1
281 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
282 * ...
283 * 30 Dec 000 -1 -2
284 * 31 Dec 000 0 -1
285 * 1 Jan 001 1 0 400-year boundary
286 * 2 Jan 001 2 1
287 * 3 Jan 001 3 2
288 * ...
289 * 31 Dec 400 DI400Y DI400Y -1
290 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
291 */
292 assert(ordinal >= 1);
293 --ordinal;
294 n400 = ordinal / DI400Y;
295 n = ordinal % DI400Y;
296 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 /* Now n is the (non-negative) offset, in days, from January 1 of
299 * year, to the desired date. Now compute how many 100-year cycles
300 * precede n.
301 * Note that it's possible for n100 to equal 4! In that case 4 full
302 * 100-year cycles precede the desired day, which implies the
303 * desired day is December 31 at the end of a 400-year cycle.
304 */
305 n100 = n / DI100Y;
306 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 /* Now compute how many 4-year cycles precede it. */
309 n4 = n / DI4Y;
310 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 /* And now how many single years. Again n1 can be 4, and again
313 * meaning that the desired day is December 31 at the end of the
314 * 4-year cycle.
315 */
316 n1 = n / 365;
317 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 *year += n100 * 100 + n4 * 4 + n1;
320 if (n1 == 4 || n100 == 4) {
321 assert(n == 0);
322 *year -= 1;
323 *month = 12;
324 *day = 31;
325 return;
326 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 /* Now the year is correct, and n is the offset from January 1. We
329 * find the month via an estimate that's either exact or one too
330 * large.
331 */
332 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
333 assert(leapyear == is_leap(*year));
334 *month = (n + 50) >> 5;
335 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
336 if (preceding > n) {
337 /* estimate is too large */
338 *month -= 1;
339 preceding -= days_in_month(*year, *month);
340 }
341 n -= preceding;
342 assert(0 <= n);
343 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000346}
347
348/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
349static int
350ymd_to_ord(int year, int month, int day)
351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000353}
354
355/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
356static int
357weekday(int year, int month, int day)
358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000360}
361
362/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
363 * first calendar week containing a Thursday.
364 */
365static int
366iso_week1_monday(int year)
367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
369 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
370 int first_weekday = (first_day + 6) % 7;
371 /* ordinal of closest Monday at or before 1/1 */
372 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
375 week1_monday += 7;
376 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000377}
378
379/* ---------------------------------------------------------------------------
380 * Range checkers.
381 */
382
383/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
384 * If not, raise OverflowError and return -1.
385 */
386static int
387check_delta_day_range(int days)
388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
390 return 0;
391 PyErr_Format(PyExc_OverflowError,
392 "days=%d; must have magnitude <= %d",
393 days, MAX_DELTA_DAYS);
394 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000395}
396
397/* Check that date arguments are in range. Return 0 if they are. If they
398 * aren't, raise ValueError and return -1.
399 */
400static int
401check_date_args(int year, int month, int day)
402{
403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 if (year < MINYEAR || year > MAXYEAR) {
Victor Stinnerb67f0962017-02-10 10:34:02 +0100405 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 return -1;
407 }
408 if (month < 1 || month > 12) {
409 PyErr_SetString(PyExc_ValueError,
410 "month must be in 1..12");
411 return -1;
412 }
413 if (day < 1 || day > days_in_month(year, month)) {
414 PyErr_SetString(PyExc_ValueError,
415 "day is out of range for month");
416 return -1;
417 }
418 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000419}
420
421/* Check that time arguments are in range. Return 0 if they are. If they
422 * aren't, raise ValueError and return -1.
423 */
424static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400425check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 if (h < 0 || h > 23) {
428 PyErr_SetString(PyExc_ValueError,
429 "hour must be in 0..23");
430 return -1;
431 }
432 if (m < 0 || m > 59) {
433 PyErr_SetString(PyExc_ValueError,
434 "minute must be in 0..59");
435 return -1;
436 }
437 if (s < 0 || s > 59) {
438 PyErr_SetString(PyExc_ValueError,
439 "second must be in 0..59");
440 return -1;
441 }
442 if (us < 0 || us > 999999) {
443 PyErr_SetString(PyExc_ValueError,
444 "microsecond must be in 0..999999");
445 return -1;
446 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400447 if (fold != 0 && fold != 1) {
448 PyErr_SetString(PyExc_ValueError,
449 "fold must be either 0 or 1");
450 return -1;
451 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000453}
454
455/* ---------------------------------------------------------------------------
456 * Normalization utilities.
457 */
458
459/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
460 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
461 * at least factor, enough of *lo is converted into "hi" units so that
462 * 0 <= *lo < factor. The input values must be such that int overflow
463 * is impossible.
464 */
465static void
466normalize_pair(int *hi, int *lo, int factor)
467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 assert(factor > 0);
469 assert(lo != hi);
470 if (*lo < 0 || *lo >= factor) {
471 const int num_hi = divmod(*lo, factor, lo);
472 const int new_hi = *hi + num_hi;
473 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
474 *hi = new_hi;
475 }
476 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000477}
478
479/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 * 0 <= *s < 24*3600
481 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000482 * The input values must be such that the internals don't overflow.
483 * The way this routine is used, we don't get close.
484 */
485static void
486normalize_d_s_us(int *d, int *s, int *us)
487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 if (*us < 0 || *us >= 1000000) {
489 normalize_pair(s, us, 1000000);
490 /* |s| can't be bigger than about
491 * |original s| + |original us|/1000000 now.
492 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 }
495 if (*s < 0 || *s >= 24*3600) {
496 normalize_pair(d, s, 24*3600);
497 /* |d| can't be bigger than about
498 * |original d| +
499 * (|original s| + |original us|/1000000) / (24*3600) now.
500 */
501 }
502 assert(0 <= *s && *s < 24*3600);
503 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000504}
505
506/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 * 1 <= *m <= 12
508 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000509 * The input values must be such that the internals don't overflow.
510 * The way this routine is used, we don't get close.
511 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000512static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000513normalize_y_m_d(int *y, int *m, int *d)
514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000516
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000517 /* In actual use, m is always the month component extracted from a
518 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 /* Now only day can be out of bounds (year may also be out of bounds
524 * for a datetime object, but we don't care about that here).
525 * If day is out of bounds, what to do is arguable, but at least the
526 * method here is principled and explainable.
527 */
528 dim = days_in_month(*y, *m);
529 if (*d < 1 || *d > dim) {
530 /* Move day-1 days from the first of the month. First try to
531 * get off cheap if we're only one day out of range
532 * (adjustments for timezone alone can't be worse than that).
533 */
534 if (*d == 0) {
535 --*m;
536 if (*m > 0)
537 *d = days_in_month(*y, *m);
538 else {
539 --*y;
540 *m = 12;
541 *d = 31;
542 }
543 }
544 else if (*d == dim + 1) {
545 /* move forward a day */
546 ++*m;
547 *d = 1;
548 if (*m > 12) {
549 *m = 1;
550 ++*y;
551 }
552 }
553 else {
554 int ordinal = ymd_to_ord(*y, *m, 1) +
555 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000556 if (ordinal < 1 || ordinal > MAXORDINAL) {
557 goto error;
558 } else {
559 ord_to_ymd(ordinal, y, m, d);
560 return 0;
561 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 }
563 }
564 assert(*m > 0);
565 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000566 if (MINYEAR <= *y && *y <= MAXYEAR)
567 return 0;
568 error:
569 PyErr_SetString(PyExc_OverflowError,
570 "date value out of range");
571 return -1;
572
Tim Peters2a799bf2002-12-16 20:18:38 +0000573}
574
575/* Fiddle out-of-bounds months and days so that the result makes some kind
576 * of sense. The parameters are both inputs and outputs. Returns < 0 on
577 * failure, where failure means the adjusted year is out of bounds.
578 */
579static int
580normalize_date(int *year, int *month, int *day)
581{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000582 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000583}
584
585/* Force all the datetime fields into range. The parameters are both
586 * inputs and outputs. Returns < 0 on error.
587 */
588static int
589normalize_datetime(int *year, int *month, int *day,
590 int *hour, int *minute, int *second,
591 int *microsecond)
592{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 normalize_pair(second, microsecond, 1000000);
594 normalize_pair(minute, second, 60);
595 normalize_pair(hour, minute, 60);
596 normalize_pair(day, hour, 24);
597 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000598}
599
600/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000601 * Basic object allocation: tp_alloc implementations. These allocate
602 * Python objects of the right size and type, and do the Python object-
603 * initialization bit. If there's not enough memory, they return NULL after
604 * setting MemoryError. All data members remain uninitialized trash.
605 *
606 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000607 * member is needed. This is ugly, imprecise, and possibly insecure.
608 * tp_basicsize for the time and datetime types is set to the size of the
609 * struct that has room for the tzinfo member, so subclasses in Python will
610 * allocate enough space for a tzinfo member whether or not one is actually
611 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
612 * part is that PyType_GenericAlloc() (which subclasses in Python end up
613 * using) just happens today to effectively ignore the nitems argument
614 * when tp_itemsize is 0, which it is for these type objects. If that
615 * changes, perhaps the callers of tp_alloc slots in this file should
616 * be changed to force a 0 nitems argument unless the type being allocated
617 * is a base type implemented in this file (so that tp_alloc is time_alloc
618 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000619 */
620
621static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000622time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 self = (PyObject *)
627 PyObject_MALLOC(aware ?
628 sizeof(PyDateTime_Time) :
629 sizeof(_PyDateTime_BaseTime));
630 if (self == NULL)
631 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100632 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000634}
635
636static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000637datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 self = (PyObject *)
642 PyObject_MALLOC(aware ?
643 sizeof(PyDateTime_DateTime) :
644 sizeof(_PyDateTime_BaseDateTime));
645 if (self == NULL)
646 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100647 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000649}
650
651/* ---------------------------------------------------------------------------
652 * Helpers for setting object fields. These work on pointers to the
653 * appropriate base class.
654 */
655
656/* For date and datetime. */
657static void
658set_date_fields(PyDateTime_Date *self, int y, int m, int d)
659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 self->hashcode = -1;
661 SET_YEAR(self, y);
662 SET_MONTH(self, m);
663 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000664}
665
666/* ---------------------------------------------------------------------------
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500667 * String parsing utilities and helper functions
668 */
669
670static const char*
671parse_digits(const char* ptr, int* var, size_t num_digits)
672{
673 for (size_t i = 0; i < num_digits; ++i) {
674 unsigned int tmp = (unsigned int)(*(ptr++) - '0');
675 if (tmp > 9) {
676 return NULL;
677 }
678 *var *= 10;
679 *var += (signed int)tmp;
680 }
681
682 return ptr;
683}
684
685static int parse_isoformat_date(const char *dtstr,
686 int* year, int *month, int* day) {
687 /* Parse the date components of the result of date.isoformat()
688 *
689 * Return codes:
690 * 0: Success
691 * -1: Failed to parse date component
692 * -2: Failed to parse dateseparator
693 */
694 const char *p = dtstr;
695 p = parse_digits(p, year, 4);
696 if (NULL == p) {
697 return -1;
698 }
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100699
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500700 if (*(p++) != '-') {
701 return -2;
702 }
703
704 p = parse_digits(p, month, 2);
705 if (NULL == p) {
706 return -1;
707 }
708
709 if (*(p++) != '-') {
710 return -2;
711 }
712
713 p = parse_digits(p, day, 2);
714 if (p == NULL) {
715 return -1;
716 }
717
718 return 0;
719}
720
721static int
722parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end,
723 int* hour, int* minute, int *second, int *microsecond) {
724 const char *p = tstr;
725 const char *p_end = tstr_end;
726 int *vals[3] = {hour, minute, second};
727
728 // Parse [HH[:MM[:SS]]]
729 for (size_t i = 0; i < 3; ++i) {
730 p = parse_digits(p, vals[i], 2);
731 if (NULL == p) {
732 return -3;
733 }
734
735 char c = *(p++);
736 if (p >= p_end) {
737 return c != '\0';
738 } else if (c == ':') {
739 continue;
740 } else if (c == '.') {
741 break;
742 } else {
743 return -4; // Malformed time separator
744 }
745 }
746
747 // Parse .fff[fff]
748 size_t len_remains = p_end - p;
749 if (!(len_remains == 6 || len_remains == 3)) {
750 return -3;
751 }
752
753 p = parse_digits(p, microsecond, len_remains);
754 if (NULL == p) {
755 return -3;
756 }
757
758 if (len_remains == 3) {
759 *microsecond *= 1000;
760 }
761
762 // Return 1 if it's not the end of the string
763 return *p != '\0';
764}
765
766static int
767parse_isoformat_time(const char *dtstr, size_t dtlen,
768 int* hour, int *minute, int *second, int *microsecond,
769 int* tzoffset, int *tzmicrosecond) {
770 // Parse the time portion of a datetime.isoformat() string
771 //
772 // Return codes:
773 // 0: Success (no tzoffset)
774 // 1: Success (with tzoffset)
775 // -3: Failed to parse time component
776 // -4: Failed to parse time separator
777 // -5: Malformed timezone string
778
779 const char *p = dtstr;
780 const char *p_end = dtstr + dtlen;
781
782 const char *tzinfo_pos = p;
783 do {
784 if (*tzinfo_pos == '+' || *tzinfo_pos == '-') {
785 break;
786 }
787 } while(++tzinfo_pos < p_end);
788
789 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos,
790 hour, minute, second, microsecond);
791
792 if (rv < 0) {
793 return rv;
794 } else if (tzinfo_pos == p_end) {
795 // We know that there's no time zone, so if there's stuff at the
796 // end of the string it's an error.
797 if (rv == 1) {
798 return -5;
799 } else {
800 return 0;
801 }
802 }
803
804 // Parse time zone component
805 // Valid formats are:
806 // - +HH:MM (len 6)
807 // - +HH:MM:SS (len 9)
808 // - +HH:MM:SS.ffffff (len 16)
809 size_t tzlen = p_end - tzinfo_pos;
810 if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) {
811 return -5;
812 }
813
814 int tzsign = (*tzinfo_pos == '-')?-1:1;
815 tzinfo_pos++;
816 int tzhour = 0, tzminute = 0, tzsecond = 0;
817 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end,
818 &tzhour, &tzminute, &tzsecond, tzmicrosecond);
819
820 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
821 *tzmicrosecond *= tzsign;
822
823 return rv?-5:1;
824}
825
826
827/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000828 * Create various objects, mostly without range checking.
829 */
830
831/* Create a date instance with no range checking. */
832static PyObject *
833new_date_ex(int year, int month, int day, PyTypeObject *type)
834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000836
Victor Stinnerb67f0962017-02-10 10:34:02 +0100837 if (check_date_args(year, month, day) < 0) {
838 return NULL;
839 }
840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
842 if (self != NULL)
843 set_date_fields(self, year, month, day);
844 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000845}
846
847#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000849
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500850// Forward declaration
851static PyObject * new_datetime_ex(int, int, int, int, int, int, int,
852 PyObject*, PyTypeObject*);
853
854/* Create date instance with no range checking, or call subclass constructor */
855static PyObject *
856new_date_subclass_ex(int year, int month, int day, PyObject *cls) {
857 PyObject *result;
858 // We have "fast path" constructors for two subclasses: date and datetime
859 if ((PyTypeObject *)cls == &PyDateTime_DateType) {
860 result = new_date_ex(year, month, day, (PyTypeObject *)cls);
861 } else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
862 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
863 (PyTypeObject *)cls);
864 } else {
865 result = PyObject_CallFunction(cls, "iii", year, month, day);
866 }
867
868 return result;
869}
870
Tim Petersb0c854d2003-05-17 15:57:00 +0000871/* Create a datetime instance with no range checking. */
872static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400873new_datetime_ex2(int year, int month, int day, int hour, int minute,
874 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 PyDateTime_DateTime *self;
877 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000878
Victor Stinnerb67f0962017-02-10 10:34:02 +0100879 if (check_date_args(year, month, day) < 0) {
880 return NULL;
881 }
882 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
883 return NULL;
884 }
885 if (check_tzinfo_subclass(tzinfo) < 0) {
886 return NULL;
887 }
888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
890 if (self != NULL) {
891 self->hastzinfo = aware;
892 set_date_fields((PyDateTime_Date *)self, year, month, day);
893 DATE_SET_HOUR(self, hour);
894 DATE_SET_MINUTE(self, minute);
895 DATE_SET_SECOND(self, second);
896 DATE_SET_MICROSECOND(self, usecond);
897 if (aware) {
898 Py_INCREF(tzinfo);
899 self->tzinfo = tzinfo;
900 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400901 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 }
903 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000904}
905
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400906static PyObject *
907new_datetime_ex(int year, int month, int day, int hour, int minute,
908 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
909{
910 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
911 tzinfo, 0, type);
912}
913
914#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
915 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000917
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500918static PyObject *
919new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
920 int second, int usecond, PyObject *tzinfo,
921 int fold, PyObject *cls) {
922 PyObject* dt;
923 if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) {
924 // Use the fast path constructor
925 dt = new_datetime(year, month, day, hour, minute, second, usecond,
926 tzinfo, fold);
927 } else {
928 // Subclass
929 dt = PyObject_CallFunction(cls, "iiiiiiiO",
930 year,
931 month,
932 day,
933 hour,
934 minute,
935 second,
936 usecond,
937 tzinfo);
938 }
939
940 return dt;
941}
942
943static PyObject *
944new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
945 int second, int usecond, PyObject *tzinfo,
946 PyObject *cls) {
947 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
948 second, usecond, tzinfo, 0,
949 cls);
950}
951
Tim Petersb0c854d2003-05-17 15:57:00 +0000952/* Create a time instance with no range checking. */
953static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400954new_time_ex2(int hour, int minute, int second, int usecond,
955 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 PyDateTime_Time *self;
958 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000959
Victor Stinnerb67f0962017-02-10 10:34:02 +0100960 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
961 return NULL;
962 }
963 if (check_tzinfo_subclass(tzinfo) < 0) {
964 return NULL;
965 }
966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
968 if (self != NULL) {
969 self->hastzinfo = aware;
970 self->hashcode = -1;
971 TIME_SET_HOUR(self, hour);
972 TIME_SET_MINUTE(self, minute);
973 TIME_SET_SECOND(self, second);
974 TIME_SET_MICROSECOND(self, usecond);
975 if (aware) {
976 Py_INCREF(tzinfo);
977 self->tzinfo = tzinfo;
978 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400979 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 }
981 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000982}
983
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400984static PyObject *
985new_time_ex(int hour, int minute, int second, int usecond,
986 PyObject *tzinfo, PyTypeObject *type)
987{
988 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
989}
990
991#define new_time(hh, mm, ss, us, tzinfo, fold) \
992 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000993
994/* Create a timedelta instance. Normalize the members iff normalize is
995 * true. Passing false is a speed optimization, if you know for sure
996 * that seconds and microseconds are already in their proper ranges. In any
997 * case, raises OverflowError and returns NULL if the normalized days is out
998 * of range).
999 */
1000static PyObject *
1001new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +00001003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 if (normalize)
1007 normalize_d_s_us(&days, &seconds, &microseconds);
1008 assert(0 <= seconds && seconds < 24*3600);
1009 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +00001010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 if (check_delta_day_range(days) < 0)
1012 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1015 if (self != NULL) {
1016 self->hashcode = -1;
1017 SET_TD_DAYS(self, days);
1018 SET_TD_SECONDS(self, seconds);
1019 SET_TD_MICROSECONDS(self, microseconds);
1020 }
1021 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001022}
1023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024#define new_delta(d, s, us, normalize) \
1025 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001026
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001027
1028typedef struct
1029{
1030 PyObject_HEAD
1031 PyObject *offset;
1032 PyObject *name;
1033} PyDateTime_TimeZone;
1034
Victor Stinner6ced7c42011-03-21 18:15:42 +01001035/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001036static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -04001037/* The interned Epoch datetime instance */
1038static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00001039
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001040/* Create new timezone instance checking offset range. This
1041 function does not check the name argument. Caller must assure
1042 that offset is a timedelta instance and name is either NULL
1043 or a unicode object. */
1044static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001045create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001046{
1047 PyDateTime_TimeZone *self;
1048 PyTypeObject *type = &PyDateTime_TimeZoneType;
1049
1050 assert(offset != NULL);
1051 assert(PyDelta_Check(offset));
1052 assert(name == NULL || PyUnicode_Check(name));
1053
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001054 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1055 if (self == NULL) {
1056 return NULL;
1057 }
1058 Py_INCREF(offset);
1059 self->offset = offset;
1060 Py_XINCREF(name);
1061 self->name = name;
1062 return (PyObject *)self;
1063}
1064
1065static int delta_bool(PyDateTime_Delta *self);
1066
1067static PyObject *
1068new_timezone(PyObject *offset, PyObject *name)
1069{
1070 assert(offset != NULL);
1071 assert(PyDelta_Check(offset));
1072 assert(name == NULL || PyUnicode_Check(name));
1073
1074 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
1075 Py_INCREF(PyDateTime_TimeZone_UTC);
1076 return PyDateTime_TimeZone_UTC;
1077 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001078 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1079 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1080 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1081 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04001082 " timedelta(hours=24),"
1083 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001084 return NULL;
1085 }
1086
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001087 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001088}
1089
Tim Petersb0c854d2003-05-17 15:57:00 +00001090/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001091 * tzinfo helpers.
1092 */
1093
Tim Peters855fe882002-12-22 03:43:39 +00001094/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
1095 * raise TypeError and return -1.
1096 */
1097static int
1098check_tzinfo_subclass(PyObject *p)
1099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 if (p == Py_None || PyTZInfo_Check(p))
1101 return 0;
1102 PyErr_Format(PyExc_TypeError,
1103 "tzinfo argument must be None or of a tzinfo subclass, "
1104 "not type '%s'",
1105 Py_TYPE(p)->tp_name);
1106 return -1;
Tim Peters855fe882002-12-22 03:43:39 +00001107}
1108
Tim Peters2a799bf2002-12-16 20:18:38 +00001109/* If self has a tzinfo member, return a BORROWED reference to it. Else
1110 * return NULL, which is NOT AN ERROR. There are no error returns here,
1111 * and the caller must not decref the result.
1112 */
1113static PyObject *
1114get_tzinfo_member(PyObject *self)
1115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 if (PyDateTime_Check(self) && HASTZINFO(self))
1119 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1120 else if (PyTime_Check(self) && HASTZINFO(self))
1121 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001124}
1125
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001126/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
1127 * be an instance of the tzinfo class. If the method returns None, this
1128 * returns None. If the method doesn't return None or timedelta, TypeError is
1129 * raised and this returns NULL. If it returns a timedelta and the value is
1130 * out of range or isn't a whole number of minutes, ValueError is raised and
1131 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +00001132 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001133static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001134call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001135{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001136 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001139 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001141
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001142 if (tzinfo == Py_None)
1143 Py_RETURN_NONE;
1144 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1145 if (offset == Py_None || offset == NULL)
1146 return offset;
1147 if (PyDelta_Check(offset)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001148 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1149 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1150 Py_DECREF(offset);
1151 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1152 " strictly between -timedelta(hours=24) and"
1153 " timedelta(hours=24).");
1154 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 }
1156 }
1157 else {
1158 PyErr_Format(PyExc_TypeError,
1159 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001160 "timedelta, not '%.200s'",
1161 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07001162 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001163 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001165
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001166 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001167}
1168
1169/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1170 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
1171 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +00001172 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001173 * If utcoffset() returns an out of range timedelta,
1174 * ValueError is raised and this returns -1. Else *none is
1175 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001176 */
Tim Peters855fe882002-12-22 03:43:39 +00001177static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001178call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1179{
1180 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001181}
1182
Tim Peters2a799bf2002-12-16 20:18:38 +00001183/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1184 * result. tzinfo must be an instance of the tzinfo class. If dst()
1185 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001186 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00001187 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +00001188 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001189 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001190 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001191static PyObject *
1192call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001193{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001194 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001195}
1196
Tim Petersbad8ff02002-12-30 20:52:32 +00001197/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +00001198 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001199 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001200 * returns NULL. If the result is a string, we ensure it is a Unicode
1201 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001202 */
1203static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001204call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001207 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 assert(tzinfo != NULL);
1210 assert(check_tzinfo_subclass(tzinfo) >= 0);
1211 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001214 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001215
Victor Stinner20401de2016-12-09 15:24:31 +01001216 result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname,
1217 tzinfoarg, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001218
1219 if (result == NULL || result == Py_None)
1220 return result;
1221
1222 if (!PyUnicode_Check(result)) {
1223 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1224 "return None or a string, not '%s'",
1225 Py_TYPE(result)->tp_name);
1226 Py_DECREF(result);
1227 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001229
1230 return result;
Tim Peters00237032002-12-27 02:21:51 +00001231}
1232
Tim Peters2a799bf2002-12-16 20:18:38 +00001233/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1234 * stuff
1235 * ", tzinfo=" + repr(tzinfo)
1236 * before the closing ")".
1237 */
1238static PyObject *
1239append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 assert(PyUnicode_Check(repr));
1244 assert(tzinfo);
1245 if (tzinfo == Py_None)
1246 return repr;
1247 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001248 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1249 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 Py_DECREF(repr);
1251 if (temp == NULL)
1252 return NULL;
1253 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1254 Py_DECREF(temp);
1255 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001256}
1257
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001258/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1259 * stuff
1260 * ", fold=" + repr(tzinfo)
1261 * before the closing ")".
1262 */
1263static PyObject *
1264append_keyword_fold(PyObject *repr, int fold)
1265{
1266 PyObject *temp;
1267
1268 assert(PyUnicode_Check(repr));
1269 if (fold == 0)
1270 return repr;
1271 /* Get rid of the trailing ')'. */
1272 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1273 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1274 Py_DECREF(repr);
1275 if (temp == NULL)
1276 return NULL;
1277 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1278 Py_DECREF(temp);
1279 return repr;
1280}
1281
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001282static inline PyObject *
1283tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) {
1284 PyObject *tzinfo;
1285 if (rv == 1) {
1286 // Create a timezone from offset in seconds (0 returns UTC)
1287 if (tzoffset == 0) {
1288 Py_INCREF(PyDateTime_TimeZone_UTC);
1289 return PyDateTime_TimeZone_UTC;
1290 }
1291
1292 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
Miss Islington (bot)c7f54352018-08-24 12:13:57 -04001293 if (delta == NULL) {
1294 return NULL;
1295 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001296 tzinfo = new_timezone(delta, NULL);
Miss Islington (bot)c7f54352018-08-24 12:13:57 -04001297 Py_DECREF(delta);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001298 } else {
1299 tzinfo = Py_None;
1300 Py_INCREF(Py_None);
1301 }
1302
1303 return tzinfo;
1304}
1305
Tim Peters2a799bf2002-12-16 20:18:38 +00001306/* ---------------------------------------------------------------------------
1307 * String format helpers.
1308 */
1309
1310static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001311format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001312{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001313 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1315 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001316 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1318 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1319 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1324 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1325 GET_DAY(date), hours, minutes, seconds,
1326 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001327}
1328
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001329static PyObject *delta_negative(PyDateTime_Delta *self);
1330
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001331/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001332 * buflen bytes remaining. The UTC offset is gotten by calling
1333 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1334 * *buf, and that's all. Else the returned value is checked for sanity (an
1335 * integer in range), and if that's OK it's converted to an hours & minutes
1336 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001337 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001338 * Returns 0 if everything is OK. If the return value from utcoffset() is
1339 * bogus, an appropriate exception is set and -1 is returned.
1340 */
1341static int
Tim Peters328fff72002-12-20 01:31:27 +00001342format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001344{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001345 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001346 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001350
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001351 offset = call_utcoffset(tzinfo, tzinfoarg);
1352 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001354 if (offset == Py_None) {
1355 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 *buf = '\0';
1357 return 0;
1358 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001359 /* Offset is normalized, so it is negative if days < 0 */
1360 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001362 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001363 if (offset == NULL)
1364 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001366 else {
1367 sign = '+';
1368 }
1369 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001370 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001371 seconds = GET_TD_SECONDS(offset);
1372 Py_DECREF(offset);
1373 minutes = divmod(seconds, 60, &seconds);
1374 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001375 if (microseconds) {
1376 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1377 hours, sep, minutes, sep, seconds, microseconds);
1378 return 0;
1379 }
1380 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001381 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1382 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001383 return 0;
1384 }
1385 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001387}
1388
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001389static PyObject *
1390make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 PyObject *temp;
1393 PyObject *tzinfo = get_tzinfo_member(object);
1394 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001395 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 if (Zreplacement == NULL)
1398 return NULL;
1399 if (tzinfo == Py_None || tzinfo == NULL)
1400 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 assert(tzinfoarg != NULL);
1403 temp = call_tzname(tzinfo, tzinfoarg);
1404 if (temp == NULL)
1405 goto Error;
1406 if (temp == Py_None) {
1407 Py_DECREF(temp);
1408 return Zreplacement;
1409 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 assert(PyUnicode_Check(temp));
1412 /* Since the tzname is getting stuffed into the
1413 * format, we have to double any % signs so that
1414 * strftime doesn't treat them as format codes.
1415 */
1416 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001417 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 Py_DECREF(temp);
1419 if (Zreplacement == NULL)
1420 return NULL;
1421 if (!PyUnicode_Check(Zreplacement)) {
1422 PyErr_SetString(PyExc_TypeError,
1423 "tzname.replace() did not return a string");
1424 goto Error;
1425 }
1426 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001427
1428 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 Py_DECREF(Zreplacement);
1430 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001431}
1432
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001433static PyObject *
1434make_freplacement(PyObject *object)
1435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 char freplacement[64];
1437 if (PyTime_Check(object))
1438 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1439 else if (PyDateTime_Check(object))
1440 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1441 else
1442 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001445}
1446
Tim Peters2a799bf2002-12-16 20:18:38 +00001447/* I sure don't want to reproduce the strftime code from the time module,
1448 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001449 * giving special meanings to the %z, %Z and %f format codes via a
1450 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001451 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1452 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001453 */
1454static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001455wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1461 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1462 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 const char *pin; /* pointer to next char in input format */
1465 Py_ssize_t flen; /* length of input format */
1466 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 PyObject *newfmt = NULL; /* py string, the output format */
1469 char *pnew; /* pointer to available byte in output format */
1470 size_t totalnew; /* number bytes total in output format buffer,
1471 exclusive of trailing \0 */
1472 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 const char *ptoappend; /* ptr to string to append to output buffer */
1475 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 assert(object && format && timetuple);
1478 assert(PyUnicode_Check(format));
1479 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001480 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 if (!pin)
1482 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 /* Scan the input format, looking for %z/%Z/%f escapes, building
1485 * a new format. Since computing the replacements for those codes
1486 * is expensive, don't unless they're actually used.
1487 */
1488 if (flen > INT_MAX - 1) {
1489 PyErr_NoMemory();
1490 goto Done;
1491 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 totalnew = flen + 1; /* realistic if no %z/%Z */
1494 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1495 if (newfmt == NULL) goto Done;
1496 pnew = PyBytes_AsString(newfmt);
1497 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 while ((ch = *pin++) != '\0') {
1500 if (ch != '%') {
1501 ptoappend = pin - 1;
1502 ntoappend = 1;
1503 }
1504 else if ((ch = *pin++) == '\0') {
1505 /* There's a lone trailing %; doesn't make sense. */
1506 PyErr_SetString(PyExc_ValueError, "strftime format "
1507 "ends with raw %");
1508 goto Done;
1509 }
1510 /* A % has been seen and ch is the character after it. */
1511 else if (ch == 'z') {
1512 if (zreplacement == NULL) {
1513 /* format utcoffset */
1514 char buf[100];
1515 PyObject *tzinfo = get_tzinfo_member(object);
1516 zreplacement = PyBytes_FromStringAndSize("", 0);
1517 if (zreplacement == NULL) goto Done;
1518 if (tzinfo != Py_None && tzinfo != NULL) {
1519 assert(tzinfoarg != NULL);
1520 if (format_utcoffset(buf,
1521 sizeof(buf),
1522 "",
1523 tzinfo,
1524 tzinfoarg) < 0)
1525 goto Done;
1526 Py_DECREF(zreplacement);
1527 zreplacement =
1528 PyBytes_FromStringAndSize(buf,
1529 strlen(buf));
1530 if (zreplacement == NULL)
1531 goto Done;
1532 }
1533 }
1534 assert(zreplacement != NULL);
1535 ptoappend = PyBytes_AS_STRING(zreplacement);
1536 ntoappend = PyBytes_GET_SIZE(zreplacement);
1537 }
1538 else if (ch == 'Z') {
1539 /* format tzname */
1540 if (Zreplacement == NULL) {
1541 Zreplacement = make_Zreplacement(object,
1542 tzinfoarg);
1543 if (Zreplacement == NULL)
1544 goto Done;
1545 }
1546 assert(Zreplacement != NULL);
1547 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001548 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001550 if (ptoappend == NULL)
1551 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 }
1553 else if (ch == 'f') {
1554 /* format microseconds */
1555 if (freplacement == NULL) {
1556 freplacement = make_freplacement(object);
1557 if (freplacement == NULL)
1558 goto Done;
1559 }
1560 assert(freplacement != NULL);
1561 assert(PyBytes_Check(freplacement));
1562 ptoappend = PyBytes_AS_STRING(freplacement);
1563 ntoappend = PyBytes_GET_SIZE(freplacement);
1564 }
1565 else {
1566 /* percent followed by neither z nor Z */
1567 ptoappend = pin - 2;
1568 ntoappend = 2;
1569 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 /* Append the ntoappend chars starting at ptoappend to
1572 * the new format.
1573 */
1574 if (ntoappend == 0)
1575 continue;
1576 assert(ptoappend != NULL);
1577 assert(ntoappend > 0);
1578 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001579 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 PyErr_NoMemory();
1581 goto Done;
1582 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001583 totalnew <<= 1;
1584 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 pnew = PyBytes_AsString(newfmt) + usednew;
1587 }
1588 memcpy(pnew, ptoappend, ntoappend);
1589 pnew += ntoappend;
1590 usednew += ntoappend;
1591 assert(usednew <= totalnew);
1592 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1595 goto Done;
1596 {
1597 PyObject *format;
1598 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 if (time == NULL)
1601 goto Done;
1602 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1603 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001604 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1605 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 Py_DECREF(format);
1607 }
1608 Py_DECREF(time);
1609 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001610 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 Py_XDECREF(freplacement);
1612 Py_XDECREF(zreplacement);
1613 Py_XDECREF(Zreplacement);
1614 Py_XDECREF(newfmt);
1615 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001616}
1617
Tim Peters2a799bf2002-12-16 20:18:38 +00001618/* ---------------------------------------------------------------------------
1619 * Wrap functions from the time module. These aren't directly available
1620 * from C. Perhaps they should be.
1621 */
1622
1623/* Call time.time() and return its result (a Python float). */
1624static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001625time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 PyObject *result = NULL;
1628 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001631 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001632
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001633 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 Py_DECREF(time);
1635 }
1636 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001637}
1638
1639/* Build a time.struct_time. The weekday and day number are automatically
1640 * computed from the y,m,d args.
1641 */
1642static PyObject *
1643build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001646 PyObject *result;
1647 _Py_IDENTIFIER(struct_time);
1648 PyObject *args;
1649
Tim Peters2a799bf2002-12-16 20:18:38 +00001650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001652 if (time == NULL) {
1653 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 }
Victor Stinner2b635972016-12-09 00:38:16 +01001655
1656 args = Py_BuildValue("iiiiiiiii",
1657 y, m, d,
1658 hh, mm, ss,
1659 weekday(y, m, d),
1660 days_before_month(y, m) + d,
1661 dstflag);
1662 if (args == NULL) {
1663 Py_DECREF(time);
1664 return NULL;
1665 }
1666
1667 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1668 args, NULL);
1669 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001670 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001672}
1673
1674/* ---------------------------------------------------------------------------
1675 * Miscellaneous helpers.
1676 */
1677
Mark Dickinsone94c6792009-02-02 20:36:42 +00001678/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001679 * The comparisons here all most naturally compute a cmp()-like result.
1680 * This little helper turns that into a bool result for rich comparisons.
1681 */
1682static PyObject *
1683diff_to_bool(int diff, int op)
1684{
stratakise8b19652017-11-02 11:32:54 +01001685 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001686}
1687
Tim Peters07534a62003-02-07 22:50:28 +00001688/* Raises a "can't compare" TypeError and returns NULL. */
1689static PyObject *
1690cmperror(PyObject *a, PyObject *b)
1691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 PyErr_Format(PyExc_TypeError,
1693 "can't compare %s to %s",
1694 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1695 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001696}
1697
Tim Peters2a799bf2002-12-16 20:18:38 +00001698/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001699 * Cached Python objects; these are set by the module init function.
1700 */
1701
1702/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703static PyObject *us_per_ms = NULL; /* 1000 */
1704static PyObject *us_per_second = NULL; /* 1000000 */
1705static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001706static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1707static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1708static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001709static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1710
Tim Peters2a799bf2002-12-16 20:18:38 +00001711/* ---------------------------------------------------------------------------
1712 * Class implementations.
1713 */
1714
1715/*
1716 * PyDateTime_Delta implementation.
1717 */
1718
1719/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001721 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001722 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1723 * due to ubiquitous overflow possibilities.
1724 */
1725static PyObject *
1726delta_to_microseconds(PyDateTime_Delta *self)
1727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 PyObject *x1 = NULL;
1729 PyObject *x2 = NULL;
1730 PyObject *x3 = NULL;
1731 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001733 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1734 if (x1 == NULL)
1735 goto Done;
1736 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1737 if (x2 == NULL)
1738 goto Done;
1739 Py_DECREF(x1);
1740 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 /* x2 has days in seconds */
1743 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1744 if (x1 == NULL)
1745 goto Done;
1746 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1747 if (x3 == NULL)
1748 goto Done;
1749 Py_DECREF(x1);
1750 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001751 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001752
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 /* x3 has days+seconds in seconds */
1754 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1755 if (x1 == NULL)
1756 goto Done;
1757 Py_DECREF(x3);
1758 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 /* x1 has days+seconds in us */
1761 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1762 if (x2 == NULL)
1763 goto Done;
1764 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001765 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001766
1767Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 Py_XDECREF(x1);
1769 Py_XDECREF(x2);
1770 Py_XDECREF(x3);
1771 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001772}
1773
Serhiy Storchaka95949422013-08-27 19:40:23 +03001774/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001775 */
1776static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001777microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 int us;
1780 int s;
1781 int d;
1782 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 PyObject *tuple = NULL;
1785 PyObject *num = NULL;
1786 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001787
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001788 assert(PyLong_CheckExact(pyus));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 tuple = PyNumber_Divmod(pyus, us_per_second);
1790 if (tuple == NULL)
1791 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 num = PyTuple_GetItem(tuple, 1); /* us */
1794 if (num == NULL)
1795 goto Done;
1796 temp = PyLong_AsLong(num);
1797 num = NULL;
1798 if (temp == -1 && PyErr_Occurred())
1799 goto Done;
1800 assert(0 <= temp && temp < 1000000);
1801 us = (int)temp;
1802 if (us < 0) {
1803 /* The divisor was positive, so this must be an error. */
1804 assert(PyErr_Occurred());
1805 goto Done;
1806 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1809 if (num == NULL)
1810 goto Done;
1811 Py_INCREF(num);
1812 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 tuple = PyNumber_Divmod(num, seconds_per_day);
1815 if (tuple == NULL)
1816 goto Done;
1817 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 num = PyTuple_GetItem(tuple, 1); /* seconds */
1820 if (num == NULL)
1821 goto Done;
1822 temp = PyLong_AsLong(num);
1823 num = NULL;
1824 if (temp == -1 && PyErr_Occurred())
1825 goto Done;
1826 assert(0 <= temp && temp < 24*3600);
1827 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 if (s < 0) {
1830 /* The divisor was positive, so this must be an error. */
1831 assert(PyErr_Occurred());
1832 goto Done;
1833 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1836 if (num == NULL)
1837 goto Done;
1838 Py_INCREF(num);
1839 temp = PyLong_AsLong(num);
1840 if (temp == -1 && PyErr_Occurred())
1841 goto Done;
1842 d = (int)temp;
1843 if ((long)d != temp) {
1844 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1845 "large to fit in a C int");
1846 goto Done;
1847 }
1848 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001849
1850Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 Py_XDECREF(tuple);
1852 Py_XDECREF(num);
1853 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001854}
1855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856#define microseconds_to_delta(pymicros) \
1857 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001858
Tim Peters2a799bf2002-12-16 20:18:38 +00001859static PyObject *
1860multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 PyObject *pyus_in;
1863 PyObject *pyus_out;
1864 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 pyus_in = delta_to_microseconds(delta);
1867 if (pyus_in == NULL)
1868 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1871 Py_DECREF(pyus_in);
1872 if (pyus_out == NULL)
1873 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 result = microseconds_to_delta(pyus_out);
1876 Py_DECREF(pyus_out);
1877 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001878}
1879
1880static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001881get_float_as_integer_ratio(PyObject *floatobj)
1882{
1883 PyObject *ratio;
1884
1885 assert(floatobj && PyFloat_Check(floatobj));
1886 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1887 if (ratio == NULL) {
1888 return NULL;
1889 }
1890 if (!PyTuple_Check(ratio)) {
1891 PyErr_Format(PyExc_TypeError,
1892 "unexpected return type from as_integer_ratio(): "
1893 "expected tuple, got '%.200s'",
1894 Py_TYPE(ratio)->tp_name);
1895 Py_DECREF(ratio);
1896 return NULL;
1897 }
1898 if (PyTuple_Size(ratio) != 2) {
1899 PyErr_SetString(PyExc_ValueError,
1900 "as_integer_ratio() must return a 2-tuple");
1901 Py_DECREF(ratio);
1902 return NULL;
1903 }
1904 return ratio;
1905}
1906
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001907/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001908static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001909multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001910{
1911 PyObject *result = NULL;
1912 PyObject *pyus_in = NULL, *temp, *pyus_out;
1913 PyObject *ratio = NULL;
1914
1915 pyus_in = delta_to_microseconds(delta);
1916 if (pyus_in == NULL)
1917 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001918 ratio = get_float_as_integer_ratio(floatobj);
1919 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001920 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001921 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001922 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001923 Py_DECREF(pyus_in);
1924 pyus_in = NULL;
1925 if (temp == NULL)
1926 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001927 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001928 Py_DECREF(temp);
1929 if (pyus_out == NULL)
1930 goto error;
1931 result = microseconds_to_delta(pyus_out);
1932 Py_DECREF(pyus_out);
1933 error:
1934 Py_XDECREF(pyus_in);
1935 Py_XDECREF(ratio);
1936
1937 return result;
1938}
1939
1940static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001941divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1942{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 PyObject *pyus_in;
1944 PyObject *pyus_out;
1945 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 pyus_in = delta_to_microseconds(delta);
1948 if (pyus_in == NULL)
1949 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1952 Py_DECREF(pyus_in);
1953 if (pyus_out == NULL)
1954 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 result = microseconds_to_delta(pyus_out);
1957 Py_DECREF(pyus_out);
1958 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001959}
1960
1961static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001962divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 PyObject *pyus_left;
1965 PyObject *pyus_right;
1966 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 pyus_left = delta_to_microseconds(left);
1969 if (pyus_left == NULL)
1970 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 pyus_right = delta_to_microseconds(right);
1973 if (pyus_right == NULL) {
1974 Py_DECREF(pyus_left);
1975 return NULL;
1976 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1979 Py_DECREF(pyus_left);
1980 Py_DECREF(pyus_right);
1981 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001982}
1983
1984static PyObject *
1985truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 PyObject *pyus_left;
1988 PyObject *pyus_right;
1989 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 pyus_left = delta_to_microseconds(left);
1992 if (pyus_left == NULL)
1993 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 pyus_right = delta_to_microseconds(right);
1996 if (pyus_right == NULL) {
1997 Py_DECREF(pyus_left);
1998 return NULL;
1999 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 result = PyNumber_TrueDivide(pyus_left, pyus_right);
2002 Py_DECREF(pyus_left);
2003 Py_DECREF(pyus_right);
2004 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002005}
2006
2007static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002008truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2009{
2010 PyObject *result;
2011 PyObject *pyus_in, *pyus_out;
2012 pyus_in = delta_to_microseconds(delta);
2013 if (pyus_in == NULL)
2014 return NULL;
2015 pyus_out = divide_nearest(pyus_in, i);
2016 Py_DECREF(pyus_in);
2017 if (pyus_out == NULL)
2018 return NULL;
2019 result = microseconds_to_delta(pyus_out);
2020 Py_DECREF(pyus_out);
2021
2022 return result;
2023}
2024
2025static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002026delta_add(PyObject *left, PyObject *right)
2027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2031 /* delta + delta */
2032 /* The C-level additions can't overflow because of the
2033 * invariant bounds.
2034 */
2035 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2036 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2037 int microseconds = GET_TD_MICROSECONDS(left) +
2038 GET_TD_MICROSECONDS(right);
2039 result = new_delta(days, seconds, microseconds, 1);
2040 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 if (result == Py_NotImplemented)
2043 Py_INCREF(result);
2044 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002045}
2046
2047static PyObject *
2048delta_negative(PyDateTime_Delta *self)
2049{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 return new_delta(-GET_TD_DAYS(self),
2051 -GET_TD_SECONDS(self),
2052 -GET_TD_MICROSECONDS(self),
2053 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002054}
2055
2056static PyObject *
2057delta_positive(PyDateTime_Delta *self)
2058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 /* Could optimize this (by returning self) if this isn't a
2060 * subclass -- but who uses unary + ? Approximately nobody.
2061 */
2062 return new_delta(GET_TD_DAYS(self),
2063 GET_TD_SECONDS(self),
2064 GET_TD_MICROSECONDS(self),
2065 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002066}
2067
2068static PyObject *
2069delta_abs(PyDateTime_Delta *self)
2070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 assert(GET_TD_MICROSECONDS(self) >= 0);
2074 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 if (GET_TD_DAYS(self) < 0)
2077 result = delta_negative(self);
2078 else
2079 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002082}
2083
2084static PyObject *
2085delta_subtract(PyObject *left, PyObject *right)
2086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2090 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002091 /* The C-level additions can't overflow because of the
2092 * invariant bounds.
2093 */
2094 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2095 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2096 int microseconds = GET_TD_MICROSECONDS(left) -
2097 GET_TD_MICROSECONDS(right);
2098 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 if (result == Py_NotImplemented)
2102 Py_INCREF(result);
2103 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002104}
2105
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002106static int
2107delta_cmp(PyObject *self, PyObject *other)
2108{
2109 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2110 if (diff == 0) {
2111 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2112 if (diff == 0)
2113 diff = GET_TD_MICROSECONDS(self) -
2114 GET_TD_MICROSECONDS(other);
2115 }
2116 return diff;
2117}
2118
Tim Peters2a799bf2002-12-16 20:18:38 +00002119static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002120delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002123 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 return diff_to_bool(diff, op);
2125 }
2126 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002127 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002129}
2130
2131static PyObject *delta_getstate(PyDateTime_Delta *self);
2132
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002133static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002134delta_hash(PyDateTime_Delta *self)
2135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 if (self->hashcode == -1) {
2137 PyObject *temp = delta_getstate(self);
2138 if (temp != NULL) {
2139 self->hashcode = PyObject_Hash(temp);
2140 Py_DECREF(temp);
2141 }
2142 }
2143 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002144}
2145
2146static PyObject *
2147delta_multiply(PyObject *left, PyObject *right)
2148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 if (PyDelta_Check(left)) {
2152 /* delta * ??? */
2153 if (PyLong_Check(right))
2154 result = multiply_int_timedelta(right,
2155 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002156 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002157 result = multiply_truedivide_timedelta_float(
2158 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 }
2160 else if (PyLong_Check(left))
2161 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002162 (PyDateTime_Delta *) right);
2163 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002164 result = multiply_truedivide_timedelta_float(
2165 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 if (result == Py_NotImplemented)
2168 Py_INCREF(result);
2169 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002170}
2171
2172static PyObject *
2173delta_divide(PyObject *left, PyObject *right)
2174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 if (PyDelta_Check(left)) {
2178 /* delta * ??? */
2179 if (PyLong_Check(right))
2180 result = divide_timedelta_int(
2181 (PyDateTime_Delta *)left,
2182 right);
2183 else if (PyDelta_Check(right))
2184 result = divide_timedelta_timedelta(
2185 (PyDateTime_Delta *)left,
2186 (PyDateTime_Delta *)right);
2187 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 if (result == Py_NotImplemented)
2190 Py_INCREF(result);
2191 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002192}
2193
Mark Dickinson7c186e22010-04-20 22:32:49 +00002194static PyObject *
2195delta_truedivide(PyObject *left, PyObject *right)
2196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 if (PyDelta_Check(left)) {
2200 if (PyDelta_Check(right))
2201 result = truedivide_timedelta_timedelta(
2202 (PyDateTime_Delta *)left,
2203 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002204 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002205 result = multiply_truedivide_timedelta_float(
2206 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002207 else if (PyLong_Check(right))
2208 result = truedivide_timedelta_int(
2209 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002212 if (result == Py_NotImplemented)
2213 Py_INCREF(result);
2214 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002215}
2216
2217static PyObject *
2218delta_remainder(PyObject *left, PyObject *right)
2219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 PyObject *pyus_left;
2221 PyObject *pyus_right;
2222 PyObject *pyus_remainder;
2223 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002224
Brian Curtindfc80e32011-08-10 20:28:54 -05002225 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2226 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2229 if (pyus_left == NULL)
2230 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2233 if (pyus_right == NULL) {
2234 Py_DECREF(pyus_left);
2235 return NULL;
2236 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002238 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2239 Py_DECREF(pyus_left);
2240 Py_DECREF(pyus_right);
2241 if (pyus_remainder == NULL)
2242 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 remainder = microseconds_to_delta(pyus_remainder);
2245 Py_DECREF(pyus_remainder);
2246 if (remainder == NULL)
2247 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002250}
2251
2252static PyObject *
2253delta_divmod(PyObject *left, PyObject *right)
2254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 PyObject *pyus_left;
2256 PyObject *pyus_right;
2257 PyObject *divmod;
2258 PyObject *delta;
2259 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002260
Brian Curtindfc80e32011-08-10 20:28:54 -05002261 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2262 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2265 if (pyus_left == NULL)
2266 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2269 if (pyus_right == NULL) {
2270 Py_DECREF(pyus_left);
2271 return NULL;
2272 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2275 Py_DECREF(pyus_left);
2276 Py_DECREF(pyus_right);
2277 if (divmod == NULL)
2278 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 assert(PyTuple_Size(divmod) == 2);
2281 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2282 if (delta == NULL) {
2283 Py_DECREF(divmod);
2284 return NULL;
2285 }
2286 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2287 Py_DECREF(delta);
2288 Py_DECREF(divmod);
2289 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002290}
2291
Tim Peters2a799bf2002-12-16 20:18:38 +00002292/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2293 * timedelta constructor. sofar is the # of microseconds accounted for
2294 * so far, and there are factor microseconds per current unit, the number
2295 * of which is given by num. num * factor is added to sofar in a
2296 * numerically careful way, and that's the result. Any fractional
2297 * microseconds left over (this can happen if num is a float type) are
2298 * added into *leftover.
2299 * Note that there are many ways this can give an error (NULL) return.
2300 */
2301static PyObject *
2302accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2303 double *leftover)
2304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 PyObject *prod;
2306 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002310 if (PyLong_Check(num)) {
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002311 prod = PyNumber_Multiply(factor, num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 if (prod == NULL)
2313 return NULL;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002314 assert(PyLong_CheckExact(prod));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 sum = PyNumber_Add(sofar, prod);
2316 Py_DECREF(prod);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002317 assert(sum == NULL || PyLong_CheckExact(sum));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 return sum;
2319 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002321 if (PyFloat_Check(num)) {
2322 double dnum;
2323 double fracpart;
2324 double intpart;
2325 PyObject *x;
2326 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002328 /* The Plan: decompose num into an integer part and a
2329 * fractional part, num = intpart + fracpart.
2330 * Then num * factor ==
2331 * intpart * factor + fracpart * factor
2332 * and the LHS can be computed exactly in long arithmetic.
2333 * The RHS is again broken into an int part and frac part.
2334 * and the frac part is added into *leftover.
2335 */
2336 dnum = PyFloat_AsDouble(num);
2337 if (dnum == -1.0 && PyErr_Occurred())
2338 return NULL;
2339 fracpart = modf(dnum, &intpart);
2340 x = PyLong_FromDouble(intpart);
2341 if (x == NULL)
2342 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 prod = PyNumber_Multiply(x, factor);
2345 Py_DECREF(x);
2346 if (prod == NULL)
2347 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 sum = PyNumber_Add(sofar, prod);
2350 Py_DECREF(prod);
2351 if (sum == NULL)
2352 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002354 if (fracpart == 0.0)
2355 return sum;
2356 /* So far we've lost no information. Dealing with the
2357 * fractional part requires float arithmetic, and may
2358 * lose a little info.
2359 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002360 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 dnum *= fracpart;
2364 fracpart = modf(dnum, &intpart);
2365 x = PyLong_FromDouble(intpart);
2366 if (x == NULL) {
2367 Py_DECREF(sum);
2368 return NULL;
2369 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002371 y = PyNumber_Add(sum, x);
2372 Py_DECREF(sum);
2373 Py_DECREF(x);
2374 *leftover += fracpart;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002375 assert(y == NULL || PyLong_CheckExact(y));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 return y;
2377 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 PyErr_Format(PyExc_TypeError,
2380 "unsupported type for timedelta %s component: %s",
2381 tag, Py_TYPE(num)->tp_name);
2382 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002383}
2384
2385static PyObject *
2386delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 /* Argument objects. */
2391 PyObject *day = NULL;
2392 PyObject *second = NULL;
2393 PyObject *us = NULL;
2394 PyObject *ms = NULL;
2395 PyObject *minute = NULL;
2396 PyObject *hour = NULL;
2397 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 PyObject *x = NULL; /* running sum of microseconds */
2400 PyObject *y = NULL; /* temp sum of microseconds */
2401 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 static char *keywords[] = {
2404 "days", "seconds", "microseconds", "milliseconds",
2405 "minutes", "hours", "weeks", NULL
2406 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2409 keywords,
2410 &day, &second, &us,
2411 &ms, &minute, &hour, &week) == 0)
2412 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 x = PyLong_FromLong(0);
2415 if (x == NULL)
2416 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418#define CLEANUP \
2419 Py_DECREF(x); \
2420 x = y; \
2421 if (x == NULL) \
2422 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002425 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 CLEANUP;
2427 }
2428 if (ms) {
2429 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2430 CLEANUP;
2431 }
2432 if (second) {
2433 y = accum("seconds", x, second, us_per_second, &leftover_us);
2434 CLEANUP;
2435 }
2436 if (minute) {
2437 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2438 CLEANUP;
2439 }
2440 if (hour) {
2441 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2442 CLEANUP;
2443 }
2444 if (day) {
2445 y = accum("days", x, day, us_per_day, &leftover_us);
2446 CLEANUP;
2447 }
2448 if (week) {
2449 y = accum("weeks", x, week, us_per_week, &leftover_us);
2450 CLEANUP;
2451 }
2452 if (leftover_us) {
2453 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002454 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002455 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002456 PyObject *temp;
2457
Victor Stinner69cc4872015-09-08 23:58:54 +02002458 whole_us = round(leftover_us);
2459 if (fabs(whole_us - leftover_us) == 0.5) {
2460 /* We're exactly halfway between two integers. In order
2461 * to do round-half-to-even, we must determine whether x
2462 * is odd. Note that x is odd when it's last bit is 1. The
2463 * code below uses bitwise and operation to check the last
2464 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002465 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002466 if (temp == NULL) {
2467 Py_DECREF(x);
2468 goto Done;
2469 }
2470 x_is_odd = PyObject_IsTrue(temp);
2471 Py_DECREF(temp);
2472 if (x_is_odd == -1) {
2473 Py_DECREF(x);
2474 goto Done;
2475 }
2476 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2477 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002478
Victor Stinner36a5a062013-08-28 01:53:39 +02002479 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 if (temp == NULL) {
2482 Py_DECREF(x);
2483 goto Done;
2484 }
2485 y = PyNumber_Add(x, temp);
2486 Py_DECREF(temp);
2487 CLEANUP;
2488 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 self = microseconds_to_delta_ex(x, type);
2491 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002492Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002494
2495#undef CLEANUP
2496}
2497
2498static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002499delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002501 return (GET_TD_DAYS(self) != 0
2502 || GET_TD_SECONDS(self) != 0
2503 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002504}
2505
2506static PyObject *
2507delta_repr(PyDateTime_Delta *self)
2508{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002509 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002510
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002511 if (args == NULL) {
2512 return NULL;
2513 }
2514
2515 const char *sep = "";
2516
2517 if (GET_TD_DAYS(self) != 0) {
2518 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2519 if (args == NULL) {
2520 return NULL;
2521 }
2522 sep = ", ";
2523 }
2524
2525 if (GET_TD_SECONDS(self) != 0) {
2526 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2527 GET_TD_SECONDS(self)));
2528 if (args == NULL) {
2529 return NULL;
2530 }
2531 sep = ", ";
2532 }
2533
2534 if (GET_TD_MICROSECONDS(self) != 0) {
2535 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2536 GET_TD_MICROSECONDS(self)));
2537 if (args == NULL) {
2538 return NULL;
2539 }
2540 }
2541
2542 if (PyUnicode_GET_LENGTH(args) == 0) {
2543 Py_SETREF(args, PyUnicode_FromString("0"));
2544 if (args == NULL) {
2545 return NULL;
2546 }
2547 }
2548
2549 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2550 args);
2551 Py_DECREF(args);
2552 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002553}
2554
2555static PyObject *
2556delta_str(PyDateTime_Delta *self)
2557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558 int us = GET_TD_MICROSECONDS(self);
2559 int seconds = GET_TD_SECONDS(self);
2560 int minutes = divmod(seconds, 60, &seconds);
2561 int hours = divmod(minutes, 60, &minutes);
2562 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 if (days) {
2565 if (us)
2566 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2567 days, (days == 1 || days == -1) ? "" : "s",
2568 hours, minutes, seconds, us);
2569 else
2570 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2571 days, (days == 1 || days == -1) ? "" : "s",
2572 hours, minutes, seconds);
2573 } else {
2574 if (us)
2575 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2576 hours, minutes, seconds, us);
2577 else
2578 return PyUnicode_FromFormat("%d:%02d:%02d",
2579 hours, minutes, seconds);
2580 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002581
Tim Peters2a799bf2002-12-16 20:18:38 +00002582}
2583
Tim Peters371935f2003-02-01 01:52:50 +00002584/* Pickle support, a simple use of __reduce__. */
2585
Tim Petersb57f8f02003-02-01 02:54:15 +00002586/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002587static PyObject *
2588delta_getstate(PyDateTime_Delta *self)
2589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002590 return Py_BuildValue("iii", GET_TD_DAYS(self),
2591 GET_TD_SECONDS(self),
2592 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002593}
2594
Tim Peters2a799bf2002-12-16 20:18:38 +00002595static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002596delta_total_seconds(PyObject *self)
2597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 PyObject *total_seconds;
2599 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2602 if (total_microseconds == NULL)
2603 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002604
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002605 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002609}
2610
2611static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002612delta_reduce(PyDateTime_Delta* self)
2613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002614 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002615}
2616
2617#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2618
2619static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 {"days", T_INT, OFFSET(days), READONLY,
2622 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 {"seconds", T_INT, OFFSET(seconds), READONLY,
2625 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002627 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2628 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2629 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002630};
2631
2632static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2634 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2637 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002640};
2641
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002642static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002643PyDoc_STR("Difference between two datetime values.");
2644
2645static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 delta_add, /* nb_add */
2647 delta_subtract, /* nb_subtract */
2648 delta_multiply, /* nb_multiply */
2649 delta_remainder, /* nb_remainder */
2650 delta_divmod, /* nb_divmod */
2651 0, /* nb_power */
2652 (unaryfunc)delta_negative, /* nb_negative */
2653 (unaryfunc)delta_positive, /* nb_positive */
2654 (unaryfunc)delta_abs, /* nb_absolute */
2655 (inquiry)delta_bool, /* nb_bool */
2656 0, /*nb_invert*/
2657 0, /*nb_lshift*/
2658 0, /*nb_rshift*/
2659 0, /*nb_and*/
2660 0, /*nb_xor*/
2661 0, /*nb_or*/
2662 0, /*nb_int*/
2663 0, /*nb_reserved*/
2664 0, /*nb_float*/
2665 0, /*nb_inplace_add*/
2666 0, /*nb_inplace_subtract*/
2667 0, /*nb_inplace_multiply*/
2668 0, /*nb_inplace_remainder*/
2669 0, /*nb_inplace_power*/
2670 0, /*nb_inplace_lshift*/
2671 0, /*nb_inplace_rshift*/
2672 0, /*nb_inplace_and*/
2673 0, /*nb_inplace_xor*/
2674 0, /*nb_inplace_or*/
2675 delta_divide, /* nb_floor_divide */
2676 delta_truedivide, /* nb_true_divide */
2677 0, /* nb_inplace_floor_divide */
2678 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002679};
2680
2681static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002682 PyVarObject_HEAD_INIT(NULL, 0)
2683 "datetime.timedelta", /* tp_name */
2684 sizeof(PyDateTime_Delta), /* tp_basicsize */
2685 0, /* tp_itemsize */
2686 0, /* tp_dealloc */
2687 0, /* tp_print */
2688 0, /* tp_getattr */
2689 0, /* tp_setattr */
2690 0, /* tp_reserved */
2691 (reprfunc)delta_repr, /* tp_repr */
2692 &delta_as_number, /* tp_as_number */
2693 0, /* tp_as_sequence */
2694 0, /* tp_as_mapping */
2695 (hashfunc)delta_hash, /* tp_hash */
2696 0, /* tp_call */
2697 (reprfunc)delta_str, /* tp_str */
2698 PyObject_GenericGetAttr, /* tp_getattro */
2699 0, /* tp_setattro */
2700 0, /* tp_as_buffer */
2701 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2702 delta_doc, /* tp_doc */
2703 0, /* tp_traverse */
2704 0, /* tp_clear */
2705 delta_richcompare, /* tp_richcompare */
2706 0, /* tp_weaklistoffset */
2707 0, /* tp_iter */
2708 0, /* tp_iternext */
2709 delta_methods, /* tp_methods */
2710 delta_members, /* tp_members */
2711 0, /* tp_getset */
2712 0, /* tp_base */
2713 0, /* tp_dict */
2714 0, /* tp_descr_get */
2715 0, /* tp_descr_set */
2716 0, /* tp_dictoffset */
2717 0, /* tp_init */
2718 0, /* tp_alloc */
2719 delta_new, /* tp_new */
2720 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002721};
2722
2723/*
2724 * PyDateTime_Date implementation.
2725 */
2726
2727/* Accessor properties. */
2728
2729static PyObject *
2730date_year(PyDateTime_Date *self, void *unused)
2731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002732 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002733}
2734
2735static PyObject *
2736date_month(PyDateTime_Date *self, void *unused)
2737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002738 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002739}
2740
2741static PyObject *
2742date_day(PyDateTime_Date *self, void *unused)
2743{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002744 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002745}
2746
2747static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002748 {"year", (getter)date_year},
2749 {"month", (getter)date_month},
2750 {"day", (getter)date_day},
2751 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002752};
2753
2754/* Constructors. */
2755
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002756static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002757
Tim Peters2a799bf2002-12-16 20:18:38 +00002758static PyObject *
2759date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002761 PyObject *self = NULL;
2762 PyObject *state;
2763 int year;
2764 int month;
2765 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002767 /* Check for invocation from pickle with __getstate__ state */
2768 if (PyTuple_GET_SIZE(args) == 1 &&
2769 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2770 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2771 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2772 {
2773 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002775 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2776 if (me != NULL) {
2777 char *pdata = PyBytes_AS_STRING(state);
2778 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2779 me->hashcode = -1;
2780 }
2781 return (PyObject *)me;
2782 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002784 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2785 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002786 self = new_date_ex(year, month, day, type);
2787 }
2788 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002789}
2790
2791/* Return new date from localtime(t). */
2792static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002793date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002794{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002795 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002797
Victor Stinnere4a994d2015-03-30 01:10:14 +02002798 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002799 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002800
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002801 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002802 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002803
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002804 return new_date_subclass_ex(tm.tm_year + 1900,
2805 tm.tm_mon + 1,
2806 tm.tm_mday,
2807 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002808}
2809
2810/* Return new date from current time.
2811 * We say this is equivalent to fromtimestamp(time.time()), and the
2812 * only way to be sure of that is to *call* time.time(). That's not
2813 * generally the same as calling C's time.
2814 */
2815static PyObject *
2816date_today(PyObject *cls, PyObject *dummy)
2817{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002818 PyObject *time;
2819 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002820 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 time = time_time();
2823 if (time == NULL)
2824 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002826 /* Note well: today() is a class method, so this may not call
2827 * date.fromtimestamp. For example, it may call
2828 * datetime.fromtimestamp. That's why we need all the accuracy
2829 * time.time() delivers; if someone were gonzo about optimization,
2830 * date.today() could get away with plain C time().
2831 */
Victor Stinner20401de2016-12-09 15:24:31 +01002832 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2833 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002834 Py_DECREF(time);
2835 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002836}
2837
2838/* Return new date from given timestamp (Python timestamp -- a double). */
2839static PyObject *
2840date_fromtimestamp(PyObject *cls, PyObject *args)
2841{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002842 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002843 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002844
Victor Stinner5d272cc2012-03-13 13:35:55 +01002845 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2846 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002848}
2849
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002850
Tim Peters2a799bf2002-12-16 20:18:38 +00002851/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2852 * the ordinal is out of range.
2853 */
2854static PyObject *
2855date_fromordinal(PyObject *cls, PyObject *args)
2856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002857 PyObject *result = NULL;
2858 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002860 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2861 int year;
2862 int month;
2863 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002865 if (ordinal < 1)
2866 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2867 ">= 1");
2868 else {
2869 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002870 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002871 }
2872 }
2873 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002874}
2875
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002876/* Return the new date from a string as generated by date.isoformat() */
2877static PyObject *
2878date_fromisoformat(PyObject *cls, PyObject *dtstr) {
2879 assert(dtstr != NULL);
2880
2881 if (!PyUnicode_Check(dtstr)) {
2882 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
2883 return NULL;
2884 }
2885
2886 Py_ssize_t len;
2887
2888 const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002889 if (dt_ptr == NULL) {
2890 goto invalid_string_error;
2891 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002892
2893 int year = 0, month = 0, day = 0;
2894
2895 int rv;
2896 if (len == 10) {
2897 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
2898 } else {
2899 rv = -1;
2900 }
2901
2902 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002903 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002904 }
2905
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002906 return new_date_subclass_ex(year, month, day, cls);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002907
2908invalid_string_error:
2909 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R",
2910 dtstr);
2911 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002912}
2913
2914
Tim Peters2a799bf2002-12-16 20:18:38 +00002915/*
2916 * Date arithmetic.
2917 */
2918
2919/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2920 * instead.
2921 */
2922static PyObject *
2923add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2924{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002925 PyObject *result = NULL;
2926 int year = GET_YEAR(date);
2927 int month = GET_MONTH(date);
2928 int deltadays = GET_TD_DAYS(delta);
2929 /* C-level overflow is impossible because |deltadays| < 1e9. */
2930 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002932 if (normalize_date(&year, &month, &day) >= 0)
2933 result = new_date(year, month, day);
2934 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002935}
2936
2937static PyObject *
2938date_add(PyObject *left, PyObject *right)
2939{
Brian Curtindfc80e32011-08-10 20:28:54 -05002940 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2941 Py_RETURN_NOTIMPLEMENTED;
2942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002943 if (PyDate_Check(left)) {
2944 /* date + ??? */
2945 if (PyDelta_Check(right))
2946 /* date + delta */
2947 return add_date_timedelta((PyDateTime_Date *) left,
2948 (PyDateTime_Delta *) right,
2949 0);
2950 }
2951 else {
2952 /* ??? + date
2953 * 'right' must be one of us, or we wouldn't have been called
2954 */
2955 if (PyDelta_Check(left))
2956 /* delta + date */
2957 return add_date_timedelta((PyDateTime_Date *) right,
2958 (PyDateTime_Delta *) left,
2959 0);
2960 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002961 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002962}
2963
2964static PyObject *
2965date_subtract(PyObject *left, PyObject *right)
2966{
Brian Curtindfc80e32011-08-10 20:28:54 -05002967 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2968 Py_RETURN_NOTIMPLEMENTED;
2969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002970 if (PyDate_Check(left)) {
2971 if (PyDate_Check(right)) {
2972 /* date - date */
2973 int left_ord = ymd_to_ord(GET_YEAR(left),
2974 GET_MONTH(left),
2975 GET_DAY(left));
2976 int right_ord = ymd_to_ord(GET_YEAR(right),
2977 GET_MONTH(right),
2978 GET_DAY(right));
2979 return new_delta(left_ord - right_ord, 0, 0, 0);
2980 }
2981 if (PyDelta_Check(right)) {
2982 /* date - delta */
2983 return add_date_timedelta((PyDateTime_Date *) left,
2984 (PyDateTime_Delta *) right,
2985 1);
2986 }
2987 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002988 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002989}
2990
2991
2992/* Various ways to turn a date into a string. */
2993
2994static PyObject *
2995date_repr(PyDateTime_Date *self)
2996{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002997 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2998 Py_TYPE(self)->tp_name,
2999 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003000}
3001
3002static PyObject *
3003date_isoformat(PyDateTime_Date *self)
3004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003005 return PyUnicode_FromFormat("%04d-%02d-%02d",
3006 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003007}
3008
Tim Peterse2df5ff2003-05-02 18:39:55 +00003009/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003010static PyObject *
3011date_str(PyDateTime_Date *self)
3012{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003013 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003014}
3015
3016
3017static PyObject *
3018date_ctime(PyDateTime_Date *self)
3019{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003020 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003021}
3022
3023static PyObject *
3024date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3025{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003026 /* This method can be inherited, and needs to call the
3027 * timetuple() method appropriate to self's class.
3028 */
3029 PyObject *result;
3030 PyObject *tuple;
3031 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003032 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003033 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003035 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3036 &format))
3037 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003038
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003039 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003040 if (tuple == NULL)
3041 return NULL;
3042 result = wrap_strftime((PyObject *)self, format, tuple,
3043 (PyObject *)self);
3044 Py_DECREF(tuple);
3045 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003046}
3047
Eric Smith1ba31142007-09-11 18:06:02 +00003048static PyObject *
3049date_format(PyDateTime_Date *self, PyObject *args)
3050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003051 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003053 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3054 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003056 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003057 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003058 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003059
Victor Stinner20401de2016-12-09 15:24:31 +01003060 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3061 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003062}
3063
Tim Peters2a799bf2002-12-16 20:18:38 +00003064/* ISO methods. */
3065
3066static PyObject *
3067date_isoweekday(PyDateTime_Date *self)
3068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003069 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003071 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003072}
3073
3074static PyObject *
3075date_isocalendar(PyDateTime_Date *self)
3076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003077 int year = GET_YEAR(self);
3078 int week1_monday = iso_week1_monday(year);
3079 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3080 int week;
3081 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 week = divmod(today - week1_monday, 7, &day);
3084 if (week < 0) {
3085 --year;
3086 week1_monday = iso_week1_monday(year);
3087 week = divmod(today - week1_monday, 7, &day);
3088 }
3089 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3090 ++year;
3091 week = 0;
3092 }
3093 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003094}
3095
3096/* Miscellaneous methods. */
3097
Tim Peters2a799bf2002-12-16 20:18:38 +00003098static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003099date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003101 if (PyDate_Check(other)) {
3102 int diff = memcmp(((PyDateTime_Date *)self)->data,
3103 ((PyDateTime_Date *)other)->data,
3104 _PyDateTime_DATE_DATASIZE);
3105 return diff_to_bool(diff, op);
3106 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003107 else
3108 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003109}
3110
3111static PyObject *
3112date_timetuple(PyDateTime_Date *self)
3113{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003114 return build_struct_time(GET_YEAR(self),
3115 GET_MONTH(self),
3116 GET_DAY(self),
3117 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003118}
3119
Tim Peters12bf3392002-12-24 05:41:27 +00003120static PyObject *
3121date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003123 PyObject *clone;
3124 PyObject *tuple;
3125 int year = GET_YEAR(self);
3126 int month = GET_MONTH(self);
3127 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003129 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3130 &year, &month, &day))
3131 return NULL;
3132 tuple = Py_BuildValue("iii", year, month, day);
3133 if (tuple == NULL)
3134 return NULL;
3135 clone = date_new(Py_TYPE(self), tuple, NULL);
3136 Py_DECREF(tuple);
3137 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003138}
3139
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003140static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003141generic_hash(unsigned char *data, int len)
3142{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003143 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003144}
3145
3146
3147static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003148
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003149static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003150date_hash(PyDateTime_Date *self)
3151{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003152 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003153 self->hashcode = generic_hash(
3154 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003155 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003157 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003158}
3159
3160static PyObject *
3161date_toordinal(PyDateTime_Date *self)
3162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003163 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3164 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003165}
3166
3167static PyObject *
3168date_weekday(PyDateTime_Date *self)
3169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003170 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003173}
3174
Tim Peters371935f2003-02-01 01:52:50 +00003175/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003176
Tim Petersb57f8f02003-02-01 02:54:15 +00003177/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003178static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003179date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003181 PyObject* field;
3182 field = PyBytes_FromStringAndSize((char*)self->data,
3183 _PyDateTime_DATE_DATASIZE);
3184 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003185}
3186
3187static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003188date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003190 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003191}
3192
3193static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003195 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00003196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003197 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
3198 METH_CLASS,
3199 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
3200 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003202 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3203 METH_CLASS,
3204 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3205 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003206
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003207 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3208 METH_CLASS,
3209 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003211 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3212 PyDoc_STR("Current date or datetime: same as "
3213 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3218 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003220 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
3221 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003223 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3224 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003226 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3227 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003229 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3230 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3231 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003233 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3234 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003236 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3237 PyDoc_STR("Return the day of the week represented by the date.\n"
3238 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003240 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3241 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3242 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003244 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3245 PyDoc_STR("Return the day of the week represented by the date.\n"
3246 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003248 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3249 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003251 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3252 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003254 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003255};
3256
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003257static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003258PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003259
3260static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003261 date_add, /* nb_add */
3262 date_subtract, /* nb_subtract */
3263 0, /* nb_multiply */
3264 0, /* nb_remainder */
3265 0, /* nb_divmod */
3266 0, /* nb_power */
3267 0, /* nb_negative */
3268 0, /* nb_positive */
3269 0, /* nb_absolute */
3270 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003271};
3272
3273static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003274 PyVarObject_HEAD_INIT(NULL, 0)
3275 "datetime.date", /* tp_name */
3276 sizeof(PyDateTime_Date), /* tp_basicsize */
3277 0, /* tp_itemsize */
3278 0, /* tp_dealloc */
3279 0, /* tp_print */
3280 0, /* tp_getattr */
3281 0, /* tp_setattr */
3282 0, /* tp_reserved */
3283 (reprfunc)date_repr, /* tp_repr */
3284 &date_as_number, /* tp_as_number */
3285 0, /* tp_as_sequence */
3286 0, /* tp_as_mapping */
3287 (hashfunc)date_hash, /* tp_hash */
3288 0, /* tp_call */
3289 (reprfunc)date_str, /* tp_str */
3290 PyObject_GenericGetAttr, /* tp_getattro */
3291 0, /* tp_setattro */
3292 0, /* tp_as_buffer */
3293 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3294 date_doc, /* tp_doc */
3295 0, /* tp_traverse */
3296 0, /* tp_clear */
3297 date_richcompare, /* tp_richcompare */
3298 0, /* tp_weaklistoffset */
3299 0, /* tp_iter */
3300 0, /* tp_iternext */
3301 date_methods, /* tp_methods */
3302 0, /* tp_members */
3303 date_getset, /* tp_getset */
3304 0, /* tp_base */
3305 0, /* tp_dict */
3306 0, /* tp_descr_get */
3307 0, /* tp_descr_set */
3308 0, /* tp_dictoffset */
3309 0, /* tp_init */
3310 0, /* tp_alloc */
3311 date_new, /* tp_new */
3312 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003313};
3314
3315/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003316 * PyDateTime_TZInfo implementation.
3317 */
3318
3319/* This is a pure abstract base class, so doesn't do anything beyond
3320 * raising NotImplemented exceptions. Real tzinfo classes need
3321 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003322 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003323 * be subclasses of this tzinfo class, which is easy and quick to check).
3324 *
3325 * Note: For reasons having to do with pickling of subclasses, we have
3326 * to allow tzinfo objects to be instantiated. This wasn't an issue
3327 * in the Python implementation (__init__() could raise NotImplementedError
3328 * there without ill effect), but doing so in the C implementation hit a
3329 * brick wall.
3330 */
3331
3332static PyObject *
3333tzinfo_nogo(const char* methodname)
3334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003335 PyErr_Format(PyExc_NotImplementedError,
3336 "a tzinfo subclass must implement %s()",
3337 methodname);
3338 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003339}
3340
3341/* Methods. A subclass must implement these. */
3342
Tim Peters52dcce22003-01-23 16:36:11 +00003343static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003344tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003346 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003347}
3348
Tim Peters52dcce22003-01-23 16:36:11 +00003349static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003350tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003352 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003353}
3354
Tim Peters52dcce22003-01-23 16:36:11 +00003355static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003356tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003358 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003359}
3360
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003361
3362static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3363 PyDateTime_Delta *delta,
3364 int factor);
3365static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3366static PyObject *datetime_dst(PyObject *self, PyObject *);
3367
Tim Peters52dcce22003-01-23 16:36:11 +00003368static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003369tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003370{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003371 PyObject *result = NULL;
3372 PyObject *off = NULL, *dst = NULL;
3373 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003374
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003375 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003376 PyErr_SetString(PyExc_TypeError,
3377 "fromutc: argument must be a datetime");
3378 return NULL;
3379 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003380 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003381 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3382 "is not self");
3383 return NULL;
3384 }
Tim Peters52dcce22003-01-23 16:36:11 +00003385
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003386 off = datetime_utcoffset(dt, NULL);
3387 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003388 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003389 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003390 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3391 "utcoffset() 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 dst = datetime_dst(dt, NULL);
3396 if (dst == NULL)
3397 goto Fail;
3398 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003399 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3400 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003401 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003402 }
Tim Peters52dcce22003-01-23 16:36:11 +00003403
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003404 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3405 if (delta == NULL)
3406 goto Fail;
3407 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003408 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003409 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003410
3411 Py_DECREF(dst);
3412 dst = call_dst(GET_DT_TZINFO(dt), result);
3413 if (dst == NULL)
3414 goto Fail;
3415 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003416 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003417 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003418 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003419 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003420 if (result == NULL)
3421 goto Fail;
3422 }
3423 Py_DECREF(delta);
3424 Py_DECREF(dst);
3425 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003426 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003427
3428Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003429 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3430 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003431
Miss Islington (bot)e86db342018-02-03 17:41:43 -08003432 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003433Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003434 Py_XDECREF(off);
3435 Py_XDECREF(dst);
3436 Py_XDECREF(delta);
3437 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003438 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003439}
3440
Tim Peters2a799bf2002-12-16 20:18:38 +00003441/*
3442 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003443 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003444 */
3445
Guido van Rossum177e41a2003-01-30 22:06:23 +00003446static PyObject *
3447tzinfo_reduce(PyObject *self)
3448{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003449 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003450 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003451 _Py_IDENTIFIER(__getinitargs__);
3452 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003453
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003454 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003455 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003456 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003457 Py_DECREF(getinitargs);
3458 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003459 return NULL;
3460 }
3461 }
3462 else {
3463 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003464
3465 args = PyTuple_New(0);
3466 if (args == NULL) {
3467 return NULL;
3468 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003469 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003470
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003471 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003472 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003473 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003474 Py_DECREF(getstate);
3475 if (state == NULL) {
3476 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003477 return NULL;
3478 }
3479 }
3480 else {
3481 PyObject **dictptr;
3482 PyErr_Clear();
3483 state = Py_None;
3484 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003485 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003486 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003487 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003488 Py_INCREF(state);
3489 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003491 if (state == Py_None) {
3492 Py_DECREF(state);
3493 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3494 }
3495 else
3496 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003497}
Tim Peters2a799bf2002-12-16 20:18:38 +00003498
3499static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003501 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3502 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003504 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003505 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3506 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003509 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003511 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003512 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003514 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3515 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003517 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003518};
3519
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003520static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003521PyDoc_STR("Abstract base class for time zone info objects.");
3522
Neal Norwitz227b5332006-03-22 09:28:35 +00003523static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003524 PyVarObject_HEAD_INIT(NULL, 0)
3525 "datetime.tzinfo", /* tp_name */
3526 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3527 0, /* tp_itemsize */
3528 0, /* tp_dealloc */
3529 0, /* tp_print */
3530 0, /* tp_getattr */
3531 0, /* tp_setattr */
3532 0, /* tp_reserved */
3533 0, /* tp_repr */
3534 0, /* tp_as_number */
3535 0, /* tp_as_sequence */
3536 0, /* tp_as_mapping */
3537 0, /* tp_hash */
3538 0, /* tp_call */
3539 0, /* tp_str */
3540 PyObject_GenericGetAttr, /* tp_getattro */
3541 0, /* tp_setattro */
3542 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003543 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003544 tzinfo_doc, /* tp_doc */
3545 0, /* tp_traverse */
3546 0, /* tp_clear */
3547 0, /* tp_richcompare */
3548 0, /* tp_weaklistoffset */
3549 0, /* tp_iter */
3550 0, /* tp_iternext */
3551 tzinfo_methods, /* tp_methods */
3552 0, /* tp_members */
3553 0, /* tp_getset */
3554 0, /* tp_base */
3555 0, /* tp_dict */
3556 0, /* tp_descr_get */
3557 0, /* tp_descr_set */
3558 0, /* tp_dictoffset */
3559 0, /* tp_init */
3560 0, /* tp_alloc */
3561 PyType_GenericNew, /* tp_new */
3562 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003563};
3564
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003565static char *timezone_kws[] = {"offset", "name", NULL};
3566
3567static PyObject *
3568timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3569{
3570 PyObject *offset;
3571 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003572 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3573 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003574 return new_timezone(offset, name);
3575
3576 return NULL;
3577}
3578
3579static void
3580timezone_dealloc(PyDateTime_TimeZone *self)
3581{
3582 Py_CLEAR(self->offset);
3583 Py_CLEAR(self->name);
3584 Py_TYPE(self)->tp_free((PyObject *)self);
3585}
3586
3587static PyObject *
3588timezone_richcompare(PyDateTime_TimeZone *self,
3589 PyDateTime_TimeZone *other, int op)
3590{
Brian Curtindfc80e32011-08-10 20:28:54 -05003591 if (op != Py_EQ && op != Py_NE)
3592 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003593 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003594 if (op == Py_EQ)
3595 Py_RETURN_FALSE;
3596 else
3597 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003598 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003599 return delta_richcompare(self->offset, other->offset, op);
3600}
3601
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003602static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003603timezone_hash(PyDateTime_TimeZone *self)
3604{
3605 return delta_hash((PyDateTime_Delta *)self->offset);
3606}
3607
3608/* Check argument type passed to tzname, utcoffset, or dst methods.
3609 Returns 0 for good argument. Returns -1 and sets exception info
3610 otherwise.
3611 */
3612static int
3613_timezone_check_argument(PyObject *dt, const char *meth)
3614{
3615 if (dt == Py_None || PyDateTime_Check(dt))
3616 return 0;
3617 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3618 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3619 return -1;
3620}
3621
3622static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003623timezone_repr(PyDateTime_TimeZone *self)
3624{
3625 /* Note that although timezone is not subclassable, it is convenient
3626 to use Py_TYPE(self)->tp_name here. */
3627 const char *type_name = Py_TYPE(self)->tp_name;
3628
3629 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3630 return PyUnicode_FromFormat("%s.utc", type_name);
3631
3632 if (self->name == NULL)
3633 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3634
3635 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3636 self->name);
3637}
3638
3639
3640static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003641timezone_str(PyDateTime_TimeZone *self)
3642{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003643 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003644 PyObject *offset;
3645 char sign;
3646
3647 if (self->name != NULL) {
3648 Py_INCREF(self->name);
3649 return self->name;
3650 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003651 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003652 (GET_TD_DAYS(self->offset) == 0 &&
3653 GET_TD_SECONDS(self->offset) == 0 &&
3654 GET_TD_MICROSECONDS(self->offset) == 0))
3655 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003656 /* Offset is normalized, so it is negative if days < 0 */
3657 if (GET_TD_DAYS(self->offset) < 0) {
3658 sign = '-';
3659 offset = delta_negative((PyDateTime_Delta *)self->offset);
3660 if (offset == NULL)
3661 return NULL;
3662 }
3663 else {
3664 sign = '+';
3665 offset = self->offset;
3666 Py_INCREF(offset);
3667 }
3668 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003669 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003670 seconds = GET_TD_SECONDS(offset);
3671 Py_DECREF(offset);
3672 minutes = divmod(seconds, 60, &seconds);
3673 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003674 if (microseconds != 0) {
3675 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3676 sign, hours, minutes,
3677 seconds, microseconds);
3678 }
3679 if (seconds != 0) {
3680 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3681 sign, hours, minutes, seconds);
3682 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003683 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003684}
3685
3686static PyObject *
3687timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3688{
3689 if (_timezone_check_argument(dt, "tzname") == -1)
3690 return NULL;
3691
3692 return timezone_str(self);
3693}
3694
3695static PyObject *
3696timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3697{
3698 if (_timezone_check_argument(dt, "utcoffset") == -1)
3699 return NULL;
3700
3701 Py_INCREF(self->offset);
3702 return self->offset;
3703}
3704
3705static PyObject *
3706timezone_dst(PyObject *self, PyObject *dt)
3707{
3708 if (_timezone_check_argument(dt, "dst") == -1)
3709 return NULL;
3710
3711 Py_RETURN_NONE;
3712}
3713
3714static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003715timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3716{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003717 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003718 PyErr_SetString(PyExc_TypeError,
3719 "fromutc: argument must be a datetime");
3720 return NULL;
3721 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003722 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003723 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3724 "is not self");
3725 return NULL;
3726 }
3727
3728 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3729}
3730
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003731static PyObject *
3732timezone_getinitargs(PyDateTime_TimeZone *self)
3733{
3734 if (self->name == NULL)
3735 return Py_BuildValue("(O)", self->offset);
3736 return Py_BuildValue("(OO)", self->offset, self->name);
3737}
3738
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003739static PyMethodDef timezone_methods[] = {
3740 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3741 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003742 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003743
3744 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003745 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003746
3747 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003748 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003749
3750 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3751 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3752
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003753 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3754 PyDoc_STR("pickle support")},
3755
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003756 {NULL, NULL}
3757};
3758
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003759static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003760PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3761
3762static PyTypeObject PyDateTime_TimeZoneType = {
3763 PyVarObject_HEAD_INIT(NULL, 0)
3764 "datetime.timezone", /* tp_name */
3765 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3766 0, /* tp_itemsize */
3767 (destructor)timezone_dealloc, /* tp_dealloc */
3768 0, /* tp_print */
3769 0, /* tp_getattr */
3770 0, /* tp_setattr */
3771 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003772 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003773 0, /* tp_as_number */
3774 0, /* tp_as_sequence */
3775 0, /* tp_as_mapping */
3776 (hashfunc)timezone_hash, /* tp_hash */
3777 0, /* tp_call */
3778 (reprfunc)timezone_str, /* tp_str */
3779 0, /* tp_getattro */
3780 0, /* tp_setattro */
3781 0, /* tp_as_buffer */
3782 Py_TPFLAGS_DEFAULT, /* tp_flags */
3783 timezone_doc, /* tp_doc */
3784 0, /* tp_traverse */
3785 0, /* tp_clear */
3786 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3787 0, /* tp_weaklistoffset */
3788 0, /* tp_iter */
3789 0, /* tp_iternext */
3790 timezone_methods, /* tp_methods */
3791 0, /* tp_members */
3792 0, /* tp_getset */
3793 &PyDateTime_TZInfoType, /* tp_base */
3794 0, /* tp_dict */
3795 0, /* tp_descr_get */
3796 0, /* tp_descr_set */
3797 0, /* tp_dictoffset */
3798 0, /* tp_init */
3799 0, /* tp_alloc */
3800 timezone_new, /* tp_new */
3801};
3802
Tim Peters2a799bf2002-12-16 20:18:38 +00003803/*
Tim Peters37f39822003-01-10 03:49:02 +00003804 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003805 */
3806
Tim Peters37f39822003-01-10 03:49:02 +00003807/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003808 */
3809
3810static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003811time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003813 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003814}
3815
Tim Peters37f39822003-01-10 03:49:02 +00003816static PyObject *
3817time_minute(PyDateTime_Time *self, void *unused)
3818{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003819 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003820}
3821
3822/* The name time_second conflicted with some platform header file. */
3823static PyObject *
3824py_time_second(PyDateTime_Time *self, void *unused)
3825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003826 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003827}
3828
3829static PyObject *
3830time_microsecond(PyDateTime_Time *self, void *unused)
3831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003832 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003833}
3834
3835static PyObject *
3836time_tzinfo(PyDateTime_Time *self, void *unused)
3837{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003838 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3839 Py_INCREF(result);
3840 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003841}
3842
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003843static PyObject *
3844time_fold(PyDateTime_Time *self, void *unused)
3845{
3846 return PyLong_FromLong(TIME_GET_FOLD(self));
3847}
3848
Tim Peters37f39822003-01-10 03:49:02 +00003849static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003850 {"hour", (getter)time_hour},
3851 {"minute", (getter)time_minute},
3852 {"second", (getter)py_time_second},
3853 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003854 {"tzinfo", (getter)time_tzinfo},
3855 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003856 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003857};
3858
3859/*
3860 * Constructors.
3861 */
3862
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003863static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003864 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003865
Tim Peters2a799bf2002-12-16 20:18:38 +00003866static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003867time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003869 PyObject *self = NULL;
3870 PyObject *state;
3871 int hour = 0;
3872 int minute = 0;
3873 int second = 0;
3874 int usecond = 0;
3875 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003876 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003878 /* Check for invocation from pickle with __getstate__ state */
3879 if (PyTuple_GET_SIZE(args) >= 1 &&
3880 PyTuple_GET_SIZE(args) <= 2 &&
3881 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3882 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003883 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003884 {
3885 PyDateTime_Time *me;
3886 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003888 if (PyTuple_GET_SIZE(args) == 2) {
3889 tzinfo = PyTuple_GET_ITEM(args, 1);
3890 if (check_tzinfo_subclass(tzinfo) < 0) {
3891 PyErr_SetString(PyExc_TypeError, "bad "
3892 "tzinfo state arg");
3893 return NULL;
3894 }
3895 }
3896 aware = (char)(tzinfo != Py_None);
3897 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3898 if (me != NULL) {
3899 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003901 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3902 me->hashcode = -1;
3903 me->hastzinfo = aware;
3904 if (aware) {
3905 Py_INCREF(tzinfo);
3906 me->tzinfo = tzinfo;
3907 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003908 if (pdata[0] & (1 << 7)) {
3909 me->data[0] -= 128;
3910 me->fold = 1;
3911 }
3912 else {
3913 me->fold = 0;
3914 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003915 }
3916 return (PyObject *)me;
3917 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003918
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003919 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003920 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003921 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003922 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3923 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003924 }
3925 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003926}
3927
3928/*
3929 * Destructor.
3930 */
3931
3932static void
Tim Peters37f39822003-01-10 03:49:02 +00003933time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003935 if (HASTZINFO(self)) {
3936 Py_XDECREF(self->tzinfo);
3937 }
3938 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003939}
3940
3941/*
Tim Peters855fe882002-12-22 03:43:39 +00003942 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003943 */
3944
Tim Peters2a799bf2002-12-16 20:18:38 +00003945/* These are all METH_NOARGS, so don't need to check the arglist. */
3946static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003947time_utcoffset(PyObject *self, PyObject *unused) {
3948 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003949}
3950
3951static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003952time_dst(PyObject *self, PyObject *unused) {
3953 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003954}
3955
3956static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003957time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003958 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003959}
3960
3961/*
Tim Peters37f39822003-01-10 03:49:02 +00003962 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003963 */
3964
3965static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003966time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003968 const char *type_name = Py_TYPE(self)->tp_name;
3969 int h = TIME_GET_HOUR(self);
3970 int m = TIME_GET_MINUTE(self);
3971 int s = TIME_GET_SECOND(self);
3972 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003973 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003974 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003976 if (us)
3977 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3978 type_name, h, m, s, us);
3979 else if (s)
3980 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3981 type_name, h, m, s);
3982 else
3983 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3984 if (result != NULL && HASTZINFO(self))
3985 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003986 if (result != NULL && fold)
3987 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003988 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003989}
3990
Tim Peters37f39822003-01-10 03:49:02 +00003991static PyObject *
3992time_str(PyDateTime_Time *self)
3993{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003994 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003995}
Tim Peters2a799bf2002-12-16 20:18:38 +00003996
3997static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003998time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003999{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004000 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004001 char *timespec = NULL;
4002 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004003 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004004 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004005 static char *specs[][2] = {
4006 {"hours", "%02d"},
4007 {"minutes", "%02d:%02d"},
4008 {"seconds", "%02d:%02d:%02d"},
4009 {"milliseconds", "%02d:%02d:%02d.%03d"},
4010 {"microseconds", "%02d:%02d:%02d.%06d"},
4011 };
4012 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004013
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004014 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4015 return NULL;
4016
4017 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4018 if (us == 0) {
4019 /* seconds */
4020 given_spec = 2;
4021 }
4022 else {
4023 /* microseconds */
4024 given_spec = 4;
4025 }
4026 }
4027 else {
4028 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4029 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4030 if (given_spec == 3) {
4031 /* milliseconds */
4032 us = us / 1000;
4033 }
4034 break;
4035 }
4036 }
4037 }
4038
4039 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4040 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4041 return NULL;
4042 }
4043 else {
4044 result = PyUnicode_FromFormat(specs[given_spec][1],
4045 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4046 TIME_GET_SECOND(self), us);
4047 }
Tim Peters37f39822003-01-10 03:49:02 +00004048
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004049 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004050 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004052 /* We need to append the UTC offset. */
4053 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4054 Py_None) < 0) {
4055 Py_DECREF(result);
4056 return NULL;
4057 }
4058 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4059 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004060}
4061
Tim Peters37f39822003-01-10 03:49:02 +00004062static PyObject *
4063time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004065 PyObject *result;
4066 PyObject *tuple;
4067 PyObject *format;
4068 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004070 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4071 &format))
4072 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004074 /* Python's strftime does insane things with the year part of the
4075 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004076 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004077 */
4078 tuple = Py_BuildValue("iiiiiiiii",
4079 1900, 1, 1, /* year, month, day */
4080 TIME_GET_HOUR(self),
4081 TIME_GET_MINUTE(self),
4082 TIME_GET_SECOND(self),
4083 0, 1, -1); /* weekday, daynum, dst */
4084 if (tuple == NULL)
4085 return NULL;
4086 assert(PyTuple_Size(tuple) == 9);
4087 result = wrap_strftime((PyObject *)self, format, tuple,
4088 Py_None);
4089 Py_DECREF(tuple);
4090 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004091}
Tim Peters2a799bf2002-12-16 20:18:38 +00004092
4093/*
4094 * Miscellaneous methods.
4095 */
4096
Tim Peters37f39822003-01-10 03:49:02 +00004097static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004098time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004099{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004100 PyObject *result = NULL;
4101 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004103
Brian Curtindfc80e32011-08-10 20:28:54 -05004104 if (! PyTime_Check(other))
4105 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004106
4107 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004108 diff = memcmp(((PyDateTime_Time *)self)->data,
4109 ((PyDateTime_Time *)other)->data,
4110 _PyDateTime_TIME_DATASIZE);
4111 return diff_to_bool(diff, op);
4112 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004113 offset1 = time_utcoffset(self, NULL);
4114 if (offset1 == NULL)
4115 return NULL;
4116 offset2 = time_utcoffset(other, NULL);
4117 if (offset2 == NULL)
4118 goto done;
4119 /* If they're both naive, or both aware and have the same offsets,
4120 * we get off cheap. Note that if they're both naive, offset1 ==
4121 * offset2 == Py_None at this point.
4122 */
4123 if ((offset1 == offset2) ||
4124 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4125 delta_cmp(offset1, offset2) == 0)) {
4126 diff = memcmp(((PyDateTime_Time *)self)->data,
4127 ((PyDateTime_Time *)other)->data,
4128 _PyDateTime_TIME_DATASIZE);
4129 result = diff_to_bool(diff, op);
4130 }
4131 /* The hard case: both aware with different UTC offsets */
4132 else if (offset1 != Py_None && offset2 != Py_None) {
4133 int offsecs1, offsecs2;
4134 assert(offset1 != offset2); /* else last "if" handled it */
4135 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4136 TIME_GET_MINUTE(self) * 60 +
4137 TIME_GET_SECOND(self) -
4138 GET_TD_DAYS(offset1) * 86400 -
4139 GET_TD_SECONDS(offset1);
4140 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4141 TIME_GET_MINUTE(other) * 60 +
4142 TIME_GET_SECOND(other) -
4143 GET_TD_DAYS(offset2) * 86400 -
4144 GET_TD_SECONDS(offset2);
4145 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004146 if (diff == 0)
4147 diff = TIME_GET_MICROSECOND(self) -
4148 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004149 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004150 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004151 else if (op == Py_EQ) {
4152 result = Py_False;
4153 Py_INCREF(result);
4154 }
4155 else if (op == Py_NE) {
4156 result = Py_True;
4157 Py_INCREF(result);
4158 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004159 else {
4160 PyErr_SetString(PyExc_TypeError,
4161 "can't compare offset-naive and "
4162 "offset-aware times");
4163 }
4164 done:
4165 Py_DECREF(offset1);
4166 Py_XDECREF(offset2);
4167 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004168}
4169
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004170static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004171time_hash(PyDateTime_Time *self)
4172{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004173 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004174 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004175 if (TIME_GET_FOLD(self)) {
4176 self0 = new_time_ex2(TIME_GET_HOUR(self),
4177 TIME_GET_MINUTE(self),
4178 TIME_GET_SECOND(self),
4179 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004180 HASTZINFO(self) ? self->tzinfo : Py_None,
4181 0, Py_TYPE(self));
4182 if (self0 == NULL)
4183 return -1;
4184 }
4185 else {
4186 self0 = (PyObject *)self;
4187 Py_INCREF(self0);
4188 }
4189 offset = time_utcoffset(self0, NULL);
4190 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004191
4192 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004195 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004196 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004197 self->hashcode = generic_hash(
4198 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004199 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004200 PyObject *temp1, *temp2;
4201 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004202 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004203 seconds = TIME_GET_HOUR(self) * 3600 +
4204 TIME_GET_MINUTE(self) * 60 +
4205 TIME_GET_SECOND(self);
4206 microseconds = TIME_GET_MICROSECOND(self);
4207 temp1 = new_delta(0, seconds, microseconds, 1);
4208 if (temp1 == NULL) {
4209 Py_DECREF(offset);
4210 return -1;
4211 }
4212 temp2 = delta_subtract(temp1, offset);
4213 Py_DECREF(temp1);
4214 if (temp2 == NULL) {
4215 Py_DECREF(offset);
4216 return -1;
4217 }
4218 self->hashcode = PyObject_Hash(temp2);
4219 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004220 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004221 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004222 }
4223 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004224}
Tim Peters2a799bf2002-12-16 20:18:38 +00004225
Tim Peters12bf3392002-12-24 05:41:27 +00004226static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004227time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004228{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004229 PyObject *clone;
4230 PyObject *tuple;
4231 int hh = TIME_GET_HOUR(self);
4232 int mm = TIME_GET_MINUTE(self);
4233 int ss = TIME_GET_SECOND(self);
4234 int us = TIME_GET_MICROSECOND(self);
4235 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004236 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004237
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004238 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004239 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004240 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004241 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004242 if (fold != 0 && fold != 1) {
4243 PyErr_SetString(PyExc_ValueError,
4244 "fold must be either 0 or 1");
4245 return NULL;
4246 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004247 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4248 if (tuple == NULL)
4249 return NULL;
4250 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004251 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004252 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004253 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004254 Py_DECREF(tuple);
4255 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004256}
4257
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004258static PyObject *
4259time_fromisoformat(PyObject *cls, PyObject *tstr) {
4260 assert(tstr != NULL);
4261
4262 if (!PyUnicode_Check(tstr)) {
4263 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4264 return NULL;
4265 }
4266
4267 Py_ssize_t len;
4268 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4269
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004270 if (p == NULL) {
4271 goto invalid_string_error;
4272 }
4273
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004274 int hour = 0, minute = 0, second = 0, microsecond = 0;
4275 int tzoffset, tzimicrosecond = 0;
4276 int rv = parse_isoformat_time(p, len,
4277 &hour, &minute, &second, &microsecond,
4278 &tzoffset, &tzimicrosecond);
4279
4280 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004281 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004282 }
4283
4284 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4285 tzimicrosecond);
4286
4287 if (tzinfo == NULL) {
4288 return NULL;
4289 }
4290
4291 PyObject *t;
4292 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4293 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4294 } else {
4295 t = PyObject_CallFunction(cls, "iiiiO",
4296 hour, minute, second, microsecond, tzinfo);
4297 }
4298
4299 Py_DECREF(tzinfo);
4300 return t;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004301
4302invalid_string_error:
4303 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4304 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004305}
4306
4307
Tim Peters371935f2003-02-01 01:52:50 +00004308/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004309
Tim Peters33e0f382003-01-10 02:05:14 +00004310/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004311 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4312 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004313 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004314 */
4315static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004316time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004318 PyObject *basestate;
4319 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004321 basestate = PyBytes_FromStringAndSize((char *)self->data,
4322 _PyDateTime_TIME_DATASIZE);
4323 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004324 if (proto > 3 && TIME_GET_FOLD(self))
4325 /* Set the first bit of the first byte */
4326 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004327 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4328 result = PyTuple_Pack(1, basestate);
4329 else
4330 result = PyTuple_Pack(2, basestate, self->tzinfo);
4331 Py_DECREF(basestate);
4332 }
4333 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004334}
4335
4336static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004337time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004338{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004339 int proto;
4340 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004341 return NULL;
4342
4343 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004344}
4345
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004346static PyObject *
4347time_reduce(PyDateTime_Time *self, PyObject *arg)
4348{
4349 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4350}
4351
Tim Peters37f39822003-01-10 03:49:02 +00004352static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004353
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004354 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4355 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4356 "[+HH:MM].\n\n"
4357 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004359 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4360 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004362 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4363 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004365 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4366 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004368 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4369 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004371 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4372 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004374 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4375 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004376
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004377 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4378 PyDoc_STR("string -> time from time.isoformat() output")},
4379
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004380 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004381 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004382
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004383 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4384 PyDoc_STR("__reduce__() -> (cls, state)")},
4385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004386 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004387};
4388
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004389static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004390PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4391\n\
4392All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004393a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004394
Neal Norwitz227b5332006-03-22 09:28:35 +00004395static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004396 PyVarObject_HEAD_INIT(NULL, 0)
4397 "datetime.time", /* tp_name */
4398 sizeof(PyDateTime_Time), /* tp_basicsize */
4399 0, /* tp_itemsize */
4400 (destructor)time_dealloc, /* tp_dealloc */
4401 0, /* tp_print */
4402 0, /* tp_getattr */
4403 0, /* tp_setattr */
4404 0, /* tp_reserved */
4405 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004406 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004407 0, /* tp_as_sequence */
4408 0, /* tp_as_mapping */
4409 (hashfunc)time_hash, /* tp_hash */
4410 0, /* tp_call */
4411 (reprfunc)time_str, /* tp_str */
4412 PyObject_GenericGetAttr, /* tp_getattro */
4413 0, /* tp_setattro */
4414 0, /* tp_as_buffer */
4415 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4416 time_doc, /* tp_doc */
4417 0, /* tp_traverse */
4418 0, /* tp_clear */
4419 time_richcompare, /* tp_richcompare */
4420 0, /* tp_weaklistoffset */
4421 0, /* tp_iter */
4422 0, /* tp_iternext */
4423 time_methods, /* tp_methods */
4424 0, /* tp_members */
4425 time_getset, /* tp_getset */
4426 0, /* tp_base */
4427 0, /* tp_dict */
4428 0, /* tp_descr_get */
4429 0, /* tp_descr_set */
4430 0, /* tp_dictoffset */
4431 0, /* tp_init */
4432 time_alloc, /* tp_alloc */
4433 time_new, /* tp_new */
4434 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004435};
4436
4437/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004438 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004439 */
4440
Tim Petersa9bc1682003-01-11 03:39:11 +00004441/* Accessor properties. Properties for day, month, and year are inherited
4442 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004443 */
4444
4445static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004446datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004448 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004449}
4450
Tim Petersa9bc1682003-01-11 03:39:11 +00004451static PyObject *
4452datetime_minute(PyDateTime_DateTime *self, void *unused)
4453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004454 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004455}
4456
4457static PyObject *
4458datetime_second(PyDateTime_DateTime *self, void *unused)
4459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004460 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004461}
4462
4463static PyObject *
4464datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004466 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004467}
4468
4469static PyObject *
4470datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004472 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4473 Py_INCREF(result);
4474 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004475}
4476
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004477static PyObject *
4478datetime_fold(PyDateTime_DateTime *self, void *unused)
4479{
4480 return PyLong_FromLong(DATE_GET_FOLD(self));
4481}
4482
Tim Petersa9bc1682003-01-11 03:39:11 +00004483static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004484 {"hour", (getter)datetime_hour},
4485 {"minute", (getter)datetime_minute},
4486 {"second", (getter)datetime_second},
4487 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004488 {"tzinfo", (getter)datetime_tzinfo},
4489 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004490 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004491};
4492
4493/*
4494 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004495 */
4496
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004497static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004498 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004499 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004500};
4501
Tim Peters2a799bf2002-12-16 20:18:38 +00004502static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004503datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004505 PyObject *self = NULL;
4506 PyObject *state;
4507 int year;
4508 int month;
4509 int day;
4510 int hour = 0;
4511 int minute = 0;
4512 int second = 0;
4513 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004514 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004515 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004517 /* Check for invocation from pickle with __getstate__ state */
4518 if (PyTuple_GET_SIZE(args) >= 1 &&
4519 PyTuple_GET_SIZE(args) <= 2 &&
4520 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4521 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004522 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004523 {
4524 PyDateTime_DateTime *me;
4525 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004527 if (PyTuple_GET_SIZE(args) == 2) {
4528 tzinfo = PyTuple_GET_ITEM(args, 1);
4529 if (check_tzinfo_subclass(tzinfo) < 0) {
4530 PyErr_SetString(PyExc_TypeError, "bad "
4531 "tzinfo state arg");
4532 return NULL;
4533 }
4534 }
4535 aware = (char)(tzinfo != Py_None);
4536 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4537 if (me != NULL) {
4538 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004540 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4541 me->hashcode = -1;
4542 me->hastzinfo = aware;
4543 if (aware) {
4544 Py_INCREF(tzinfo);
4545 me->tzinfo = tzinfo;
4546 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004547 if (pdata[2] & (1 << 7)) {
4548 me->data[2] -= 128;
4549 me->fold = 1;
4550 }
4551 else {
4552 me->fold = 0;
4553 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004554 }
4555 return (PyObject *)me;
4556 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004557
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004558 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004559 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004560 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004561 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004562 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004563 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004564 }
4565 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004566}
4567
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004568/* TM_FUNC is the shared type of _PyTime_localtime() and
4569 * _PyTime_gmtime(). */
4570typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004571
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004572/* As of version 2015f max fold in IANA database is
4573 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004574static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004575/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004576static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004577
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004578static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004579utc_to_seconds(int year, int month, int day,
4580 int hour, int minute, int second)
4581{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004582 long long ordinal;
4583
4584 /* ymd_to_ord() doesn't support year <= 0 */
4585 if (year < MINYEAR || year > MAXYEAR) {
4586 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4587 return -1;
4588 }
4589
4590 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004591 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4592}
4593
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004594static long long
4595local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004596{
4597 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004598 time_t t;
4599 u -= epoch;
4600 t = u;
4601 if (t != u) {
4602 PyErr_SetString(PyExc_OverflowError,
4603 "timestamp out of range for platform time_t");
4604 return -1;
4605 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004606 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004607 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004608 return utc_to_seconds(local_time.tm_year + 1900,
4609 local_time.tm_mon + 1,
4610 local_time.tm_mday,
4611 local_time.tm_hour,
4612 local_time.tm_min,
4613 local_time.tm_sec);
4614}
4615
Tim Petersa9bc1682003-01-11 03:39:11 +00004616/* Internal helper.
4617 * Build datetime from a time_t and a distinct count of microseconds.
4618 * Pass localtime or gmtime for f, to control the interpretation of timet.
4619 */
4620static PyObject *
4621datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004622 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004623{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004624 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004625 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004626
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004627 if (f(timet, &tm) != 0)
4628 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004629
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004630 year = tm.tm_year + 1900;
4631 month = tm.tm_mon + 1;
4632 day = tm.tm_mday;
4633 hour = tm.tm_hour;
4634 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004635 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004636 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004637 * except to the extent that passing them on to the datetime
4638 * constructor would raise ValueError for a reason that
4639 * made no sense to the user.
4640 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004641 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004642
Victor Stinnerb67f0962017-02-10 10:34:02 +01004643 /* local timezone requires to compute fold */
Miss Islington (bot)97364932018-07-25 13:34:09 -07004644 if (tzinfo == Py_None && f == _PyTime_localtime
4645 /* On Windows, passing a negative value to local results
4646 * in an OSError because localtime_s on Windows does
4647 * not support negative timestamps. Unfortunately this
4648 * means that fold detection for time values between
4649 * 0 and max_fold_seconds will result in an identical
4650 * error since we subtract max_fold_seconds to detect a
4651 * fold. However, since we know there haven't been any
4652 * folds in the interval [0, max_fold_seconds) in any
4653 * timezone, we can hackily just forego fold detection
4654 * for this time range.
4655 */
4656#ifdef MS_WINDOWS
4657 && (timet - max_fold_seconds > 0)
4658#endif
4659 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004660 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004661
4662 result_seconds = utc_to_seconds(year, month, day,
4663 hour, minute, second);
4664 /* Probe max_fold_seconds to detect a fold. */
4665 probe_seconds = local(epoch + timet - max_fold_seconds);
4666 if (probe_seconds == -1)
4667 return NULL;
4668 transition = result_seconds - probe_seconds - max_fold_seconds;
4669 if (transition < 0) {
4670 probe_seconds = local(epoch + timet + transition);
4671 if (probe_seconds == -1)
4672 return NULL;
4673 if (probe_seconds == result_seconds)
4674 fold = 1;
4675 }
4676 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004677 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4678 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004679}
4680
4681/* Internal helper.
4682 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4683 * to control the interpretation of the timestamp. Since a double doesn't
4684 * have enough bits to cover a datetime's full range of precision, it's
4685 * better to call datetime_from_timet_and_us provided you have a way
4686 * to get that much precision (e.g., C time() isn't good enough).
4687 */
4688static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004689datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004690 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004692 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004693 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004694
Victor Stinnere4a994d2015-03-30 01:10:14 +02004695 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004696 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004697 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004698
Victor Stinner21f58932012-03-14 00:15:40 +01004699 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004700}
4701
4702/* Internal helper.
4703 * Build most accurate possible datetime for current time. Pass localtime or
4704 * gmtime for f as appropriate.
4705 */
4706static PyObject *
4707datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4708{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004709 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004710 time_t secs;
4711 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004712
Victor Stinner1e2b6882015-09-18 13:23:02 +02004713 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004714 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004715 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004716
Victor Stinner1e2b6882015-09-18 13:23:02 +02004717 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004718}
4719
Larry Hastings61272b72014-01-07 12:41:53 -08004720/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004721
4722@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004723datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004724
4725 tz: object = None
4726 Timezone object.
4727
4728Returns new datetime object representing current time local to tz.
4729
4730If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004731[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004732
Larry Hastings31826802013-10-19 00:09:25 -07004733static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004734datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004735/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004736{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004737 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004738
Larry Hastings31826802013-10-19 00:09:25 -07004739 /* Return best possible local time -- this isn't constrained by the
4740 * precision of a timestamp.
4741 */
4742 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004743 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004744
Larry Hastings5c661892014-01-24 06:17:25 -08004745 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004746 tz == Py_None ? _PyTime_localtime :
4747 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004748 tz);
4749 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004750 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004751 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004752 }
4753 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004754}
4755
Tim Petersa9bc1682003-01-11 03:39:11 +00004756/* Return best possible UTC time -- this isn't constrained by the
4757 * precision of a timestamp.
4758 */
4759static PyObject *
4760datetime_utcnow(PyObject *cls, PyObject *dummy)
4761{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004762 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004763}
4764
Tim Peters2a799bf2002-12-16 20:18:38 +00004765/* Return new local datetime from timestamp (Python timestamp -- a double). */
4766static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004767datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004768{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004769 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004770 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004771 PyObject *tzinfo = Py_None;
4772 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004773
Victor Stinner5d272cc2012-03-13 13:35:55 +01004774 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004775 keywords, &timestamp, &tzinfo))
4776 return NULL;
4777 if (check_tzinfo_subclass(tzinfo) < 0)
4778 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004780 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004781 tzinfo == Py_None ? _PyTime_localtime :
4782 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004783 timestamp,
4784 tzinfo);
4785 if (self != NULL && tzinfo != Py_None) {
4786 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004787 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004788 }
4789 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004790}
4791
Tim Petersa9bc1682003-01-11 03:39:11 +00004792/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4793static PyObject *
4794datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4795{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004796 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004797 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004798
Victor Stinner5d272cc2012-03-13 13:35:55 +01004799 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004800 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004801 Py_None);
4802 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004803}
4804
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004805/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004806static PyObject *
4807datetime_strptime(PyObject *cls, PyObject *args)
4808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004809 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004810 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004811 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004812
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004813 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004814 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004815
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004816 if (module == NULL) {
4817 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004818 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004819 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004820 }
Victor Stinner20401de2016-12-09 15:24:31 +01004821 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4822 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004823}
4824
Tim Petersa9bc1682003-01-11 03:39:11 +00004825/* Return new datetime from date/datetime and time arguments. */
4826static PyObject *
4827datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4828{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004829 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004830 PyObject *date;
4831 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004832 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004833 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004834
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004835 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004836 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004837 &PyDateTime_TimeType, &time, &tzinfo)) {
4838 if (tzinfo == NULL) {
4839 if (HASTZINFO(time))
4840 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4841 else
4842 tzinfo = Py_None;
4843 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004844 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
4845 GET_MONTH(date),
4846 GET_DAY(date),
4847 TIME_GET_HOUR(time),
4848 TIME_GET_MINUTE(time),
4849 TIME_GET_SECOND(time),
4850 TIME_GET_MICROSECOND(time),
4851 tzinfo,
4852 TIME_GET_FOLD(time),
4853 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004854 }
4855 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004856}
Tim Peters2a799bf2002-12-16 20:18:38 +00004857
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004858static PyObject *
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004859_sanitize_isoformat_str(PyObject *dtstr, int *needs_decref) {
4860 // `fromisoformat` allows surrogate characters in exactly one position,
4861 // the separator; to allow datetime_fromisoformat to make the simplifying
4862 // assumption that all valid strings can be encoded in UTF-8, this function
4863 // replaces any surrogate character separators with `T`.
4864 Py_ssize_t len = PyUnicode_GetLength(dtstr);
4865 *needs_decref = 0;
4866 if (len <= 10 || !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
4867 return dtstr;
4868 }
4869
4870 PyObject *str_out = PyUnicode_New(len, PyUnicode_MAX_CHAR_VALUE(dtstr));
4871 if (str_out == NULL) {
4872 return NULL;
4873 }
4874
4875 if (PyUnicode_CopyCharacters(str_out, 0, dtstr, 0, len) == -1 ||
4876 PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
4877 Py_DECREF(str_out);
4878 return NULL;
4879 }
4880
4881 *needs_decref = 1;
4882 return str_out;
4883}
4884
4885static PyObject *
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004886datetime_fromisoformat(PyObject* cls, PyObject *dtstr) {
4887 assert(dtstr != NULL);
4888
4889 if (!PyUnicode_Check(dtstr)) {
4890 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4891 return NULL;
4892 }
4893
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004894 int needs_decref = 0;
4895 dtstr = _sanitize_isoformat_str(dtstr, &needs_decref);
4896 if (dtstr == NULL) {
4897 goto error;
4898 }
4899
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004900 Py_ssize_t len;
4901 const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004902
4903 if (dt_ptr == NULL) {
4904 goto invalid_string_error;
4905 }
4906
4907 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004908
4909 int year = 0, month = 0, day = 0;
4910 int hour = 0, minute = 0, second = 0, microsecond = 0;
4911 int tzoffset = 0, tzusec = 0;
4912
4913 // date has a fixed length of 10
4914 int rv = parse_isoformat_date(p, &year, &month, &day);
4915
4916 if (!rv && len > 10) {
4917 // In UTF-8, the length of multi-byte characters is encoded in the MSB
4918 if ((p[10] & 0x80) == 0) {
4919 p += 11;
4920 } else {
4921 switch(p[10] & 0xf0) {
4922 case 0xe0:
4923 p += 13;
4924 break;
4925 case 0xf0:
4926 p += 14;
4927 break;
4928 default:
4929 p += 12;
4930 break;
4931 }
4932 }
4933
4934 len -= (p - dt_ptr);
4935 rv = parse_isoformat_time(p, len,
4936 &hour, &minute, &second, &microsecond,
4937 &tzoffset, &tzusec);
4938 }
4939 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004940 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004941 }
4942
4943 PyObject* tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
4944 if (tzinfo == NULL) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004945 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004946 }
4947
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004948 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
4949 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004950
4951 Py_DECREF(tzinfo);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004952 if (needs_decref) {
4953 Py_DECREF(dtstr);
4954 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004955 return dt;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004956
4957invalid_string_error:
4958 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
4959
4960error:
4961 if (needs_decref) {
4962 Py_DECREF(dtstr);
4963 }
4964
4965 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004966}
4967
4968
Tim Peters2a799bf2002-12-16 20:18:38 +00004969/*
4970 * Destructor.
4971 */
4972
4973static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004974datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004976 if (HASTZINFO(self)) {
4977 Py_XDECREF(self->tzinfo);
4978 }
4979 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004980}
4981
4982/*
4983 * Indirect access to tzinfo methods.
4984 */
4985
Tim Peters2a799bf2002-12-16 20:18:38 +00004986/* These are all METH_NOARGS, so don't need to check the arglist. */
4987static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004988datetime_utcoffset(PyObject *self, PyObject *unused) {
4989 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004990}
4991
4992static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004993datetime_dst(PyObject *self, PyObject *unused) {
4994 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004995}
4996
4997static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004998datetime_tzname(PyObject *self, PyObject *unused) {
4999 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00005000}
5001
5002/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005003 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005004 */
5005
Tim Petersa9bc1682003-01-11 03:39:11 +00005006/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5007 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005008 */
5009static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005010add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005011 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005012{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005013 /* Note that the C-level additions can't overflow, because of
5014 * invariant bounds on the member values.
5015 */
5016 int year = GET_YEAR(date);
5017 int month = GET_MONTH(date);
5018 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5019 int hour = DATE_GET_HOUR(date);
5020 int minute = DATE_GET_MINUTE(date);
5021 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5022 int microsecond = DATE_GET_MICROSECOND(date) +
5023 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005025 assert(factor == 1 || factor == -1);
5026 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005027 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005028 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005029 }
5030
5031 return new_datetime(year, month, day,
5032 hour, minute, second, microsecond,
5033 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005034}
5035
5036static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005037datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005038{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005039 if (PyDateTime_Check(left)) {
5040 /* datetime + ??? */
5041 if (PyDelta_Check(right))
5042 /* datetime + delta */
5043 return add_datetime_timedelta(
5044 (PyDateTime_DateTime *)left,
5045 (PyDateTime_Delta *)right,
5046 1);
5047 }
5048 else if (PyDelta_Check(left)) {
5049 /* delta + datetime */
5050 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5051 (PyDateTime_Delta *) left,
5052 1);
5053 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005054 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005055}
5056
5057static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005058datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005059{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005060 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005062 if (PyDateTime_Check(left)) {
5063 /* datetime - ??? */
5064 if (PyDateTime_Check(right)) {
5065 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005066 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005067 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005068
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005069 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5070 offset2 = offset1 = Py_None;
5071 Py_INCREF(offset1);
5072 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005073 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005074 else {
5075 offset1 = datetime_utcoffset(left, NULL);
5076 if (offset1 == NULL)
5077 return NULL;
5078 offset2 = datetime_utcoffset(right, NULL);
5079 if (offset2 == NULL) {
5080 Py_DECREF(offset1);
5081 return NULL;
5082 }
5083 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5084 PyErr_SetString(PyExc_TypeError,
5085 "can't subtract offset-naive and "
5086 "offset-aware datetimes");
5087 Py_DECREF(offset1);
5088 Py_DECREF(offset2);
5089 return NULL;
5090 }
5091 }
5092 if ((offset1 != offset2) &&
5093 delta_cmp(offset1, offset2) != 0) {
5094 offdiff = delta_subtract(offset1, offset2);
5095 if (offdiff == NULL) {
5096 Py_DECREF(offset1);
5097 Py_DECREF(offset2);
5098 return NULL;
5099 }
5100 }
5101 Py_DECREF(offset1);
5102 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005103 delta_d = ymd_to_ord(GET_YEAR(left),
5104 GET_MONTH(left),
5105 GET_DAY(left)) -
5106 ymd_to_ord(GET_YEAR(right),
5107 GET_MONTH(right),
5108 GET_DAY(right));
5109 /* These can't overflow, since the values are
5110 * normalized. At most this gives the number of
5111 * seconds in one day.
5112 */
5113 delta_s = (DATE_GET_HOUR(left) -
5114 DATE_GET_HOUR(right)) * 3600 +
5115 (DATE_GET_MINUTE(left) -
5116 DATE_GET_MINUTE(right)) * 60 +
5117 (DATE_GET_SECOND(left) -
5118 DATE_GET_SECOND(right));
5119 delta_us = DATE_GET_MICROSECOND(left) -
5120 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005121 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005122 if (result == NULL)
5123 return NULL;
5124
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005125 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005126 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005127 Py_DECREF(offdiff);
5128 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005129 }
5130 else if (PyDelta_Check(right)) {
5131 /* datetime - delta */
5132 result = add_datetime_timedelta(
5133 (PyDateTime_DateTime *)left,
5134 (PyDateTime_Delta *)right,
5135 -1);
5136 }
5137 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005139 if (result == Py_NotImplemented)
5140 Py_INCREF(result);
5141 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005142}
5143
5144/* Various ways to turn a datetime into a string. */
5145
5146static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005147datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005149 const char *type_name = Py_TYPE(self)->tp_name;
5150 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005152 if (DATE_GET_MICROSECOND(self)) {
5153 baserepr = PyUnicode_FromFormat(
5154 "%s(%d, %d, %d, %d, %d, %d, %d)",
5155 type_name,
5156 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5157 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5158 DATE_GET_SECOND(self),
5159 DATE_GET_MICROSECOND(self));
5160 }
5161 else if (DATE_GET_SECOND(self)) {
5162 baserepr = PyUnicode_FromFormat(
5163 "%s(%d, %d, %d, %d, %d, %d)",
5164 type_name,
5165 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5166 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5167 DATE_GET_SECOND(self));
5168 }
5169 else {
5170 baserepr = PyUnicode_FromFormat(
5171 "%s(%d, %d, %d, %d, %d)",
5172 type_name,
5173 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5174 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5175 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005176 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5177 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005178 if (baserepr == NULL || ! HASTZINFO(self))
5179 return baserepr;
5180 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005181}
5182
Tim Petersa9bc1682003-01-11 03:39:11 +00005183static PyObject *
5184datetime_str(PyDateTime_DateTime *self)
5185{
Victor Stinner4c381542016-12-09 00:33:39 +01005186 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005187}
Tim Peters2a799bf2002-12-16 20:18:38 +00005188
5189static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005190datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005191{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005192 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005193 char *timespec = NULL;
5194 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005195 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005196 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005197 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005198 static char *specs[][2] = {
5199 {"hours", "%04d-%02d-%02d%c%02d"},
5200 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5201 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5202 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5203 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5204 };
5205 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005206
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005207 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005208 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005209
5210 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5211 if (us == 0) {
5212 /* seconds */
5213 given_spec = 2;
5214 }
5215 else {
5216 /* microseconds */
5217 given_spec = 4;
5218 }
5219 }
5220 else {
5221 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5222 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5223 if (given_spec == 3) {
5224 us = us / 1000;
5225 }
5226 break;
5227 }
5228 }
5229 }
5230
5231 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5232 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5233 return NULL;
5234 }
5235 else {
5236 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005237 GET_YEAR(self), GET_MONTH(self),
5238 GET_DAY(self), (int)sep,
5239 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5240 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005241 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 if (!result || !HASTZINFO(self))
5244 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005246 /* We need to append the UTC offset. */
5247 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5248 (PyObject *)self) < 0) {
5249 Py_DECREF(result);
5250 return NULL;
5251 }
5252 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5253 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005254}
5255
Tim Petersa9bc1682003-01-11 03:39:11 +00005256static PyObject *
5257datetime_ctime(PyDateTime_DateTime *self)
5258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005259 return format_ctime((PyDateTime_Date *)self,
5260 DATE_GET_HOUR(self),
5261 DATE_GET_MINUTE(self),
5262 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005263}
5264
Tim Peters2a799bf2002-12-16 20:18:38 +00005265/* Miscellaneous methods. */
5266
Tim Petersa9bc1682003-01-11 03:39:11 +00005267static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005268flip_fold(PyObject *dt)
5269{
5270 return new_datetime_ex2(GET_YEAR(dt),
5271 GET_MONTH(dt),
5272 GET_DAY(dt),
5273 DATE_GET_HOUR(dt),
5274 DATE_GET_MINUTE(dt),
5275 DATE_GET_SECOND(dt),
5276 DATE_GET_MICROSECOND(dt),
5277 HASTZINFO(dt) ?
5278 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5279 !DATE_GET_FOLD(dt),
5280 Py_TYPE(dt));
5281}
5282
5283static PyObject *
5284get_flip_fold_offset(PyObject *dt)
5285{
5286 PyObject *result, *flip_dt;
5287
5288 flip_dt = flip_fold(dt);
5289 if (flip_dt == NULL)
5290 return NULL;
5291 result = datetime_utcoffset(flip_dt, NULL);
5292 Py_DECREF(flip_dt);
5293 return result;
5294}
5295
5296/* PEP 495 exception: Whenever one or both of the operands in
5297 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakafd936662018-03-28 23:05:24 +03005298 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005299 *
5300 * Return 1 if exception applies, 0 if not, and -1 on error.
5301 */
5302static int
5303pep495_eq_exception(PyObject *self, PyObject *other,
5304 PyObject *offset_self, PyObject *offset_other)
5305{
5306 int result = 0;
5307 PyObject *flip_offset;
5308
5309 flip_offset = get_flip_fold_offset(self);
5310 if (flip_offset == NULL)
5311 return -1;
5312 if (flip_offset != offset_self &&
5313 delta_cmp(flip_offset, offset_self))
5314 {
5315 result = 1;
5316 goto done;
5317 }
5318 Py_DECREF(flip_offset);
5319
5320 flip_offset = get_flip_fold_offset(other);
5321 if (flip_offset == NULL)
5322 return -1;
5323 if (flip_offset != offset_other &&
5324 delta_cmp(flip_offset, offset_other))
5325 result = 1;
5326 done:
5327 Py_DECREF(flip_offset);
5328 return result;
5329}
5330
5331static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005332datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005333{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005334 PyObject *result = NULL;
5335 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005336 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005338 if (! PyDateTime_Check(other)) {
5339 if (PyDate_Check(other)) {
5340 /* Prevent invocation of date_richcompare. We want to
5341 return NotImplemented here to give the other object
5342 a chance. But since DateTime is a subclass of
5343 Date, if the other object is a Date, it would
5344 compute an ordering based on the date part alone,
5345 and we don't want that. So force unequal or
5346 uncomparable here in that case. */
5347 if (op == Py_EQ)
5348 Py_RETURN_FALSE;
5349 if (op == Py_NE)
5350 Py_RETURN_TRUE;
5351 return cmperror(self, other);
5352 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005353 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005354 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005355
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005356 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005357 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5358 ((PyDateTime_DateTime *)other)->data,
5359 _PyDateTime_DATETIME_DATASIZE);
5360 return diff_to_bool(diff, op);
5361 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005362 offset1 = datetime_utcoffset(self, NULL);
5363 if (offset1 == NULL)
5364 return NULL;
5365 offset2 = datetime_utcoffset(other, NULL);
5366 if (offset2 == NULL)
5367 goto done;
5368 /* If they're both naive, or both aware and have the same offsets,
5369 * we get off cheap. Note that if they're both naive, offset1 ==
5370 * offset2 == Py_None at this point.
5371 */
5372 if ((offset1 == offset2) ||
5373 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5374 delta_cmp(offset1, offset2) == 0)) {
5375 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5376 ((PyDateTime_DateTime *)other)->data,
5377 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005378 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5379 int ex = pep495_eq_exception(self, other, offset1, offset2);
5380 if (ex == -1)
5381 goto done;
5382 if (ex)
5383 diff = 1;
5384 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005385 result = diff_to_bool(diff, op);
5386 }
5387 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005388 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005389
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005390 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005391 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5392 other);
5393 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005394 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005395 diff = GET_TD_DAYS(delta);
5396 if (diff == 0)
5397 diff = GET_TD_SECONDS(delta) |
5398 GET_TD_MICROSECONDS(delta);
5399 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005400 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5401 int ex = pep495_eq_exception(self, other, offset1, offset2);
5402 if (ex == -1)
5403 goto done;
5404 if (ex)
5405 diff = 1;
5406 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005407 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005408 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005409 else if (op == Py_EQ) {
5410 result = Py_False;
5411 Py_INCREF(result);
5412 }
5413 else if (op == Py_NE) {
5414 result = Py_True;
5415 Py_INCREF(result);
5416 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005417 else {
5418 PyErr_SetString(PyExc_TypeError,
5419 "can't compare offset-naive and "
5420 "offset-aware datetimes");
5421 }
5422 done:
5423 Py_DECREF(offset1);
5424 Py_XDECREF(offset2);
5425 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005426}
5427
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005428static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005429datetime_hash(PyDateTime_DateTime *self)
5430{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005431 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005432 PyObject *offset, *self0;
5433 if (DATE_GET_FOLD(self)) {
5434 self0 = new_datetime_ex2(GET_YEAR(self),
5435 GET_MONTH(self),
5436 GET_DAY(self),
5437 DATE_GET_HOUR(self),
5438 DATE_GET_MINUTE(self),
5439 DATE_GET_SECOND(self),
5440 DATE_GET_MICROSECOND(self),
5441 HASTZINFO(self) ? self->tzinfo : Py_None,
5442 0, Py_TYPE(self));
5443 if (self0 == NULL)
5444 return -1;
5445 }
5446 else {
5447 self0 = (PyObject *)self;
5448 Py_INCREF(self0);
5449 }
5450 offset = datetime_utcoffset(self0, NULL);
5451 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005452
5453 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005454 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005456 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005457 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005458 self->hashcode = generic_hash(
5459 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005460 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005461 PyObject *temp1, *temp2;
5462 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005464 assert(HASTZINFO(self));
5465 days = ymd_to_ord(GET_YEAR(self),
5466 GET_MONTH(self),
5467 GET_DAY(self));
5468 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005469 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005470 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005471 temp1 = new_delta(days, seconds,
5472 DATE_GET_MICROSECOND(self),
5473 1);
5474 if (temp1 == NULL) {
5475 Py_DECREF(offset);
5476 return -1;
5477 }
5478 temp2 = delta_subtract(temp1, offset);
5479 Py_DECREF(temp1);
5480 if (temp2 == NULL) {
5481 Py_DECREF(offset);
5482 return -1;
5483 }
5484 self->hashcode = PyObject_Hash(temp2);
5485 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005486 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005487 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005488 }
5489 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005490}
Tim Peters2a799bf2002-12-16 20:18:38 +00005491
5492static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005493datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005495 PyObject *clone;
5496 PyObject *tuple;
5497 int y = GET_YEAR(self);
5498 int m = GET_MONTH(self);
5499 int d = GET_DAY(self);
5500 int hh = DATE_GET_HOUR(self);
5501 int mm = DATE_GET_MINUTE(self);
5502 int ss = DATE_GET_SECOND(self);
5503 int us = DATE_GET_MICROSECOND(self);
5504 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005505 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005506
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005507 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005508 datetime_kws,
5509 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005510 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005511 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005512 if (fold != 0 && fold != 1) {
5513 PyErr_SetString(PyExc_ValueError,
5514 "fold must be either 0 or 1");
5515 return NULL;
5516 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005517 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5518 if (tuple == NULL)
5519 return NULL;
5520 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005521 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005522 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005523 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005524 Py_DECREF(tuple);
5525 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005526}
5527
5528static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005529local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005530{
5531 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005532 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005533 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005534 PyObject *nameo = NULL;
5535 const char *zone = NULL;
5536
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005537 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005538 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005539#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005540 zone = local_time_tm.tm_zone;
5541 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005542#else /* HAVE_STRUCT_TM_TM_ZONE */
5543 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005544 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005545 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005546 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005547 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005548 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005549 local_time = new_datetime(local_time_tm.tm_year + 1900,
5550 local_time_tm.tm_mon + 1,
5551 local_time_tm.tm_mday,
5552 local_time_tm.tm_hour,
5553 local_time_tm.tm_min,
5554 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005555 if (local_time == NULL) {
5556 return NULL;
5557 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005558 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005559 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005560 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5561 utc_time_tm.tm_mon + 1,
5562 utc_time_tm.tm_mday,
5563 utc_time_tm.tm_hour,
5564 utc_time_tm.tm_min,
5565 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005566 if (utc_time == NULL) {
5567 Py_DECREF(local_time);
5568 return NULL;
5569 }
5570 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005571 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005572 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005573 }
5574#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005575 if (delta == NULL) {
5576 return NULL;
5577 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005578 if (zone != NULL) {
5579 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5580 if (nameo == NULL)
5581 goto error;
5582 }
5583 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005584 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005585 error:
5586 Py_DECREF(delta);
5587 return result;
5588}
5589
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005590static PyObject *
5591local_timezone(PyDateTime_DateTime *utc_time)
5592{
5593 time_t timestamp;
5594 PyObject *delta;
5595 PyObject *one_second;
5596 PyObject *seconds;
5597
5598 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5599 if (delta == NULL)
5600 return NULL;
5601 one_second = new_delta(0, 1, 0, 0);
5602 if (one_second == NULL) {
5603 Py_DECREF(delta);
5604 return NULL;
5605 }
5606 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5607 (PyDateTime_Delta *)one_second);
5608 Py_DECREF(one_second);
5609 Py_DECREF(delta);
5610 if (seconds == NULL)
5611 return NULL;
5612 timestamp = _PyLong_AsTime_t(seconds);
5613 Py_DECREF(seconds);
5614 if (timestamp == -1 && PyErr_Occurred())
5615 return NULL;
5616 return local_timezone_from_timestamp(timestamp);
5617}
5618
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005619static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005620local_to_seconds(int year, int month, int day,
5621 int hour, int minute, int second, int fold);
5622
5623static PyObject *
5624local_timezone_from_local(PyDateTime_DateTime *local_dt)
5625{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005626 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005627 time_t timestamp;
5628 seconds = local_to_seconds(GET_YEAR(local_dt),
5629 GET_MONTH(local_dt),
5630 GET_DAY(local_dt),
5631 DATE_GET_HOUR(local_dt),
5632 DATE_GET_MINUTE(local_dt),
5633 DATE_GET_SECOND(local_dt),
5634 DATE_GET_FOLD(local_dt));
5635 if (seconds == -1)
5636 return NULL;
5637 /* XXX: add bounds check */
5638 timestamp = seconds - epoch;
5639 return local_timezone_from_timestamp(timestamp);
5640}
5641
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005642static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005643datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005644{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005645 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005646 PyObject *offset;
5647 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005648 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005649 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005650 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005651
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005652 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005653 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005654 return NULL;
5655
5656 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005657 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005658
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005659 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005660 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005661 self_tzinfo = local_timezone_from_local(self);
5662 if (self_tzinfo == NULL)
5663 return NULL;
5664 } else {
5665 self_tzinfo = self->tzinfo;
5666 Py_INCREF(self_tzinfo);
5667 }
Tim Peters521fc152002-12-31 17:36:56 +00005668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005669 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005670 if (self_tzinfo == tzinfo) {
5671 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005672 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005673 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005674 }
Tim Peters521fc152002-12-31 17:36:56 +00005675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005676 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005677 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5678 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005679 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005680 return NULL;
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005681 else if(offset == Py_None) {
5682 Py_DECREF(offset);
5683 goto naive;
5684 }
5685 else if (!PyDelta_Check(offset)) {
5686 Py_DECREF(offset);
5687 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5688 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5689 return NULL;
5690 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005691 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005692 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5693 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005694 Py_DECREF(offset);
5695 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005696 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005697
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005698 /* Make sure result is aware and UTC. */
5699 if (!HASTZINFO(result)) {
5700 temp = (PyObject *)result;
5701 result = (PyDateTime_DateTime *)
5702 new_datetime_ex2(GET_YEAR(result),
5703 GET_MONTH(result),
5704 GET_DAY(result),
5705 DATE_GET_HOUR(result),
5706 DATE_GET_MINUTE(result),
5707 DATE_GET_SECOND(result),
5708 DATE_GET_MICROSECOND(result),
5709 PyDateTime_TimeZone_UTC,
5710 DATE_GET_FOLD(result),
5711 Py_TYPE(result));
5712 Py_DECREF(temp);
5713 if (result == NULL)
5714 return NULL;
5715 }
5716 else {
5717 /* Result is already aware - just replace tzinfo. */
5718 temp = result->tzinfo;
5719 result->tzinfo = PyDateTime_TimeZone_UTC;
5720 Py_INCREF(result->tzinfo);
5721 Py_DECREF(temp);
5722 }
5723
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005724 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005725 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005726 if (tzinfo == Py_None) {
5727 tzinfo = local_timezone(result);
5728 if (tzinfo == NULL) {
5729 Py_DECREF(result);
5730 return NULL;
5731 }
5732 }
5733 else
5734 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005735 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005736 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005737
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005738 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005739 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005740 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005741 Py_DECREF(temp);
5742
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005743 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005744}
5745
5746static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005747datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005749 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005751 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005752 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005753
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005754 dst = call_dst(self->tzinfo, (PyObject *)self);
5755 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005756 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005757
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005758 if (dst != Py_None)
5759 dstflag = delta_bool((PyDateTime_Delta *)dst);
5760 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005761 }
5762 return build_struct_time(GET_YEAR(self),
5763 GET_MONTH(self),
5764 GET_DAY(self),
5765 DATE_GET_HOUR(self),
5766 DATE_GET_MINUTE(self),
5767 DATE_GET_SECOND(self),
5768 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005769}
5770
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005771static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005772local_to_seconds(int year, int month, int day,
5773 int hour, int minute, int second, int fold)
5774{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005775 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005776 t = utc_to_seconds(year, month, day, hour, minute, second);
5777 /* Our goal is to solve t = local(u) for u. */
5778 lt = local(t);
5779 if (lt == -1)
5780 return -1;
5781 a = lt - t;
5782 u1 = t - a;
5783 t1 = local(u1);
5784 if (t1 == -1)
5785 return -1;
5786 if (t1 == t) {
5787 /* We found one solution, but it may not be the one we need.
5788 * Look for an earlier solution (if `fold` is 0), or a
5789 * later one (if `fold` is 1). */
5790 if (fold)
5791 u2 = u1 + max_fold_seconds;
5792 else
5793 u2 = u1 - max_fold_seconds;
5794 lt = local(u2);
5795 if (lt == -1)
5796 return -1;
5797 b = lt - u2;
5798 if (a == b)
5799 return u1;
5800 }
5801 else {
5802 b = t1 - u1;
5803 assert(a != b);
5804 }
5805 u2 = t - b;
5806 t2 = local(u2);
5807 if (t2 == -1)
5808 return -1;
5809 if (t2 == t)
5810 return u2;
5811 if (t1 == t)
5812 return u1;
5813 /* We have found both offsets a and b, but neither t - a nor t - b is
5814 * a solution. This means t is in the gap. */
5815 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5816}
5817
5818/* date(1970,1,1).toordinal() == 719163 */
5819#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5820
Tim Peters2a799bf2002-12-16 20:18:38 +00005821static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005822datetime_timestamp(PyDateTime_DateTime *self)
5823{
5824 PyObject *result;
5825
5826 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5827 PyObject *delta;
5828 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5829 if (delta == NULL)
5830 return NULL;
5831 result = delta_total_seconds(delta);
5832 Py_DECREF(delta);
5833 }
5834 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005835 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005836 seconds = local_to_seconds(GET_YEAR(self),
5837 GET_MONTH(self),
5838 GET_DAY(self),
5839 DATE_GET_HOUR(self),
5840 DATE_GET_MINUTE(self),
5841 DATE_GET_SECOND(self),
5842 DATE_GET_FOLD(self));
5843 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005844 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005845 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5846 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005847 }
5848 return result;
5849}
5850
5851static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005852datetime_getdate(PyDateTime_DateTime *self)
5853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005854 return new_date(GET_YEAR(self),
5855 GET_MONTH(self),
5856 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005857}
5858
5859static PyObject *
5860datetime_gettime(PyDateTime_DateTime *self)
5861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005862 return new_time(DATE_GET_HOUR(self),
5863 DATE_GET_MINUTE(self),
5864 DATE_GET_SECOND(self),
5865 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005866 Py_None,
5867 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005868}
5869
5870static PyObject *
5871datetime_gettimetz(PyDateTime_DateTime *self)
5872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005873 return new_time(DATE_GET_HOUR(self),
5874 DATE_GET_MINUTE(self),
5875 DATE_GET_SECOND(self),
5876 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005877 GET_DT_TZINFO(self),
5878 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005879}
5880
5881static PyObject *
5882datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005883{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005884 int y, m, d, hh, mm, ss;
5885 PyObject *tzinfo;
5886 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005887
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005888 tzinfo = GET_DT_TZINFO(self);
5889 if (tzinfo == Py_None) {
5890 utcself = self;
5891 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005892 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005893 else {
5894 PyObject *offset;
5895 offset = call_utcoffset(tzinfo, (PyObject *)self);
5896 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005897 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005898 if (offset == Py_None) {
5899 Py_DECREF(offset);
5900 utcself = self;
5901 Py_INCREF(utcself);
5902 }
5903 else {
5904 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5905 (PyDateTime_Delta *)offset, -1);
5906 Py_DECREF(offset);
5907 if (utcself == NULL)
5908 return NULL;
5909 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005910 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005911 y = GET_YEAR(utcself);
5912 m = GET_MONTH(utcself);
5913 d = GET_DAY(utcself);
5914 hh = DATE_GET_HOUR(utcself);
5915 mm = DATE_GET_MINUTE(utcself);
5916 ss = DATE_GET_SECOND(utcself);
5917
5918 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005919 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005920}
5921
Tim Peters371935f2003-02-01 01:52:50 +00005922/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005923
Tim Petersa9bc1682003-01-11 03:39:11 +00005924/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005925 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5926 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005927 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005928 */
5929static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005930datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005932 PyObject *basestate;
5933 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005935 basestate = PyBytes_FromStringAndSize((char *)self->data,
5936 _PyDateTime_DATETIME_DATASIZE);
5937 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005938 if (proto > 3 && DATE_GET_FOLD(self))
5939 /* Set the first bit of the third byte */
5940 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005941 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5942 result = PyTuple_Pack(1, basestate);
5943 else
5944 result = PyTuple_Pack(2, basestate, self->tzinfo);
5945 Py_DECREF(basestate);
5946 }
5947 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005948}
5949
5950static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005951datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005952{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005953 int proto;
5954 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005955 return NULL;
5956
5957 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005958}
5959
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005960static PyObject *
5961datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5962{
5963 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5964}
5965
Tim Petersa9bc1682003-01-11 03:39:11 +00005966static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005968 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005969
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005970 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005972 {"utcnow", (PyCFunction)datetime_utcnow,
5973 METH_NOARGS | METH_CLASS,
5974 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005976 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5977 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5978 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005980 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5981 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005982 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005984 {"strptime", (PyCFunction)datetime_strptime,
5985 METH_VARARGS | METH_CLASS,
5986 PyDoc_STR("string, format -> new datetime parsed from a string "
5987 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005989 {"combine", (PyCFunction)datetime_combine,
5990 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5991 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005992
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005993 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
5994 METH_O | METH_CLASS,
5995 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
5996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005997 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005999 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
6000 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006002 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6003 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006005 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6006 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006008 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6009 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006011 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6012 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006013
Alexander Belopolskya4415142012-06-08 12:33:09 -04006014 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6015 PyDoc_STR("Return POSIX timestamp as float.")},
6016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006017 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6018 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006020 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
6021 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006022 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006023 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006024 "defaults to 'T'.\n"
6025 "timespec specifies what components of the time to include"
6026 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6027 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006029 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6030 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006032 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6033 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006035 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6036 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006038 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
6039 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006041 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
6042 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006043
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006044 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006045 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006046
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006047 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6048 PyDoc_STR("__reduce__() -> (cls, state)")},
6049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006050 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006051};
6052
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006053static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006054PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6055\n\
6056The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006057instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006058
Tim Petersa9bc1682003-01-11 03:39:11 +00006059static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006060 datetime_add, /* nb_add */
6061 datetime_subtract, /* nb_subtract */
6062 0, /* nb_multiply */
6063 0, /* nb_remainder */
6064 0, /* nb_divmod */
6065 0, /* nb_power */
6066 0, /* nb_negative */
6067 0, /* nb_positive */
6068 0, /* nb_absolute */
6069 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006070};
6071
Neal Norwitz227b5332006-03-22 09:28:35 +00006072static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006073 PyVarObject_HEAD_INIT(NULL, 0)
6074 "datetime.datetime", /* tp_name */
6075 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6076 0, /* tp_itemsize */
6077 (destructor)datetime_dealloc, /* tp_dealloc */
6078 0, /* tp_print */
6079 0, /* tp_getattr */
6080 0, /* tp_setattr */
6081 0, /* tp_reserved */
6082 (reprfunc)datetime_repr, /* tp_repr */
6083 &datetime_as_number, /* tp_as_number */
6084 0, /* tp_as_sequence */
6085 0, /* tp_as_mapping */
6086 (hashfunc)datetime_hash, /* tp_hash */
6087 0, /* tp_call */
6088 (reprfunc)datetime_str, /* tp_str */
6089 PyObject_GenericGetAttr, /* tp_getattro */
6090 0, /* tp_setattro */
6091 0, /* tp_as_buffer */
6092 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6093 datetime_doc, /* tp_doc */
6094 0, /* tp_traverse */
6095 0, /* tp_clear */
6096 datetime_richcompare, /* tp_richcompare */
6097 0, /* tp_weaklistoffset */
6098 0, /* tp_iter */
6099 0, /* tp_iternext */
6100 datetime_methods, /* tp_methods */
6101 0, /* tp_members */
6102 datetime_getset, /* tp_getset */
6103 &PyDateTime_DateType, /* tp_base */
6104 0, /* tp_dict */
6105 0, /* tp_descr_get */
6106 0, /* tp_descr_set */
6107 0, /* tp_dictoffset */
6108 0, /* tp_init */
6109 datetime_alloc, /* tp_alloc */
6110 datetime_new, /* tp_new */
6111 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006112};
6113
6114/* ---------------------------------------------------------------------------
6115 * Module methods and initialization.
6116 */
6117
6118static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006119 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006120};
6121
Tim Peters9ddf40b2004-06-20 22:41:32 +00006122/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6123 * datetime.h.
6124 */
6125static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006126 &PyDateTime_DateType,
6127 &PyDateTime_DateTimeType,
6128 &PyDateTime_TimeType,
6129 &PyDateTime_DeltaType,
6130 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006131 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006132 new_date_ex,
6133 new_datetime_ex,
6134 new_time_ex,
6135 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006136 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006137 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006138 date_fromtimestamp,
6139 new_datetime_ex2,
6140 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006141};
6142
6143
Martin v. Löwis1a214512008-06-11 05:26:20 +00006144
6145static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006146 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006147 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006148 "Fast implementation of the datetime type.",
6149 -1,
6150 module_methods,
6151 NULL,
6152 NULL,
6153 NULL,
6154 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006155};
6156
Tim Peters2a799bf2002-12-16 20:18:38 +00006157PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006158PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006160 PyObject *m; /* a module object */
6161 PyObject *d; /* its dict */
6162 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006163 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006165 m = PyModule_Create(&datetimemodule);
6166 if (m == NULL)
6167 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006169 if (PyType_Ready(&PyDateTime_DateType) < 0)
6170 return NULL;
6171 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6172 return NULL;
6173 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6174 return NULL;
6175 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6176 return NULL;
6177 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6178 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006179 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6180 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006182 /* timedelta values */
6183 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006185 x = new_delta(0, 0, 1, 0);
6186 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6187 return NULL;
6188 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006190 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6191 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6192 return NULL;
6193 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006195 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6196 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6197 return NULL;
6198 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006200 /* date values */
6201 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006203 x = new_date(1, 1, 1);
6204 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6205 return NULL;
6206 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006208 x = new_date(MAXYEAR, 12, 31);
6209 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6210 return NULL;
6211 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006213 x = new_delta(1, 0, 0, 0);
6214 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6215 return NULL;
6216 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006218 /* time values */
6219 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006220
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006221 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006222 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6223 return NULL;
6224 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006225
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006226 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006227 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6228 return NULL;
6229 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006231 x = new_delta(0, 0, 1, 0);
6232 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6233 return NULL;
6234 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006236 /* datetime values */
6237 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006238
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006239 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006240 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6241 return NULL;
6242 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006243
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006244 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006245 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6246 return NULL;
6247 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006249 x = new_delta(0, 0, 1, 0);
6250 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6251 return NULL;
6252 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006253
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006254 /* timezone values */
6255 d = PyDateTime_TimeZoneType.tp_dict;
6256
6257 delta = new_delta(0, 0, 0, 0);
6258 if (delta == NULL)
6259 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006260 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006261 Py_DECREF(delta);
6262 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6263 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006264 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006265 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006266
6267 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6268 if (delta == NULL)
6269 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006270 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006271 Py_DECREF(delta);
6272 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6273 return NULL;
6274 Py_DECREF(x);
6275
6276 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6277 if (delta == NULL)
6278 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006279 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006280 Py_DECREF(delta);
6281 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6282 return NULL;
6283 Py_DECREF(x);
6284
Alexander Belopolskya4415142012-06-08 12:33:09 -04006285 /* Epoch */
6286 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006287 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006288 if (PyDateTime_Epoch == NULL)
6289 return NULL;
6290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006291 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006292 PyModule_AddIntMacro(m, MINYEAR);
6293 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006295 Py_INCREF(&PyDateTime_DateType);
6296 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006298 Py_INCREF(&PyDateTime_DateTimeType);
6299 PyModule_AddObject(m, "datetime",
6300 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006302 Py_INCREF(&PyDateTime_TimeType);
6303 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006305 Py_INCREF(&PyDateTime_DeltaType);
6306 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006308 Py_INCREF(&PyDateTime_TZInfoType);
6309 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006310
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006311 Py_INCREF(&PyDateTime_TimeZoneType);
6312 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006314 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6315 if (x == NULL)
6316 return NULL;
6317 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006319 /* A 4-year cycle has an extra leap day over what we'd get from
6320 * pasting together 4 single years.
6321 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006322 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006323 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006325 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6326 * get from pasting together 4 100-year cycles.
6327 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006328 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006329 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006331 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6332 * pasting together 25 4-year cycles.
6333 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006334 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006335 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006337 us_per_ms = PyLong_FromLong(1000);
6338 us_per_second = PyLong_FromLong(1000000);
6339 us_per_minute = PyLong_FromLong(60000000);
6340 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006341 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006342 us_per_minute == NULL || seconds_per_day == NULL)
6343 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006345 /* The rest are too big for 32-bit ints, but even
6346 * us_per_week fits in 40 bits, so doubles should be exact.
6347 */
6348 us_per_hour = PyLong_FromDouble(3600000000.0);
6349 us_per_day = PyLong_FromDouble(86400000000.0);
6350 us_per_week = PyLong_FromDouble(604800000000.0);
6351 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6352 return NULL;
6353 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006354}
Tim Petersf3615152003-01-01 21:51:37 +00006355
6356/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006357Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006358 x.n = x stripped of its timezone -- its naive time.
6359 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006360 return None
Tim Petersf3615152003-01-01 21:51:37 +00006361 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006362 return None
Tim Petersf3615152003-01-01 21:51:37 +00006363 x.s = x's standard offset, x.o - x.d
6364
6365Now some derived rules, where k is a duration (timedelta).
6366
63671. x.o = x.s + x.d
6368 This follows from the definition of x.s.
6369
Tim Petersc5dc4da2003-01-02 17:55:03 +000063702. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006371 This is actually a requirement, an assumption we need to make about
6372 sane tzinfo classes.
6373
63743. The naive UTC time corresponding to x is x.n - x.o.
6375 This is again a requirement for a sane tzinfo class.
6376
63774. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006378 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006379
Tim Petersc5dc4da2003-01-02 17:55:03 +000063805. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006381 Again follows from how arithmetic is defined.
6382
Tim Peters8bb5ad22003-01-24 02:44:45 +00006383Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006384(meaning that the various tzinfo methods exist, and don't blow up or return
6385None when called).
6386
Tim Petersa9bc1682003-01-11 03:39:11 +00006387The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006388x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006389
6390By #3, we want
6391
Tim Peters8bb5ad22003-01-24 02:44:45 +00006392 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006393
6394The algorithm starts by attaching tz to x.n, and calling that y. So
6395x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6396becomes true; in effect, we want to solve [2] for k:
6397
Tim Peters8bb5ad22003-01-24 02:44:45 +00006398 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006399
6400By #1, this is the same as
6401
Tim Peters8bb5ad22003-01-24 02:44:45 +00006402 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006403
6404By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6405Substituting that into [3],
6406
Tim Peters8bb5ad22003-01-24 02:44:45 +00006407 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6408 k - (y+k).s - (y+k).d = 0; rearranging,
6409 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6410 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006411
Tim Peters8bb5ad22003-01-24 02:44:45 +00006412On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6413approximate k by ignoring the (y+k).d term at first. Note that k can't be
6414very large, since all offset-returning methods return a duration of magnitude
6415less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6416be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006417
6418In any case, the new value is
6419
Tim Peters8bb5ad22003-01-24 02:44:45 +00006420 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006421
Tim Peters8bb5ad22003-01-24 02:44:45 +00006422It's helpful to step back at look at [4] from a higher level: it's simply
6423mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006424
6425At this point, if
6426
Tim Peters8bb5ad22003-01-24 02:44:45 +00006427 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006428
6429we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006430at the start of daylight time. Picture US Eastern for concreteness. The wall
6431time 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 +00006432sense then. The docs ask that an Eastern tzinfo class consider such a time to
6433be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6434on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006435the only spelling that makes sense on the local wall clock.
6436
Tim Petersc5dc4da2003-01-02 17:55:03 +00006437In fact, if [5] holds at this point, we do have the standard-time spelling,
6438but that takes a bit of proof. We first prove a stronger result. What's the
6439difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006440
Tim Peters8bb5ad22003-01-24 02:44:45 +00006441 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006442
Tim Petersc5dc4da2003-01-02 17:55:03 +00006443Now
6444 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006445 (y + y.s).n = by #5
6446 y.n + y.s = since y.n = x.n
6447 x.n + y.s = since z and y are have the same tzinfo member,
6448 y.s = z.s by #2
6449 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006450
Tim Petersc5dc4da2003-01-02 17:55:03 +00006451Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006452
Tim Petersc5dc4da2003-01-02 17:55:03 +00006453 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006454 x.n - ((x.n + z.s) - z.o) = expanding
6455 x.n - x.n - z.s + z.o = cancelling
6456 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006457 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006458
Tim Petersc5dc4da2003-01-02 17:55:03 +00006459So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006460
Tim Petersc5dc4da2003-01-02 17:55:03 +00006461If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006462spelling we wanted in the endcase described above. We're done. Contrarily,
6463if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006464
Tim Petersc5dc4da2003-01-02 17:55:03 +00006465If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6466add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006467local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006468
Tim Petersc5dc4da2003-01-02 17:55:03 +00006469Let
Tim Petersf3615152003-01-01 21:51:37 +00006470
Tim Peters4fede1a2003-01-04 00:26:59 +00006471 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006472
Tim Peters4fede1a2003-01-04 00:26:59 +00006473and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006474
Tim Peters8bb5ad22003-01-24 02:44:45 +00006475 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006476
Tim Peters8bb5ad22003-01-24 02:44:45 +00006477If so, we're done. If not, the tzinfo class is insane, according to the
6478assumptions we've made. This also requires a bit of proof. As before, let's
6479compute the difference between the LHS and RHS of [8] (and skipping some of
6480the justifications for the kinds of substitutions we've done several times
6481already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006482
Tim Peters8bb5ad22003-01-24 02:44:45 +00006483 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006484 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6485 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6486 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6487 - z.n + z.n - z.o + z'.o = cancel z.n
6488 - z.o + z'.o = #1 twice
6489 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6490 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006491
6492So 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 +00006493we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6494return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006495
Tim Peters8bb5ad22003-01-24 02:44:45 +00006496How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6497a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6498would have to change the result dst() returns: we start in DST, and moving
6499a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006500
Tim Peters8bb5ad22003-01-24 02:44:45 +00006501There isn't a sane case where this can happen. The closest it gets is at
6502the end of DST, where there's an hour in UTC with no spelling in a hybrid
6503tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6504that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6505UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6506time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6507clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6508standard time. Since that's what the local clock *does*, we want to map both
6509UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006510in local time, but so it goes -- it's the way the local clock works.
6511
Tim Peters8bb5ad22003-01-24 02:44:45 +00006512When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6513so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6514z' = 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 +00006515(correctly) concludes that z' is not UTC-equivalent to x.
6516
6517Because we know z.d said z was in daylight time (else [5] would have held and
6518we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006519and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006520return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6521but the reasoning doesn't depend on the example -- it depends on there being
6522two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006523z' must be in standard time, and is the spelling we want in this case.
6524
6525Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6526concerned (because it takes z' as being in standard time rather than the
6527daylight time we intend here), but returning it gives the real-life "local
6528clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6529tz.
6530
6531When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6532the 1:MM standard time spelling we want.
6533
6534So how can this break? One of the assumptions must be violated. Two
6535possibilities:
6536
65371) [2] effectively says that y.s is invariant across all y belong to a given
6538 time zone. This isn't true if, for political reasons or continental drift,
6539 a region decides to change its base offset from UTC.
6540
65412) There may be versions of "double daylight" time where the tail end of
6542 the analysis gives up a step too early. I haven't thought about that
6543 enough to say.
6544
6545In any case, it's clear that the default fromutc() is strong enough to handle
6546"almost all" time zones: so long as the standard offset is invariant, it
6547doesn't matter if daylight time transition points change from year to year, or
6548if daylight time is skipped in some years; it doesn't matter how large or
6549small dst() may get within its bounds; and it doesn't even matter if some
6550perverse time zone returns a negative dst()). So a breaking case must be
6551pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006552--------------------------------------------------------------------------- */