blob: 91d6991b2af99d5e313b7aa059c3c7718f92cc35 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
Tim Peters2a799bf2002-12-16 20:18:38 +00006#include "structmember.h"
7
8#include <time.h>
9
Victor Stinner09e5cf22015-03-30 00:09:18 +020010#ifdef MS_WINDOWS
11# include <winsock2.h> /* struct timeval */
12#endif
13
Tim Peters9ddf40b2004-06-20 22:41:32 +000014/* Differentiate between building the core module and building extension
15 * modules.
16 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000017#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000018#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000019#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000020#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000021#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000022
Larry Hastings61272b72014-01-07 12:41:53 -080023/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080024module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080025class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Larry Hastings61272b72014-01-07 12:41:53 -080026[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -080027/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080028
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030029#include "clinic/_datetimemodule.c.h"
30
Tim Peters2a799bf2002-12-16 20:18:38 +000031/* We require that C int be at least 32 bits, and use int virtually
32 * everywhere. In just a few cases we use a temp long, where a Python
33 * API returns a C long. In such cases, we have to ensure that the
34 * final result fits in a C int (this can be an issue on 64-bit boxes).
35 */
36#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000037# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000038#endif
39
40#define MINYEAR 1
41#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000042#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000043
44/* Nine decimal digits is easy to communicate, and leaves enough room
45 * so that two delta days can be added w/o fear of overflowing a signed
46 * 32-bit int, and with plenty of room left over to absorb any possible
47 * carries from adding seconds.
48 */
49#define MAX_DELTA_DAYS 999999999
50
51/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define GET_YEAR PyDateTime_GET_YEAR
53#define GET_MONTH PyDateTime_GET_MONTH
54#define GET_DAY PyDateTime_GET_DAY
55#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
56#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
57#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
58#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040059#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000060
61/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
63 ((o)->data[1] = ((v) & 0x00ff)))
64#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
65#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000066
67/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
69#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
70#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
71#define DATE_SET_MICROSECOND(o, v) \
72 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
73 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
74 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040075#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000076
77/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
79#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
80#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
81#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040082#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
84#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
85#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
86#define TIME_SET_MICROSECOND(o, v) \
87 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
88 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
89 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040090#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000091
92/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
94#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
95#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097#define SET_TD_DAYS(o, v) ((o)->days = (v))
98#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000099#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
100
Tim Petersa032d2e2003-01-11 00:15:54 +0000101/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
102 * p->hastzinfo.
103 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000104#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
105#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
106 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
107#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
108 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000109/* M is a char or int claiming to be a valid month. The macro is equivalent
110 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000112 */
113#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
114
Tim Peters2a799bf2002-12-16 20:18:38 +0000115/* Forward declarations. */
116static PyTypeObject PyDateTime_DateType;
117static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000118static PyTypeObject PyDateTime_DeltaType;
119static PyTypeObject PyDateTime_TimeType;
120static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000121static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000122
Victor Stinnerb67f0962017-02-10 10:34:02 +0100123static int check_tzinfo_subclass(PyObject *p);
124
Martin v. Löwise75fc142013-11-07 18:46:53 +0100125_Py_IDENTIFIER(as_integer_ratio);
126_Py_IDENTIFIER(fromutc);
127_Py_IDENTIFIER(isoformat);
128_Py_IDENTIFIER(strftime);
129
Tim Peters2a799bf2002-12-16 20:18:38 +0000130/* ---------------------------------------------------------------------------
131 * Math utilities.
132 */
133
134/* k = i+j overflows iff k differs in sign from both inputs,
135 * iff k^i has sign bit set and k^j has sign bit set,
136 * iff (k^i)&(k^j) has sign bit set.
137 */
138#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000140
141/* Compute Python divmod(x, y), returning the quotient and storing the
142 * remainder into *r. The quotient is the floor of x/y, and that's
143 * the real point of this. C will probably truncate instead (C99
144 * requires truncation; C89 left it implementation-defined).
145 * Simplification: we *require* that y > 0 here. That's appropriate
146 * for all the uses made of it. This simplifies the code and makes
147 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
148 * overflow case).
149 */
150static int
151divmod(int x, int y, int *r)
152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 assert(y > 0);
156 quo = x / y;
157 *r = x - quo * y;
158 if (*r < 0) {
159 --quo;
160 *r += y;
161 }
162 assert(0 <= *r && *r < y);
163 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000164}
165
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000166/* Nearest integer to m / n for integers m and n. Half-integer results
167 * are rounded to even.
168 */
169static PyObject *
170divide_nearest(PyObject *m, PyObject *n)
171{
172 PyObject *result;
173 PyObject *temp;
174
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000175 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000176 if (temp == NULL)
177 return NULL;
178 result = PyTuple_GET_ITEM(temp, 0);
179 Py_INCREF(result);
180 Py_DECREF(temp);
181
182 return result;
183}
184
Tim Peters2a799bf2002-12-16 20:18:38 +0000185/* ---------------------------------------------------------------------------
186 * General calendrical helper functions
187 */
188
189/* For each month ordinal in 1..12, the number of days in that month,
190 * and the number of days before that month in the same year. These
191 * are correct for non-leap years only.
192 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200193static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 0, /* unused; this vector uses 1-based indexing */
195 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000196};
197
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200198static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 0, /* unused; this vector uses 1-based indexing */
200 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000201};
202
203/* year -> 1 if leap year, else 0. */
204static int
205is_leap(int year)
206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* Cast year to unsigned. The result is the same either way, but
208 * C can generate faster code for unsigned mod than for signed
209 * mod (especially for % 4 -- a good compiler should just grab
210 * the last 2 bits when the LHS is unsigned).
211 */
212 const unsigned int ayear = (unsigned int)year;
213 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000214}
215
216/* year, month -> number of days in that month in that year */
217static int
218days_in_month(int year, int month)
219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 assert(month >= 1);
221 assert(month <= 12);
222 if (month == 2 && is_leap(year))
223 return 29;
224 else
225 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000226}
227
Martin Panter46f50722016-05-26 05:35:26 +0000228/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000229static int
230days_before_month(int year, int month)
231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 assert(month >= 1);
235 assert(month <= 12);
236 days = _days_before_month[month];
237 if (month > 2 && is_leap(year))
238 ++days;
239 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000240}
241
242/* year -> number of days before January 1st of year. Remember that we
243 * start with year 1, so days_before_year(1) == 0.
244 */
245static int
246days_before_year(int year)
247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 int y = year - 1;
249 /* This is incorrect if year <= 0; we really want the floor
250 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000251 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000253 assert (year >= 1);
254 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000255}
256
257/* Number of days in 4, 100, and 400 year cycles. That these have
258 * the correct values is asserted in the module init function.
259 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260#define DI4Y 1461 /* days_before_year(5); days in 4 years */
261#define DI100Y 36524 /* days_before_year(101); days in 100 years */
262#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000263
264/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
265static void
266ord_to_ymd(int ordinal, int *year, int *month, int *day)
267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
271 * leap years repeats exactly every 400 years. The basic strategy is
272 * to find the closest 400-year boundary at or before ordinal, then
273 * work with the offset from that boundary to ordinal. Life is much
274 * clearer if we subtract 1 from ordinal first -- then the values
275 * of ordinal at 400-year boundaries are exactly those divisible
276 * by DI400Y:
277 *
278 * D M Y n n-1
279 * -- --- ---- ---------- ----------------
280 * 31 Dec -400 -DI400Y -DI400Y -1
281 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
282 * ...
283 * 30 Dec 000 -1 -2
284 * 31 Dec 000 0 -1
285 * 1 Jan 001 1 0 400-year boundary
286 * 2 Jan 001 2 1
287 * 3 Jan 001 3 2
288 * ...
289 * 31 Dec 400 DI400Y DI400Y -1
290 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
291 */
292 assert(ordinal >= 1);
293 --ordinal;
294 n400 = ordinal / DI400Y;
295 n = ordinal % DI400Y;
296 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 /* Now n is the (non-negative) offset, in days, from January 1 of
299 * year, to the desired date. Now compute how many 100-year cycles
300 * precede n.
301 * Note that it's possible for n100 to equal 4! In that case 4 full
302 * 100-year cycles precede the desired day, which implies the
303 * desired day is December 31 at the end of a 400-year cycle.
304 */
305 n100 = n / DI100Y;
306 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 /* Now compute how many 4-year cycles precede it. */
309 n4 = n / DI4Y;
310 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 /* And now how many single years. Again n1 can be 4, and again
313 * meaning that the desired day is December 31 at the end of the
314 * 4-year cycle.
315 */
316 n1 = n / 365;
317 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 *year += n100 * 100 + n4 * 4 + n1;
320 if (n1 == 4 || n100 == 4) {
321 assert(n == 0);
322 *year -= 1;
323 *month = 12;
324 *day = 31;
325 return;
326 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 /* Now the year is correct, and n is the offset from January 1. We
329 * find the month via an estimate that's either exact or one too
330 * large.
331 */
332 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
333 assert(leapyear == is_leap(*year));
334 *month = (n + 50) >> 5;
335 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
336 if (preceding > n) {
337 /* estimate is too large */
338 *month -= 1;
339 preceding -= days_in_month(*year, *month);
340 }
341 n -= preceding;
342 assert(0 <= n);
343 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000346}
347
348/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
349static int
350ymd_to_ord(int year, int month, int day)
351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000353}
354
355/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
356static int
357weekday(int year, int month, int day)
358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000360}
361
362/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
363 * first calendar week containing a Thursday.
364 */
365static int
366iso_week1_monday(int year)
367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
369 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
370 int first_weekday = (first_day + 6) % 7;
371 /* ordinal of closest Monday at or before 1/1 */
372 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
375 week1_monday += 7;
376 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000377}
378
379/* ---------------------------------------------------------------------------
380 * Range checkers.
381 */
382
383/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
384 * If not, raise OverflowError and return -1.
385 */
386static int
387check_delta_day_range(int days)
388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
390 return 0;
391 PyErr_Format(PyExc_OverflowError,
392 "days=%d; must have magnitude <= %d",
393 days, MAX_DELTA_DAYS);
394 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000395}
396
397/* Check that date arguments are in range. Return 0 if they are. If they
398 * aren't, raise ValueError and return -1.
399 */
400static int
401check_date_args(int year, int month, int day)
402{
403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 if (year < MINYEAR || year > MAXYEAR) {
Victor Stinnerb67f0962017-02-10 10:34:02 +0100405 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 return -1;
407 }
408 if (month < 1 || month > 12) {
409 PyErr_SetString(PyExc_ValueError,
410 "month must be in 1..12");
411 return -1;
412 }
413 if (day < 1 || day > days_in_month(year, month)) {
414 PyErr_SetString(PyExc_ValueError,
415 "day is out of range for month");
416 return -1;
417 }
418 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000419}
420
421/* Check that time arguments are in range. Return 0 if they are. If they
422 * aren't, raise ValueError and return -1.
423 */
424static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400425check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 if (h < 0 || h > 23) {
428 PyErr_SetString(PyExc_ValueError,
429 "hour must be in 0..23");
430 return -1;
431 }
432 if (m < 0 || m > 59) {
433 PyErr_SetString(PyExc_ValueError,
434 "minute must be in 0..59");
435 return -1;
436 }
437 if (s < 0 || s > 59) {
438 PyErr_SetString(PyExc_ValueError,
439 "second must be in 0..59");
440 return -1;
441 }
442 if (us < 0 || us > 999999) {
443 PyErr_SetString(PyExc_ValueError,
444 "microsecond must be in 0..999999");
445 return -1;
446 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400447 if (fold != 0 && fold != 1) {
448 PyErr_SetString(PyExc_ValueError,
449 "fold must be either 0 or 1");
450 return -1;
451 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000453}
454
455/* ---------------------------------------------------------------------------
456 * Normalization utilities.
457 */
458
459/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
460 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
461 * at least factor, enough of *lo is converted into "hi" units so that
462 * 0 <= *lo < factor. The input values must be such that int overflow
463 * is impossible.
464 */
465static void
466normalize_pair(int *hi, int *lo, int factor)
467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 assert(factor > 0);
469 assert(lo != hi);
470 if (*lo < 0 || *lo >= factor) {
471 const int num_hi = divmod(*lo, factor, lo);
472 const int new_hi = *hi + num_hi;
473 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
474 *hi = new_hi;
475 }
476 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000477}
478
479/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 * 0 <= *s < 24*3600
481 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000482 * The input values must be such that the internals don't overflow.
483 * The way this routine is used, we don't get close.
484 */
485static void
486normalize_d_s_us(int *d, int *s, int *us)
487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 if (*us < 0 || *us >= 1000000) {
489 normalize_pair(s, us, 1000000);
490 /* |s| can't be bigger than about
491 * |original s| + |original us|/1000000 now.
492 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 }
495 if (*s < 0 || *s >= 24*3600) {
496 normalize_pair(d, s, 24*3600);
497 /* |d| can't be bigger than about
498 * |original d| +
499 * (|original s| + |original us|/1000000) / (24*3600) now.
500 */
501 }
502 assert(0 <= *s && *s < 24*3600);
503 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000504}
505
506/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 * 1 <= *m <= 12
508 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000509 * The input values must be such that the internals don't overflow.
510 * The way this routine is used, we don't get close.
511 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000512static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000513normalize_y_m_d(int *y, int *m, int *d)
514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000516
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000517 /* In actual use, m is always the month component extracted from a
518 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 /* Now only day can be out of bounds (year may also be out of bounds
524 * for a datetime object, but we don't care about that here).
525 * If day is out of bounds, what to do is arguable, but at least the
526 * method here is principled and explainable.
527 */
528 dim = days_in_month(*y, *m);
529 if (*d < 1 || *d > dim) {
530 /* Move day-1 days from the first of the month. First try to
531 * get off cheap if we're only one day out of range
532 * (adjustments for timezone alone can't be worse than that).
533 */
534 if (*d == 0) {
535 --*m;
536 if (*m > 0)
537 *d = days_in_month(*y, *m);
538 else {
539 --*y;
540 *m = 12;
541 *d = 31;
542 }
543 }
544 else if (*d == dim + 1) {
545 /* move forward a day */
546 ++*m;
547 *d = 1;
548 if (*m > 12) {
549 *m = 1;
550 ++*y;
551 }
552 }
553 else {
554 int ordinal = ymd_to_ord(*y, *m, 1) +
555 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000556 if (ordinal < 1 || ordinal > MAXORDINAL) {
557 goto error;
558 } else {
559 ord_to_ymd(ordinal, y, m, d);
560 return 0;
561 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 }
563 }
564 assert(*m > 0);
565 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000566 if (MINYEAR <= *y && *y <= MAXYEAR)
567 return 0;
568 error:
569 PyErr_SetString(PyExc_OverflowError,
570 "date value out of range");
571 return -1;
572
Tim Peters2a799bf2002-12-16 20:18:38 +0000573}
574
575/* Fiddle out-of-bounds months and days so that the result makes some kind
576 * of sense. The parameters are both inputs and outputs. Returns < 0 on
577 * failure, where failure means the adjusted year is out of bounds.
578 */
579static int
580normalize_date(int *year, int *month, int *day)
581{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000582 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000583}
584
585/* Force all the datetime fields into range. The parameters are both
586 * inputs and outputs. Returns < 0 on error.
587 */
588static int
589normalize_datetime(int *year, int *month, int *day,
590 int *hour, int *minute, int *second,
591 int *microsecond)
592{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 normalize_pair(second, microsecond, 1000000);
594 normalize_pair(minute, second, 60);
595 normalize_pair(hour, minute, 60);
596 normalize_pair(day, hour, 24);
597 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000598}
599
600/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000601 * Basic object allocation: tp_alloc implementations. These allocate
602 * Python objects of the right size and type, and do the Python object-
603 * initialization bit. If there's not enough memory, they return NULL after
604 * setting MemoryError. All data members remain uninitialized trash.
605 *
606 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000607 * member is needed. This is ugly, imprecise, and possibly insecure.
608 * tp_basicsize for the time and datetime types is set to the size of the
609 * struct that has room for the tzinfo member, so subclasses in Python will
610 * allocate enough space for a tzinfo member whether or not one is actually
611 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
612 * part is that PyType_GenericAlloc() (which subclasses in Python end up
613 * using) just happens today to effectively ignore the nitems argument
614 * when tp_itemsize is 0, which it is for these type objects. If that
615 * changes, perhaps the callers of tp_alloc slots in this file should
616 * be changed to force a 0 nitems argument unless the type being allocated
617 * is a base type implemented in this file (so that tp_alloc is time_alloc
618 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000619 */
620
621static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000622time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 self = (PyObject *)
627 PyObject_MALLOC(aware ?
628 sizeof(PyDateTime_Time) :
629 sizeof(_PyDateTime_BaseTime));
630 if (self == NULL)
631 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100632 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000634}
635
636static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000637datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 self = (PyObject *)
642 PyObject_MALLOC(aware ?
643 sizeof(PyDateTime_DateTime) :
644 sizeof(_PyDateTime_BaseDateTime));
645 if (self == NULL)
646 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100647 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000649}
650
651/* ---------------------------------------------------------------------------
652 * Helpers for setting object fields. These work on pointers to the
653 * appropriate base class.
654 */
655
656/* For date and datetime. */
657static void
658set_date_fields(PyDateTime_Date *self, int y, int m, int d)
659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 self->hashcode = -1;
661 SET_YEAR(self, y);
662 SET_MONTH(self, m);
663 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000664}
665
666/* ---------------------------------------------------------------------------
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500667 * String parsing utilities and helper functions
668 */
669
670static const char*
671parse_digits(const char* ptr, int* var, size_t num_digits)
672{
673 for (size_t i = 0; i < num_digits; ++i) {
674 unsigned int tmp = (unsigned int)(*(ptr++) - '0');
675 if (tmp > 9) {
676 return NULL;
677 }
678 *var *= 10;
679 *var += (signed int)tmp;
680 }
681
682 return ptr;
683}
684
685static int parse_isoformat_date(const char *dtstr,
686 int* year, int *month, int* day) {
687 /* Parse the date components of the result of date.isoformat()
688 *
689 * Return codes:
690 * 0: Success
691 * -1: Failed to parse date component
692 * -2: Failed to parse dateseparator
693 */
694 const char *p = dtstr;
695 p = parse_digits(p, year, 4);
696 if (NULL == p) {
697 return -1;
698 }
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100699
Paul Ganssle09dc2f52017-12-21 00:33:49 -0500700 if (*(p++) != '-') {
701 return -2;
702 }
703
704 p = parse_digits(p, month, 2);
705 if (NULL == p) {
706 return -1;
707 }
708
709 if (*(p++) != '-') {
710 return -2;
711 }
712
713 p = parse_digits(p, day, 2);
714 if (p == NULL) {
715 return -1;
716 }
717
718 return 0;
719}
720
721static int
722parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end,
723 int* hour, int* minute, int *second, int *microsecond) {
724 const char *p = tstr;
725 const char *p_end = tstr_end;
726 int *vals[3] = {hour, minute, second};
727
728 // Parse [HH[:MM[:SS]]]
729 for (size_t i = 0; i < 3; ++i) {
730 p = parse_digits(p, vals[i], 2);
731 if (NULL == p) {
732 return -3;
733 }
734
735 char c = *(p++);
736 if (p >= p_end) {
737 return c != '\0';
738 } else if (c == ':') {
739 continue;
740 } else if (c == '.') {
741 break;
742 } else {
743 return -4; // Malformed time separator
744 }
745 }
746
747 // Parse .fff[fff]
748 size_t len_remains = p_end - p;
749 if (!(len_remains == 6 || len_remains == 3)) {
750 return -3;
751 }
752
753 p = parse_digits(p, microsecond, len_remains);
754 if (NULL == p) {
755 return -3;
756 }
757
758 if (len_remains == 3) {
759 *microsecond *= 1000;
760 }
761
762 // Return 1 if it's not the end of the string
763 return *p != '\0';
764}
765
766static int
767parse_isoformat_time(const char *dtstr, size_t dtlen,
768 int* hour, int *minute, int *second, int *microsecond,
769 int* tzoffset, int *tzmicrosecond) {
770 // Parse the time portion of a datetime.isoformat() string
771 //
772 // Return codes:
773 // 0: Success (no tzoffset)
774 // 1: Success (with tzoffset)
775 // -3: Failed to parse time component
776 // -4: Failed to parse time separator
777 // -5: Malformed timezone string
778
779 const char *p = dtstr;
780 const char *p_end = dtstr + dtlen;
781
782 const char *tzinfo_pos = p;
783 do {
784 if (*tzinfo_pos == '+' || *tzinfo_pos == '-') {
785 break;
786 }
787 } while(++tzinfo_pos < p_end);
788
789 int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos,
790 hour, minute, second, microsecond);
791
792 if (rv < 0) {
793 return rv;
794 } else if (tzinfo_pos == p_end) {
795 // We know that there's no time zone, so if there's stuff at the
796 // end of the string it's an error.
797 if (rv == 1) {
798 return -5;
799 } else {
800 return 0;
801 }
802 }
803
804 // Parse time zone component
805 // Valid formats are:
806 // - +HH:MM (len 6)
807 // - +HH:MM:SS (len 9)
808 // - +HH:MM:SS.ffffff (len 16)
809 size_t tzlen = p_end - tzinfo_pos;
810 if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) {
811 return -5;
812 }
813
814 int tzsign = (*tzinfo_pos == '-')?-1:1;
815 tzinfo_pos++;
816 int tzhour = 0, tzminute = 0, tzsecond = 0;
817 rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end,
818 &tzhour, &tzminute, &tzsecond, tzmicrosecond);
819
820 *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
821 *tzmicrosecond *= tzsign;
822
823 return rv?-5:1;
824}
825
826
827/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000828 * Create various objects, mostly without range checking.
829 */
830
831/* Create a date instance with no range checking. */
832static PyObject *
833new_date_ex(int year, int month, int day, PyTypeObject *type)
834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000836
Victor Stinnerb67f0962017-02-10 10:34:02 +0100837 if (check_date_args(year, month, day) < 0) {
838 return NULL;
839 }
840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
842 if (self != NULL)
843 set_date_fields(self, year, month, day);
844 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000845}
846
847#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000849
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500850// Forward declaration
851static PyObject * new_datetime_ex(int, int, int, int, int, int, int,
852 PyObject*, PyTypeObject*);
853
854/* Create date instance with no range checking, or call subclass constructor */
855static PyObject *
856new_date_subclass_ex(int year, int month, int day, PyObject *cls) {
857 PyObject *result;
858 // We have "fast path" constructors for two subclasses: date and datetime
859 if ((PyTypeObject *)cls == &PyDateTime_DateType) {
860 result = new_date_ex(year, month, day, (PyTypeObject *)cls);
861 } else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) {
862 result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None,
863 (PyTypeObject *)cls);
864 } else {
865 result = PyObject_CallFunction(cls, "iii", year, month, day);
866 }
867
868 return result;
869}
870
Tim Petersb0c854d2003-05-17 15:57:00 +0000871/* Create a datetime instance with no range checking. */
872static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400873new_datetime_ex2(int year, int month, int day, int hour, int minute,
874 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 PyDateTime_DateTime *self;
877 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000878
Victor Stinnerb67f0962017-02-10 10:34:02 +0100879 if (check_date_args(year, month, day) < 0) {
880 return NULL;
881 }
882 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
883 return NULL;
884 }
885 if (check_tzinfo_subclass(tzinfo) < 0) {
886 return NULL;
887 }
888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
890 if (self != NULL) {
891 self->hastzinfo = aware;
892 set_date_fields((PyDateTime_Date *)self, year, month, day);
893 DATE_SET_HOUR(self, hour);
894 DATE_SET_MINUTE(self, minute);
895 DATE_SET_SECOND(self, second);
896 DATE_SET_MICROSECOND(self, usecond);
897 if (aware) {
898 Py_INCREF(tzinfo);
899 self->tzinfo = tzinfo;
900 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400901 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 }
903 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000904}
905
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400906static PyObject *
907new_datetime_ex(int year, int month, int day, int hour, int minute,
908 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
909{
910 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
911 tzinfo, 0, type);
912}
913
914#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
915 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000917
Paul Ganssle9f1b7b92018-01-16 13:06:31 -0500918static PyObject *
919new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute,
920 int second, int usecond, PyObject *tzinfo,
921 int fold, PyObject *cls) {
922 PyObject* dt;
923 if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) {
924 // Use the fast path constructor
925 dt = new_datetime(year, month, day, hour, minute, second, usecond,
926 tzinfo, fold);
927 } else {
928 // Subclass
929 dt = PyObject_CallFunction(cls, "iiiiiiiO",
930 year,
931 month,
932 day,
933 hour,
934 minute,
935 second,
936 usecond,
937 tzinfo);
938 }
939
940 return dt;
941}
942
943static PyObject *
944new_datetime_subclass_ex(int year, int month, int day, int hour, int minute,
945 int second, int usecond, PyObject *tzinfo,
946 PyObject *cls) {
947 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
948 second, usecond, tzinfo, 0,
949 cls);
950}
951
Tim Petersb0c854d2003-05-17 15:57:00 +0000952/* Create a time instance with no range checking. */
953static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400954new_time_ex2(int hour, int minute, int second, int usecond,
955 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 PyDateTime_Time *self;
958 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000959
Victor Stinnerb67f0962017-02-10 10:34:02 +0100960 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
961 return NULL;
962 }
963 if (check_tzinfo_subclass(tzinfo) < 0) {
964 return NULL;
965 }
966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
968 if (self != NULL) {
969 self->hastzinfo = aware;
970 self->hashcode = -1;
971 TIME_SET_HOUR(self, hour);
972 TIME_SET_MINUTE(self, minute);
973 TIME_SET_SECOND(self, second);
974 TIME_SET_MICROSECOND(self, usecond);
975 if (aware) {
976 Py_INCREF(tzinfo);
977 self->tzinfo = tzinfo;
978 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400979 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 }
981 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000982}
983
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400984static PyObject *
985new_time_ex(int hour, int minute, int second, int usecond,
986 PyObject *tzinfo, PyTypeObject *type)
987{
988 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
989}
990
991#define new_time(hh, mm, ss, us, tzinfo, fold) \
992 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000993
994/* Create a timedelta instance. Normalize the members iff normalize is
995 * true. Passing false is a speed optimization, if you know for sure
996 * that seconds and microseconds are already in their proper ranges. In any
997 * case, raises OverflowError and returns NULL if the normalized days is out
998 * of range).
999 */
1000static PyObject *
1001new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +00001003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 if (normalize)
1007 normalize_d_s_us(&days, &seconds, &microseconds);
1008 assert(0 <= seconds && seconds < 24*3600);
1009 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +00001010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 if (check_delta_day_range(days) < 0)
1012 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
1015 if (self != NULL) {
1016 self->hashcode = -1;
1017 SET_TD_DAYS(self, days);
1018 SET_TD_SECONDS(self, seconds);
1019 SET_TD_MICROSECONDS(self, microseconds);
1020 }
1021 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +00001022}
1023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024#define new_delta(d, s, us, normalize) \
1025 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001026
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001027
1028typedef struct
1029{
1030 PyObject_HEAD
1031 PyObject *offset;
1032 PyObject *name;
1033} PyDateTime_TimeZone;
1034
Victor Stinner6ced7c42011-03-21 18:15:42 +01001035/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001036static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -04001037/* The interned Epoch datetime instance */
1038static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00001039
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001040/* Create new timezone instance checking offset range. This
1041 function does not check the name argument. Caller must assure
1042 that offset is a timedelta instance and name is either NULL
1043 or a unicode object. */
1044static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001045create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001046{
1047 PyDateTime_TimeZone *self;
1048 PyTypeObject *type = &PyDateTime_TimeZoneType;
1049
1050 assert(offset != NULL);
1051 assert(PyDelta_Check(offset));
1052 assert(name == NULL || PyUnicode_Check(name));
1053
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001054 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
1055 if (self == NULL) {
1056 return NULL;
1057 }
1058 Py_INCREF(offset);
1059 self->offset = offset;
1060 Py_XINCREF(name);
1061 self->name = name;
1062 return (PyObject *)self;
1063}
1064
1065static int delta_bool(PyDateTime_Delta *self);
1066
1067static PyObject *
1068new_timezone(PyObject *offset, PyObject *name)
1069{
1070 assert(offset != NULL);
1071 assert(PyDelta_Check(offset));
1072 assert(name == NULL || PyUnicode_Check(name));
1073
1074 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
1075 Py_INCREF(PyDateTime_TimeZone_UTC);
1076 return PyDateTime_TimeZone_UTC;
1077 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001078 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1079 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1080 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1081 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04001082 " timedelta(hours=24),"
1083 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001084 return NULL;
1085 }
1086
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00001087 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00001088}
1089
Tim Petersb0c854d2003-05-17 15:57:00 +00001090/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001091 * tzinfo helpers.
1092 */
1093
Tim Peters855fe882002-12-22 03:43:39 +00001094/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
1095 * raise TypeError and return -1.
1096 */
1097static int
1098check_tzinfo_subclass(PyObject *p)
1099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 if (p == Py_None || PyTZInfo_Check(p))
1101 return 0;
1102 PyErr_Format(PyExc_TypeError,
1103 "tzinfo argument must be None or of a tzinfo subclass, "
1104 "not type '%s'",
1105 Py_TYPE(p)->tp_name);
1106 return -1;
Tim Peters855fe882002-12-22 03:43:39 +00001107}
1108
Tim Peters2a799bf2002-12-16 20:18:38 +00001109/* If self has a tzinfo member, return a BORROWED reference to it. Else
1110 * return NULL, which is NOT AN ERROR. There are no error returns here,
1111 * and the caller must not decref the result.
1112 */
1113static PyObject *
1114get_tzinfo_member(PyObject *self)
1115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 if (PyDateTime_Check(self) && HASTZINFO(self))
1119 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
1120 else if (PyTime_Check(self) && HASTZINFO(self))
1121 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001124}
1125
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001126/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
1127 * be an instance of the tzinfo class. If the method returns None, this
1128 * returns None. If the method doesn't return None or timedelta, TypeError is
1129 * raised and this returns NULL. If it returns a timedelta and the value is
1130 * out of range or isn't a whole number of minutes, ValueError is raised and
1131 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +00001132 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001133static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001134call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001135{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001136 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001139 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001141
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001142 if (tzinfo == Py_None)
1143 Py_RETURN_NONE;
1144 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
1145 if (offset == Py_None || offset == NULL)
1146 return offset;
1147 if (PyDelta_Check(offset)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001148 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
1149 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
1150 Py_DECREF(offset);
1151 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
1152 " strictly between -timedelta(hours=24) and"
1153 " timedelta(hours=24).");
1154 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 }
1156 }
1157 else {
1158 PyErr_Format(PyExc_TypeError,
1159 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001160 "timedelta, not '%.200s'",
1161 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07001162 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001163 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001165
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001166 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +00001167}
1168
1169/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
1170 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
1171 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +00001172 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001173 * If utcoffset() returns an out of range timedelta,
1174 * ValueError is raised and this returns -1. Else *none is
1175 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001176 */
Tim Peters855fe882002-12-22 03:43:39 +00001177static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001178call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
1179{
1180 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001181}
1182
Tim Peters2a799bf2002-12-16 20:18:38 +00001183/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
1184 * result. tzinfo must be an instance of the tzinfo class. If dst()
1185 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001186 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00001187 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +00001188 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001189 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +00001190 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001191static PyObject *
1192call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001193{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001194 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001195}
1196
Tim Petersbad8ff02002-12-30 20:52:32 +00001197/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +00001198 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001199 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001200 * returns NULL. If the result is a string, we ensure it is a Unicode
1201 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001202 */
1203static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001204call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001207 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 assert(tzinfo != NULL);
1210 assert(check_tzinfo_subclass(tzinfo) >= 0);
1211 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001214 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001215
Victor Stinner20401de2016-12-09 15:24:31 +01001216 result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname,
1217 tzinfoarg, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001218
1219 if (result == NULL || result == Py_None)
1220 return result;
1221
1222 if (!PyUnicode_Check(result)) {
1223 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1224 "return None or a string, not '%s'",
1225 Py_TYPE(result)->tp_name);
1226 Py_DECREF(result);
1227 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001229
1230 return result;
Tim Peters00237032002-12-27 02:21:51 +00001231}
1232
Tim Peters2a799bf2002-12-16 20:18:38 +00001233/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1234 * stuff
1235 * ", tzinfo=" + repr(tzinfo)
1236 * before the closing ")".
1237 */
1238static PyObject *
1239append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 assert(PyUnicode_Check(repr));
1244 assert(tzinfo);
1245 if (tzinfo == Py_None)
1246 return repr;
1247 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001248 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1249 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 Py_DECREF(repr);
1251 if (temp == NULL)
1252 return NULL;
1253 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1254 Py_DECREF(temp);
1255 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001256}
1257
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001258/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1259 * stuff
1260 * ", fold=" + repr(tzinfo)
1261 * before the closing ")".
1262 */
1263static PyObject *
1264append_keyword_fold(PyObject *repr, int fold)
1265{
1266 PyObject *temp;
1267
1268 assert(PyUnicode_Check(repr));
1269 if (fold == 0)
1270 return repr;
1271 /* Get rid of the trailing ')'. */
1272 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1273 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1274 Py_DECREF(repr);
1275 if (temp == NULL)
1276 return NULL;
1277 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1278 Py_DECREF(temp);
1279 return repr;
1280}
1281
Paul Ganssle09dc2f52017-12-21 00:33:49 -05001282static inline PyObject *
1283tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) {
1284 PyObject *tzinfo;
1285 if (rv == 1) {
1286 // Create a timezone from offset in seconds (0 returns UTC)
1287 if (tzoffset == 0) {
1288 Py_INCREF(PyDateTime_TimeZone_UTC);
1289 return PyDateTime_TimeZone_UTC;
1290 }
1291
1292 PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1);
1293 tzinfo = new_timezone(delta, NULL);
1294 Py_XDECREF(delta);
1295 } else {
1296 tzinfo = Py_None;
1297 Py_INCREF(Py_None);
1298 }
1299
1300 return tzinfo;
1301}
1302
Tim Peters2a799bf2002-12-16 20:18:38 +00001303/* ---------------------------------------------------------------------------
1304 * String format helpers.
1305 */
1306
1307static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001308format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001309{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001310 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1312 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001313 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1315 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1316 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1321 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1322 GET_DAY(date), hours, minutes, seconds,
1323 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001324}
1325
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001326static PyObject *delta_negative(PyDateTime_Delta *self);
1327
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001328/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001329 * buflen bytes remaining. The UTC offset is gotten by calling
1330 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1331 * *buf, and that's all. Else the returned value is checked for sanity (an
1332 * integer in range), and if that's OK it's converted to an hours & minutes
1333 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001334 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001335 * Returns 0 if everything is OK. If the return value from utcoffset() is
1336 * bogus, an appropriate exception is set and -1 is returned.
1337 */
1338static int
Tim Peters328fff72002-12-20 01:31:27 +00001339format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001341{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001342 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001343 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001347
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001348 offset = call_utcoffset(tzinfo, tzinfoarg);
1349 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001351 if (offset == Py_None) {
1352 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 *buf = '\0';
1354 return 0;
1355 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001356 /* Offset is normalized, so it is negative if days < 0 */
1357 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001359 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001360 if (offset == NULL)
1361 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001363 else {
1364 sign = '+';
1365 }
1366 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001367 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001368 seconds = GET_TD_SECONDS(offset);
1369 Py_DECREF(offset);
1370 minutes = divmod(seconds, 60, &seconds);
1371 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001372 if (microseconds) {
1373 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1374 hours, sep, minutes, sep, seconds, microseconds);
1375 return 0;
1376 }
1377 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001378 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1379 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001380 return 0;
1381 }
1382 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001384}
1385
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001386static PyObject *
1387make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 PyObject *temp;
1390 PyObject *tzinfo = get_tzinfo_member(object);
1391 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001392 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 if (Zreplacement == NULL)
1395 return NULL;
1396 if (tzinfo == Py_None || tzinfo == NULL)
1397 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 assert(tzinfoarg != NULL);
1400 temp = call_tzname(tzinfo, tzinfoarg);
1401 if (temp == NULL)
1402 goto Error;
1403 if (temp == Py_None) {
1404 Py_DECREF(temp);
1405 return Zreplacement;
1406 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 assert(PyUnicode_Check(temp));
1409 /* Since the tzname is getting stuffed into the
1410 * format, we have to double any % signs so that
1411 * strftime doesn't treat them as format codes.
1412 */
1413 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001414 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 Py_DECREF(temp);
1416 if (Zreplacement == NULL)
1417 return NULL;
1418 if (!PyUnicode_Check(Zreplacement)) {
1419 PyErr_SetString(PyExc_TypeError,
1420 "tzname.replace() did not return a string");
1421 goto Error;
1422 }
1423 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001424
1425 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 Py_DECREF(Zreplacement);
1427 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001428}
1429
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001430static PyObject *
1431make_freplacement(PyObject *object)
1432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 char freplacement[64];
1434 if (PyTime_Check(object))
1435 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1436 else if (PyDateTime_Check(object))
1437 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1438 else
1439 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001442}
1443
Tim Peters2a799bf2002-12-16 20:18:38 +00001444/* I sure don't want to reproduce the strftime code from the time module,
1445 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001446 * giving special meanings to the %z, %Z and %f format codes via a
1447 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001448 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1449 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001450 */
1451static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001452wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001454{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1458 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1459 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 const char *pin; /* pointer to next char in input format */
1462 Py_ssize_t flen; /* length of input format */
1463 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 PyObject *newfmt = NULL; /* py string, the output format */
1466 char *pnew; /* pointer to available byte in output format */
1467 size_t totalnew; /* number bytes total in output format buffer,
1468 exclusive of trailing \0 */
1469 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 const char *ptoappend; /* ptr to string to append to output buffer */
1472 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 assert(object && format && timetuple);
1475 assert(PyUnicode_Check(format));
1476 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001477 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 if (!pin)
1479 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 /* Scan the input format, looking for %z/%Z/%f escapes, building
1482 * a new format. Since computing the replacements for those codes
1483 * is expensive, don't unless they're actually used.
1484 */
1485 if (flen > INT_MAX - 1) {
1486 PyErr_NoMemory();
1487 goto Done;
1488 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 totalnew = flen + 1; /* realistic if no %z/%Z */
1491 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1492 if (newfmt == NULL) goto Done;
1493 pnew = PyBytes_AsString(newfmt);
1494 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 while ((ch = *pin++) != '\0') {
1497 if (ch != '%') {
1498 ptoappend = pin - 1;
1499 ntoappend = 1;
1500 }
1501 else if ((ch = *pin++) == '\0') {
1502 /* There's a lone trailing %; doesn't make sense. */
1503 PyErr_SetString(PyExc_ValueError, "strftime format "
1504 "ends with raw %");
1505 goto Done;
1506 }
1507 /* A % has been seen and ch is the character after it. */
1508 else if (ch == 'z') {
1509 if (zreplacement == NULL) {
1510 /* format utcoffset */
1511 char buf[100];
1512 PyObject *tzinfo = get_tzinfo_member(object);
1513 zreplacement = PyBytes_FromStringAndSize("", 0);
1514 if (zreplacement == NULL) goto Done;
1515 if (tzinfo != Py_None && tzinfo != NULL) {
1516 assert(tzinfoarg != NULL);
1517 if (format_utcoffset(buf,
1518 sizeof(buf),
1519 "",
1520 tzinfo,
1521 tzinfoarg) < 0)
1522 goto Done;
1523 Py_DECREF(zreplacement);
1524 zreplacement =
1525 PyBytes_FromStringAndSize(buf,
1526 strlen(buf));
1527 if (zreplacement == NULL)
1528 goto Done;
1529 }
1530 }
1531 assert(zreplacement != NULL);
1532 ptoappend = PyBytes_AS_STRING(zreplacement);
1533 ntoappend = PyBytes_GET_SIZE(zreplacement);
1534 }
1535 else if (ch == 'Z') {
1536 /* format tzname */
1537 if (Zreplacement == NULL) {
1538 Zreplacement = make_Zreplacement(object,
1539 tzinfoarg);
1540 if (Zreplacement == NULL)
1541 goto Done;
1542 }
1543 assert(Zreplacement != NULL);
1544 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001545 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001547 if (ptoappend == NULL)
1548 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 }
1550 else if (ch == 'f') {
1551 /* format microseconds */
1552 if (freplacement == NULL) {
1553 freplacement = make_freplacement(object);
1554 if (freplacement == NULL)
1555 goto Done;
1556 }
1557 assert(freplacement != NULL);
1558 assert(PyBytes_Check(freplacement));
1559 ptoappend = PyBytes_AS_STRING(freplacement);
1560 ntoappend = PyBytes_GET_SIZE(freplacement);
1561 }
1562 else {
1563 /* percent followed by neither z nor Z */
1564 ptoappend = pin - 2;
1565 ntoappend = 2;
1566 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 /* Append the ntoappend chars starting at ptoappend to
1569 * the new format.
1570 */
1571 if (ntoappend == 0)
1572 continue;
1573 assert(ptoappend != NULL);
1574 assert(ntoappend > 0);
1575 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001576 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 PyErr_NoMemory();
1578 goto Done;
1579 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001580 totalnew <<= 1;
1581 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 pnew = PyBytes_AsString(newfmt) + usednew;
1584 }
1585 memcpy(pnew, ptoappend, ntoappend);
1586 pnew += ntoappend;
1587 usednew += ntoappend;
1588 assert(usednew <= totalnew);
1589 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1592 goto Done;
1593 {
1594 PyObject *format;
1595 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 if (time == NULL)
1598 goto Done;
1599 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1600 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001601 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1602 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 Py_DECREF(format);
1604 }
1605 Py_DECREF(time);
1606 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001607 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 Py_XDECREF(freplacement);
1609 Py_XDECREF(zreplacement);
1610 Py_XDECREF(Zreplacement);
1611 Py_XDECREF(newfmt);
1612 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001613}
1614
Tim Peters2a799bf2002-12-16 20:18:38 +00001615/* ---------------------------------------------------------------------------
1616 * Wrap functions from the time module. These aren't directly available
1617 * from C. Perhaps they should be.
1618 */
1619
1620/* Call time.time() and return its result (a Python float). */
1621static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001622time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 PyObject *result = NULL;
1625 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001628 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001629
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001630 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 Py_DECREF(time);
1632 }
1633 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001634}
1635
1636/* Build a time.struct_time. The weekday and day number are automatically
1637 * computed from the y,m,d args.
1638 */
1639static PyObject *
1640build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001643 PyObject *result;
1644 _Py_IDENTIFIER(struct_time);
1645 PyObject *args;
1646
Tim Peters2a799bf2002-12-16 20:18:38 +00001647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001649 if (time == NULL) {
1650 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 }
Victor Stinner2b635972016-12-09 00:38:16 +01001652
1653 args = Py_BuildValue("iiiiiiiii",
1654 y, m, d,
1655 hh, mm, ss,
1656 weekday(y, m, d),
1657 days_before_month(y, m) + d,
1658 dstflag);
1659 if (args == NULL) {
1660 Py_DECREF(time);
1661 return NULL;
1662 }
1663
1664 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1665 args, NULL);
1666 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001667 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001669}
1670
1671/* ---------------------------------------------------------------------------
1672 * Miscellaneous helpers.
1673 */
1674
Mark Dickinsone94c6792009-02-02 20:36:42 +00001675/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001676 * The comparisons here all most naturally compute a cmp()-like result.
1677 * This little helper turns that into a bool result for rich comparisons.
1678 */
1679static PyObject *
1680diff_to_bool(int diff, int op)
1681{
stratakise8b19652017-11-02 11:32:54 +01001682 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001683}
1684
Tim Peters07534a62003-02-07 22:50:28 +00001685/* Raises a "can't compare" TypeError and returns NULL. */
1686static PyObject *
1687cmperror(PyObject *a, PyObject *b)
1688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 PyErr_Format(PyExc_TypeError,
1690 "can't compare %s to %s",
1691 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1692 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001693}
1694
Tim Peters2a799bf2002-12-16 20:18:38 +00001695/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001696 * Cached Python objects; these are set by the module init function.
1697 */
1698
1699/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700static PyObject *us_per_ms = NULL; /* 1000 */
1701static PyObject *us_per_second = NULL; /* 1000000 */
1702static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001703static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1704static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1705static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001706static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1707
Tim Peters2a799bf2002-12-16 20:18:38 +00001708/* ---------------------------------------------------------------------------
1709 * Class implementations.
1710 */
1711
1712/*
1713 * PyDateTime_Delta implementation.
1714 */
1715
1716/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001718 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001719 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1720 * due to ubiquitous overflow possibilities.
1721 */
1722static PyObject *
1723delta_to_microseconds(PyDateTime_Delta *self)
1724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 PyObject *x1 = NULL;
1726 PyObject *x2 = NULL;
1727 PyObject *x3 = NULL;
1728 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1731 if (x1 == NULL)
1732 goto Done;
1733 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1734 if (x2 == NULL)
1735 goto Done;
1736 Py_DECREF(x1);
1737 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 /* x2 has days in seconds */
1740 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1741 if (x1 == NULL)
1742 goto Done;
1743 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1744 if (x3 == NULL)
1745 goto Done;
1746 Py_DECREF(x1);
1747 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001748 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 /* x3 has days+seconds in seconds */
1751 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1752 if (x1 == NULL)
1753 goto Done;
1754 Py_DECREF(x3);
1755 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 /* x1 has days+seconds in us */
1758 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1759 if (x2 == NULL)
1760 goto Done;
1761 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001762 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001763
1764Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 Py_XDECREF(x1);
1766 Py_XDECREF(x2);
1767 Py_XDECREF(x3);
1768 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001769}
1770
Serhiy Storchaka95949422013-08-27 19:40:23 +03001771/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001772 */
1773static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001774microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 int us;
1777 int s;
1778 int d;
1779 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 PyObject *tuple = NULL;
1782 PyObject *num = NULL;
1783 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001784
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001785 assert(PyLong_CheckExact(pyus));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 tuple = PyNumber_Divmod(pyus, us_per_second);
1787 if (tuple == NULL)
1788 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 num = PyTuple_GetItem(tuple, 1); /* us */
1791 if (num == NULL)
1792 goto Done;
1793 temp = PyLong_AsLong(num);
1794 num = NULL;
1795 if (temp == -1 && PyErr_Occurred())
1796 goto Done;
1797 assert(0 <= temp && temp < 1000000);
1798 us = (int)temp;
1799 if (us < 0) {
1800 /* The divisor was positive, so this must be an error. */
1801 assert(PyErr_Occurred());
1802 goto Done;
1803 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1806 if (num == NULL)
1807 goto Done;
1808 Py_INCREF(num);
1809 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001810
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 tuple = PyNumber_Divmod(num, seconds_per_day);
1812 if (tuple == NULL)
1813 goto Done;
1814 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 num = PyTuple_GetItem(tuple, 1); /* seconds */
1817 if (num == NULL)
1818 goto Done;
1819 temp = PyLong_AsLong(num);
1820 num = NULL;
1821 if (temp == -1 && PyErr_Occurred())
1822 goto Done;
1823 assert(0 <= temp && temp < 24*3600);
1824 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 if (s < 0) {
1827 /* The divisor was positive, so this must be an error. */
1828 assert(PyErr_Occurred());
1829 goto Done;
1830 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1833 if (num == NULL)
1834 goto Done;
1835 Py_INCREF(num);
1836 temp = PyLong_AsLong(num);
1837 if (temp == -1 && PyErr_Occurred())
1838 goto Done;
1839 d = (int)temp;
1840 if ((long)d != temp) {
1841 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1842 "large to fit in a C int");
1843 goto Done;
1844 }
1845 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001846
1847Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 Py_XDECREF(tuple);
1849 Py_XDECREF(num);
1850 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001851}
1852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853#define microseconds_to_delta(pymicros) \
1854 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001855
Tim Peters2a799bf2002-12-16 20:18:38 +00001856static PyObject *
1857multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1858{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 PyObject *pyus_in;
1860 PyObject *pyus_out;
1861 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 pyus_in = delta_to_microseconds(delta);
1864 if (pyus_in == NULL)
1865 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1868 Py_DECREF(pyus_in);
1869 if (pyus_out == NULL)
1870 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 result = microseconds_to_delta(pyus_out);
1873 Py_DECREF(pyus_out);
1874 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001875}
1876
1877static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001878get_float_as_integer_ratio(PyObject *floatobj)
1879{
1880 PyObject *ratio;
1881
1882 assert(floatobj && PyFloat_Check(floatobj));
1883 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1884 if (ratio == NULL) {
1885 return NULL;
1886 }
1887 if (!PyTuple_Check(ratio)) {
1888 PyErr_Format(PyExc_TypeError,
1889 "unexpected return type from as_integer_ratio(): "
1890 "expected tuple, got '%.200s'",
1891 Py_TYPE(ratio)->tp_name);
1892 Py_DECREF(ratio);
1893 return NULL;
1894 }
1895 if (PyTuple_Size(ratio) != 2) {
1896 PyErr_SetString(PyExc_ValueError,
1897 "as_integer_ratio() must return a 2-tuple");
1898 Py_DECREF(ratio);
1899 return NULL;
1900 }
1901 return ratio;
1902}
1903
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001904/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001905static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001906multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001907{
1908 PyObject *result = NULL;
1909 PyObject *pyus_in = NULL, *temp, *pyus_out;
1910 PyObject *ratio = NULL;
1911
1912 pyus_in = delta_to_microseconds(delta);
1913 if (pyus_in == NULL)
1914 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001915 ratio = get_float_as_integer_ratio(floatobj);
1916 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001917 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001918 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001919 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001920 Py_DECREF(pyus_in);
1921 pyus_in = NULL;
1922 if (temp == NULL)
1923 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001924 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001925 Py_DECREF(temp);
1926 if (pyus_out == NULL)
1927 goto error;
1928 result = microseconds_to_delta(pyus_out);
1929 Py_DECREF(pyus_out);
1930 error:
1931 Py_XDECREF(pyus_in);
1932 Py_XDECREF(ratio);
1933
1934 return result;
1935}
1936
1937static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001938divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 PyObject *pyus_in;
1941 PyObject *pyus_out;
1942 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 pyus_in = delta_to_microseconds(delta);
1945 if (pyus_in == NULL)
1946 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1949 Py_DECREF(pyus_in);
1950 if (pyus_out == NULL)
1951 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 result = microseconds_to_delta(pyus_out);
1954 Py_DECREF(pyus_out);
1955 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001956}
1957
1958static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001959divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 PyObject *pyus_left;
1962 PyObject *pyus_right;
1963 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 pyus_left = delta_to_microseconds(left);
1966 if (pyus_left == NULL)
1967 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 pyus_right = delta_to_microseconds(right);
1970 if (pyus_right == NULL) {
1971 Py_DECREF(pyus_left);
1972 return NULL;
1973 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1976 Py_DECREF(pyus_left);
1977 Py_DECREF(pyus_right);
1978 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001979}
1980
1981static PyObject *
1982truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001984 PyObject *pyus_left;
1985 PyObject *pyus_right;
1986 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 pyus_left = delta_to_microseconds(left);
1989 if (pyus_left == NULL)
1990 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 pyus_right = delta_to_microseconds(right);
1993 if (pyus_right == NULL) {
1994 Py_DECREF(pyus_left);
1995 return NULL;
1996 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1999 Py_DECREF(pyus_left);
2000 Py_DECREF(pyus_right);
2001 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002}
2003
2004static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002005truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
2006{
2007 PyObject *result;
2008 PyObject *pyus_in, *pyus_out;
2009 pyus_in = delta_to_microseconds(delta);
2010 if (pyus_in == NULL)
2011 return NULL;
2012 pyus_out = divide_nearest(pyus_in, i);
2013 Py_DECREF(pyus_in);
2014 if (pyus_out == NULL)
2015 return NULL;
2016 result = microseconds_to_delta(pyus_out);
2017 Py_DECREF(pyus_out);
2018
2019 return result;
2020}
2021
2022static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002023delta_add(PyObject *left, PyObject *right)
2024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2028 /* delta + delta */
2029 /* The C-level additions can't overflow because of the
2030 * invariant bounds.
2031 */
2032 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
2033 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
2034 int microseconds = GET_TD_MICROSECONDS(left) +
2035 GET_TD_MICROSECONDS(right);
2036 result = new_delta(days, seconds, microseconds, 1);
2037 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 if (result == Py_NotImplemented)
2040 Py_INCREF(result);
2041 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002042}
2043
2044static PyObject *
2045delta_negative(PyDateTime_Delta *self)
2046{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 return new_delta(-GET_TD_DAYS(self),
2048 -GET_TD_SECONDS(self),
2049 -GET_TD_MICROSECONDS(self),
2050 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002051}
2052
2053static PyObject *
2054delta_positive(PyDateTime_Delta *self)
2055{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 /* Could optimize this (by returning self) if this isn't a
2057 * subclass -- but who uses unary + ? Approximately nobody.
2058 */
2059 return new_delta(GET_TD_DAYS(self),
2060 GET_TD_SECONDS(self),
2061 GET_TD_MICROSECONDS(self),
2062 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002063}
2064
2065static PyObject *
2066delta_abs(PyDateTime_Delta *self)
2067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 assert(GET_TD_MICROSECONDS(self) >= 0);
2071 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 if (GET_TD_DAYS(self) < 0)
2074 result = delta_negative(self);
2075 else
2076 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002079}
2080
2081static PyObject *
2082delta_subtract(PyObject *left, PyObject *right)
2083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 if (PyDelta_Check(left) && PyDelta_Check(right)) {
2087 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04002088 /* The C-level additions can't overflow because of the
2089 * invariant bounds.
2090 */
2091 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
2092 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
2093 int microseconds = GET_TD_MICROSECONDS(left) -
2094 GET_TD_MICROSECONDS(right);
2095 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 if (result == Py_NotImplemented)
2099 Py_INCREF(result);
2100 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002101}
2102
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002103static int
2104delta_cmp(PyObject *self, PyObject *other)
2105{
2106 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
2107 if (diff == 0) {
2108 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
2109 if (diff == 0)
2110 diff = GET_TD_MICROSECONDS(self) -
2111 GET_TD_MICROSECONDS(other);
2112 }
2113 return diff;
2114}
2115
Tim Peters2a799bf2002-12-16 20:18:38 +00002116static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002117delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002118{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002120 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 return diff_to_bool(diff, op);
2122 }
2123 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05002124 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002125 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002126}
2127
2128static PyObject *delta_getstate(PyDateTime_Delta *self);
2129
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002130static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002131delta_hash(PyDateTime_Delta *self)
2132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 if (self->hashcode == -1) {
2134 PyObject *temp = delta_getstate(self);
2135 if (temp != NULL) {
2136 self->hashcode = PyObject_Hash(temp);
2137 Py_DECREF(temp);
2138 }
2139 }
2140 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002141}
2142
2143static PyObject *
2144delta_multiply(PyObject *left, PyObject *right)
2145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 if (PyDelta_Check(left)) {
2149 /* delta * ??? */
2150 if (PyLong_Check(right))
2151 result = multiply_int_timedelta(right,
2152 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002153 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002154 result = multiply_truedivide_timedelta_float(
2155 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 }
2157 else if (PyLong_Check(left))
2158 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002159 (PyDateTime_Delta *) right);
2160 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002161 result = multiply_truedivide_timedelta_float(
2162 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 if (result == Py_NotImplemented)
2165 Py_INCREF(result);
2166 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002167}
2168
2169static PyObject *
2170delta_divide(PyObject *left, PyObject *right)
2171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 if (PyDelta_Check(left)) {
2175 /* delta * ??? */
2176 if (PyLong_Check(right))
2177 result = divide_timedelta_int(
2178 (PyDateTime_Delta *)left,
2179 right);
2180 else if (PyDelta_Check(right))
2181 result = divide_timedelta_timedelta(
2182 (PyDateTime_Delta *)left,
2183 (PyDateTime_Delta *)right);
2184 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 if (result == Py_NotImplemented)
2187 Py_INCREF(result);
2188 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002189}
2190
Mark Dickinson7c186e22010-04-20 22:32:49 +00002191static PyObject *
2192delta_truedivide(PyObject *left, PyObject *right)
2193{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 if (PyDelta_Check(left)) {
2197 if (PyDelta_Check(right))
2198 result = truedivide_timedelta_timedelta(
2199 (PyDateTime_Delta *)left,
2200 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002201 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03002202 result = multiply_truedivide_timedelta_float(
2203 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002204 else if (PyLong_Check(right))
2205 result = truedivide_timedelta_int(
2206 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002207 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 if (result == Py_NotImplemented)
2210 Py_INCREF(result);
2211 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002212}
2213
2214static PyObject *
2215delta_remainder(PyObject *left, PyObject *right)
2216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 PyObject *pyus_left;
2218 PyObject *pyus_right;
2219 PyObject *pyus_remainder;
2220 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002221
Brian Curtindfc80e32011-08-10 20:28:54 -05002222 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2223 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2226 if (pyus_left == NULL)
2227 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2230 if (pyus_right == NULL) {
2231 Py_DECREF(pyus_left);
2232 return NULL;
2233 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2236 Py_DECREF(pyus_left);
2237 Py_DECREF(pyus_right);
2238 if (pyus_remainder == NULL)
2239 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 remainder = microseconds_to_delta(pyus_remainder);
2242 Py_DECREF(pyus_remainder);
2243 if (remainder == NULL)
2244 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002247}
2248
2249static PyObject *
2250delta_divmod(PyObject *left, PyObject *right)
2251{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002252 PyObject *pyus_left;
2253 PyObject *pyus_right;
2254 PyObject *divmod;
2255 PyObject *delta;
2256 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002257
Brian Curtindfc80e32011-08-10 20:28:54 -05002258 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2259 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2262 if (pyus_left == NULL)
2263 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2266 if (pyus_right == NULL) {
2267 Py_DECREF(pyus_left);
2268 return NULL;
2269 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2272 Py_DECREF(pyus_left);
2273 Py_DECREF(pyus_right);
2274 if (divmod == NULL)
2275 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 assert(PyTuple_Size(divmod) == 2);
2278 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2279 if (delta == NULL) {
2280 Py_DECREF(divmod);
2281 return NULL;
2282 }
2283 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2284 Py_DECREF(delta);
2285 Py_DECREF(divmod);
2286 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002287}
2288
Tim Peters2a799bf2002-12-16 20:18:38 +00002289/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2290 * timedelta constructor. sofar is the # of microseconds accounted for
2291 * so far, and there are factor microseconds per current unit, the number
2292 * of which is given by num. num * factor is added to sofar in a
2293 * numerically careful way, and that's the result. Any fractional
2294 * microseconds left over (this can happen if num is a float type) are
2295 * added into *leftover.
2296 * Note that there are many ways this can give an error (NULL) return.
2297 */
2298static PyObject *
2299accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2300 double *leftover)
2301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 PyObject *prod;
2303 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 if (PyLong_Check(num)) {
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002308 prod = PyNumber_Multiply(factor, num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002309 if (prod == NULL)
2310 return NULL;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002311 assert(PyLong_CheckExact(prod));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 sum = PyNumber_Add(sofar, prod);
2313 Py_DECREF(prod);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002314 assert(sum == NULL || PyLong_CheckExact(sum));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 return sum;
2316 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 if (PyFloat_Check(num)) {
2319 double dnum;
2320 double fracpart;
2321 double intpart;
2322 PyObject *x;
2323 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 /* The Plan: decompose num into an integer part and a
2326 * fractional part, num = intpart + fracpart.
2327 * Then num * factor ==
2328 * intpart * factor + fracpart * factor
2329 * and the LHS can be computed exactly in long arithmetic.
2330 * The RHS is again broken into an int part and frac part.
2331 * and the frac part is added into *leftover.
2332 */
2333 dnum = PyFloat_AsDouble(num);
2334 if (dnum == -1.0 && PyErr_Occurred())
2335 return NULL;
2336 fracpart = modf(dnum, &intpart);
2337 x = PyLong_FromDouble(intpart);
2338 if (x == NULL)
2339 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 prod = PyNumber_Multiply(x, factor);
2342 Py_DECREF(x);
2343 if (prod == NULL)
2344 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346 sum = PyNumber_Add(sofar, prod);
2347 Py_DECREF(prod);
2348 if (sum == NULL)
2349 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 if (fracpart == 0.0)
2352 return sum;
2353 /* So far we've lost no information. Dealing with the
2354 * fractional part requires float arithmetic, and may
2355 * lose a little info.
2356 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002357 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002358 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 dnum *= fracpart;
2361 fracpart = modf(dnum, &intpart);
2362 x = PyLong_FromDouble(intpart);
2363 if (x == NULL) {
2364 Py_DECREF(sum);
2365 return NULL;
2366 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 y = PyNumber_Add(sum, x);
2369 Py_DECREF(sum);
2370 Py_DECREF(x);
2371 *leftover += fracpart;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002372 assert(y == NULL || PyLong_CheckExact(y));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 return y;
2374 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 PyErr_Format(PyExc_TypeError,
2377 "unsupported type for timedelta %s component: %s",
2378 tag, Py_TYPE(num)->tp_name);
2379 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002380}
2381
2382static PyObject *
2383delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 /* Argument objects. */
2388 PyObject *day = NULL;
2389 PyObject *second = NULL;
2390 PyObject *us = NULL;
2391 PyObject *ms = NULL;
2392 PyObject *minute = NULL;
2393 PyObject *hour = NULL;
2394 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 PyObject *x = NULL; /* running sum of microseconds */
2397 PyObject *y = NULL; /* temp sum of microseconds */
2398 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 static char *keywords[] = {
2401 "days", "seconds", "microseconds", "milliseconds",
2402 "minutes", "hours", "weeks", NULL
2403 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2406 keywords,
2407 &day, &second, &us,
2408 &ms, &minute, &hour, &week) == 0)
2409 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 x = PyLong_FromLong(0);
2412 if (x == NULL)
2413 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415#define CLEANUP \
2416 Py_DECREF(x); \
2417 x = y; \
2418 if (x == NULL) \
2419 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002422 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 CLEANUP;
2424 }
2425 if (ms) {
2426 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2427 CLEANUP;
2428 }
2429 if (second) {
2430 y = accum("seconds", x, second, us_per_second, &leftover_us);
2431 CLEANUP;
2432 }
2433 if (minute) {
2434 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2435 CLEANUP;
2436 }
2437 if (hour) {
2438 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2439 CLEANUP;
2440 }
2441 if (day) {
2442 y = accum("days", x, day, us_per_day, &leftover_us);
2443 CLEANUP;
2444 }
2445 if (week) {
2446 y = accum("weeks", x, week, us_per_week, &leftover_us);
2447 CLEANUP;
2448 }
2449 if (leftover_us) {
2450 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002451 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002452 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002453 PyObject *temp;
2454
Victor Stinner69cc4872015-09-08 23:58:54 +02002455 whole_us = round(leftover_us);
2456 if (fabs(whole_us - leftover_us) == 0.5) {
2457 /* We're exactly halfway between two integers. In order
2458 * to do round-half-to-even, we must determine whether x
2459 * is odd. Note that x is odd when it's last bit is 1. The
2460 * code below uses bitwise and operation to check the last
2461 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002462 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002463 if (temp == NULL) {
2464 Py_DECREF(x);
2465 goto Done;
2466 }
2467 x_is_odd = PyObject_IsTrue(temp);
2468 Py_DECREF(temp);
2469 if (x_is_odd == -1) {
2470 Py_DECREF(x);
2471 goto Done;
2472 }
2473 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2474 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002475
Victor Stinner36a5a062013-08-28 01:53:39 +02002476 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 if (temp == NULL) {
2479 Py_DECREF(x);
2480 goto Done;
2481 }
2482 y = PyNumber_Add(x, temp);
2483 Py_DECREF(temp);
2484 CLEANUP;
2485 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 self = microseconds_to_delta_ex(x, type);
2488 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002489Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002491
2492#undef CLEANUP
2493}
2494
2495static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002496delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 return (GET_TD_DAYS(self) != 0
2499 || GET_TD_SECONDS(self) != 0
2500 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002501}
2502
2503static PyObject *
2504delta_repr(PyDateTime_Delta *self)
2505{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002506 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002507
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002508 if (args == NULL) {
2509 return NULL;
2510 }
2511
2512 const char *sep = "";
2513
2514 if (GET_TD_DAYS(self) != 0) {
2515 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2516 if (args == NULL) {
2517 return NULL;
2518 }
2519 sep = ", ";
2520 }
2521
2522 if (GET_TD_SECONDS(self) != 0) {
2523 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2524 GET_TD_SECONDS(self)));
2525 if (args == NULL) {
2526 return NULL;
2527 }
2528 sep = ", ";
2529 }
2530
2531 if (GET_TD_MICROSECONDS(self) != 0) {
2532 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2533 GET_TD_MICROSECONDS(self)));
2534 if (args == NULL) {
2535 return NULL;
2536 }
2537 }
2538
2539 if (PyUnicode_GET_LENGTH(args) == 0) {
2540 Py_SETREF(args, PyUnicode_FromString("0"));
2541 if (args == NULL) {
2542 return NULL;
2543 }
2544 }
2545
2546 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2547 args);
2548 Py_DECREF(args);
2549 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002550}
2551
2552static PyObject *
2553delta_str(PyDateTime_Delta *self)
2554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002555 int us = GET_TD_MICROSECONDS(self);
2556 int seconds = GET_TD_SECONDS(self);
2557 int minutes = divmod(seconds, 60, &seconds);
2558 int hours = divmod(minutes, 60, &minutes);
2559 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 if (days) {
2562 if (us)
2563 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2564 days, (days == 1 || days == -1) ? "" : "s",
2565 hours, minutes, seconds, us);
2566 else
2567 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2568 days, (days == 1 || days == -1) ? "" : "s",
2569 hours, minutes, seconds);
2570 } else {
2571 if (us)
2572 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2573 hours, minutes, seconds, us);
2574 else
2575 return PyUnicode_FromFormat("%d:%02d:%02d",
2576 hours, minutes, seconds);
2577 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002578
Tim Peters2a799bf2002-12-16 20:18:38 +00002579}
2580
Tim Peters371935f2003-02-01 01:52:50 +00002581/* Pickle support, a simple use of __reduce__. */
2582
Tim Petersb57f8f02003-02-01 02:54:15 +00002583/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002584static PyObject *
2585delta_getstate(PyDateTime_Delta *self)
2586{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 return Py_BuildValue("iii", GET_TD_DAYS(self),
2588 GET_TD_SECONDS(self),
2589 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002590}
2591
Tim Peters2a799bf2002-12-16 20:18:38 +00002592static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002593delta_total_seconds(PyObject *self)
2594{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002595 PyObject *total_seconds;
2596 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2599 if (total_microseconds == NULL)
2600 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002601
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002602 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002604 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002605 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002606}
2607
2608static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002609delta_reduce(PyDateTime_Delta* self)
2610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002612}
2613
2614#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2615
2616static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002618 {"days", T_INT, OFFSET(days), READONLY,
2619 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 {"seconds", T_INT, OFFSET(seconds), READONLY,
2622 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2625 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2626 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002627};
2628
2629static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2631 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2634 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002637};
2638
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002639static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002640PyDoc_STR("Difference between two datetime values.");
2641
2642static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643 delta_add, /* nb_add */
2644 delta_subtract, /* nb_subtract */
2645 delta_multiply, /* nb_multiply */
2646 delta_remainder, /* nb_remainder */
2647 delta_divmod, /* nb_divmod */
2648 0, /* nb_power */
2649 (unaryfunc)delta_negative, /* nb_negative */
2650 (unaryfunc)delta_positive, /* nb_positive */
2651 (unaryfunc)delta_abs, /* nb_absolute */
2652 (inquiry)delta_bool, /* nb_bool */
2653 0, /*nb_invert*/
2654 0, /*nb_lshift*/
2655 0, /*nb_rshift*/
2656 0, /*nb_and*/
2657 0, /*nb_xor*/
2658 0, /*nb_or*/
2659 0, /*nb_int*/
2660 0, /*nb_reserved*/
2661 0, /*nb_float*/
2662 0, /*nb_inplace_add*/
2663 0, /*nb_inplace_subtract*/
2664 0, /*nb_inplace_multiply*/
2665 0, /*nb_inplace_remainder*/
2666 0, /*nb_inplace_power*/
2667 0, /*nb_inplace_lshift*/
2668 0, /*nb_inplace_rshift*/
2669 0, /*nb_inplace_and*/
2670 0, /*nb_inplace_xor*/
2671 0, /*nb_inplace_or*/
2672 delta_divide, /* nb_floor_divide */
2673 delta_truedivide, /* nb_true_divide */
2674 0, /* nb_inplace_floor_divide */
2675 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002676};
2677
2678static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002679 PyVarObject_HEAD_INIT(NULL, 0)
2680 "datetime.timedelta", /* tp_name */
2681 sizeof(PyDateTime_Delta), /* tp_basicsize */
2682 0, /* tp_itemsize */
2683 0, /* tp_dealloc */
2684 0, /* tp_print */
2685 0, /* tp_getattr */
2686 0, /* tp_setattr */
2687 0, /* tp_reserved */
2688 (reprfunc)delta_repr, /* tp_repr */
2689 &delta_as_number, /* tp_as_number */
2690 0, /* tp_as_sequence */
2691 0, /* tp_as_mapping */
2692 (hashfunc)delta_hash, /* tp_hash */
2693 0, /* tp_call */
2694 (reprfunc)delta_str, /* tp_str */
2695 PyObject_GenericGetAttr, /* tp_getattro */
2696 0, /* tp_setattro */
2697 0, /* tp_as_buffer */
2698 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2699 delta_doc, /* tp_doc */
2700 0, /* tp_traverse */
2701 0, /* tp_clear */
2702 delta_richcompare, /* tp_richcompare */
2703 0, /* tp_weaklistoffset */
2704 0, /* tp_iter */
2705 0, /* tp_iternext */
2706 delta_methods, /* tp_methods */
2707 delta_members, /* tp_members */
2708 0, /* tp_getset */
2709 0, /* tp_base */
2710 0, /* tp_dict */
2711 0, /* tp_descr_get */
2712 0, /* tp_descr_set */
2713 0, /* tp_dictoffset */
2714 0, /* tp_init */
2715 0, /* tp_alloc */
2716 delta_new, /* tp_new */
2717 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002718};
2719
2720/*
2721 * PyDateTime_Date implementation.
2722 */
2723
2724/* Accessor properties. */
2725
2726static PyObject *
2727date_year(PyDateTime_Date *self, void *unused)
2728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002729 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002730}
2731
2732static PyObject *
2733date_month(PyDateTime_Date *self, void *unused)
2734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002735 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002736}
2737
2738static PyObject *
2739date_day(PyDateTime_Date *self, void *unused)
2740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002741 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002742}
2743
2744static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002745 {"year", (getter)date_year},
2746 {"month", (getter)date_month},
2747 {"day", (getter)date_day},
2748 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002749};
2750
2751/* Constructors. */
2752
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002753static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002754
Tim Peters2a799bf2002-12-16 20:18:38 +00002755static PyObject *
2756date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002758 PyObject *self = NULL;
2759 PyObject *state;
2760 int year;
2761 int month;
2762 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002764 /* Check for invocation from pickle with __getstate__ state */
2765 if (PyTuple_GET_SIZE(args) == 1 &&
2766 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2767 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2768 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2769 {
2770 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2773 if (me != NULL) {
2774 char *pdata = PyBytes_AS_STRING(state);
2775 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2776 me->hashcode = -1;
2777 }
2778 return (PyObject *)me;
2779 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002781 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2782 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002783 self = new_date_ex(year, month, day, type);
2784 }
2785 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002786}
2787
2788/* Return new date from localtime(t). */
2789static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002790date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002791{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002792 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002793 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002794
Victor Stinnere4a994d2015-03-30 01:10:14 +02002795 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002797
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002798 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002799 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002800
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002801 return new_date_subclass_ex(tm.tm_year + 1900,
2802 tm.tm_mon + 1,
2803 tm.tm_mday,
2804 cls);
Tim Peters2a799bf2002-12-16 20:18:38 +00002805}
2806
2807/* Return new date from current time.
2808 * We say this is equivalent to fromtimestamp(time.time()), and the
2809 * only way to be sure of that is to *call* time.time(). That's not
2810 * generally the same as calling C's time.
2811 */
2812static PyObject *
2813date_today(PyObject *cls, PyObject *dummy)
2814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 PyObject *time;
2816 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002817 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002819 time = time_time();
2820 if (time == NULL)
2821 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002822
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002823 /* Note well: today() is a class method, so this may not call
2824 * date.fromtimestamp. For example, it may call
2825 * datetime.fromtimestamp. That's why we need all the accuracy
2826 * time.time() delivers; if someone were gonzo about optimization,
2827 * date.today() could get away with plain C time().
2828 */
Victor Stinner20401de2016-12-09 15:24:31 +01002829 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2830 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 Py_DECREF(time);
2832 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002833}
2834
2835/* Return new date from given timestamp (Python timestamp -- a double). */
2836static PyObject *
2837date_fromtimestamp(PyObject *cls, PyObject *args)
2838{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002839 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002840 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002841
Victor Stinner5d272cc2012-03-13 13:35:55 +01002842 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2843 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002845}
2846
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002847
Tim Peters2a799bf2002-12-16 20:18:38 +00002848/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2849 * the ordinal is out of range.
2850 */
2851static PyObject *
2852date_fromordinal(PyObject *cls, PyObject *args)
2853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 PyObject *result = NULL;
2855 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002857 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2858 int year;
2859 int month;
2860 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 if (ordinal < 1)
2863 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2864 ">= 1");
2865 else {
2866 ord_to_ymd(ordinal, &year, &month, &day);
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002867 result = new_date_subclass_ex(year, month, day, cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 }
2869 }
2870 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002871}
2872
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002873/* Return the new date from a string as generated by date.isoformat() */
2874static PyObject *
2875date_fromisoformat(PyObject *cls, PyObject *dtstr) {
2876 assert(dtstr != NULL);
2877
2878 if (!PyUnicode_Check(dtstr)) {
2879 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
2880 return NULL;
2881 }
2882
2883 Py_ssize_t len;
2884
2885 const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002886 if (dt_ptr == NULL) {
2887 goto invalid_string_error;
2888 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002889
2890 int year = 0, month = 0, day = 0;
2891
2892 int rv;
2893 if (len == 10) {
2894 rv = parse_isoformat_date(dt_ptr, &year, &month, &day);
2895 } else {
2896 rv = -1;
2897 }
2898
2899 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002900 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002901 }
2902
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05002903 return new_date_subclass_ex(year, month, day, cls);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04002904
2905invalid_string_error:
2906 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R",
2907 dtstr);
2908 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05002909}
2910
2911
Tim Peters2a799bf2002-12-16 20:18:38 +00002912/*
2913 * Date arithmetic.
2914 */
2915
2916/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2917 * instead.
2918 */
2919static PyObject *
2920add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002922 PyObject *result = NULL;
2923 int year = GET_YEAR(date);
2924 int month = GET_MONTH(date);
2925 int deltadays = GET_TD_DAYS(delta);
2926 /* C-level overflow is impossible because |deltadays| < 1e9. */
2927 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002929 if (normalize_date(&year, &month, &day) >= 0)
2930 result = new_date(year, month, day);
2931 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002932}
2933
2934static PyObject *
2935date_add(PyObject *left, PyObject *right)
2936{
Brian Curtindfc80e32011-08-10 20:28:54 -05002937 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2938 Py_RETURN_NOTIMPLEMENTED;
2939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002940 if (PyDate_Check(left)) {
2941 /* date + ??? */
2942 if (PyDelta_Check(right))
2943 /* date + delta */
2944 return add_date_timedelta((PyDateTime_Date *) left,
2945 (PyDateTime_Delta *) right,
2946 0);
2947 }
2948 else {
2949 /* ??? + date
2950 * 'right' must be one of us, or we wouldn't have been called
2951 */
2952 if (PyDelta_Check(left))
2953 /* delta + date */
2954 return add_date_timedelta((PyDateTime_Date *) right,
2955 (PyDateTime_Delta *) left,
2956 0);
2957 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002958 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002959}
2960
2961static PyObject *
2962date_subtract(PyObject *left, PyObject *right)
2963{
Brian Curtindfc80e32011-08-10 20:28:54 -05002964 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2965 Py_RETURN_NOTIMPLEMENTED;
2966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002967 if (PyDate_Check(left)) {
2968 if (PyDate_Check(right)) {
2969 /* date - date */
2970 int left_ord = ymd_to_ord(GET_YEAR(left),
2971 GET_MONTH(left),
2972 GET_DAY(left));
2973 int right_ord = ymd_to_ord(GET_YEAR(right),
2974 GET_MONTH(right),
2975 GET_DAY(right));
2976 return new_delta(left_ord - right_ord, 0, 0, 0);
2977 }
2978 if (PyDelta_Check(right)) {
2979 /* date - delta */
2980 return add_date_timedelta((PyDateTime_Date *) left,
2981 (PyDateTime_Delta *) right,
2982 1);
2983 }
2984 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002985 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002986}
2987
2988
2989/* Various ways to turn a date into a string. */
2990
2991static PyObject *
2992date_repr(PyDateTime_Date *self)
2993{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002994 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2995 Py_TYPE(self)->tp_name,
2996 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002997}
2998
2999static PyObject *
3000date_isoformat(PyDateTime_Date *self)
3001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003002 return PyUnicode_FromFormat("%04d-%02d-%02d",
3003 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003004}
3005
Tim Peterse2df5ff2003-05-02 18:39:55 +00003006/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003007static PyObject *
3008date_str(PyDateTime_Date *self)
3009{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003010 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00003011}
3012
3013
3014static PyObject *
3015date_ctime(PyDateTime_Date *self)
3016{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003017 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00003018}
3019
3020static PyObject *
3021date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003023 /* This method can be inherited, and needs to call the
3024 * timetuple() method appropriate to self's class.
3025 */
3026 PyObject *result;
3027 PyObject *tuple;
3028 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003029 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003030 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003032 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3033 &format))
3034 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003035
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003036 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003037 if (tuple == NULL)
3038 return NULL;
3039 result = wrap_strftime((PyObject *)self, format, tuple,
3040 (PyObject *)self);
3041 Py_DECREF(tuple);
3042 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003043}
3044
Eric Smith1ba31142007-09-11 18:06:02 +00003045static PyObject *
3046date_format(PyDateTime_Date *self, PyObject *args)
3047{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003048 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00003049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003050 if (!PyArg_ParseTuple(args, "U:__format__", &format))
3051 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00003052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003053 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01003054 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003055 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00003056
Victor Stinner20401de2016-12-09 15:24:31 +01003057 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
3058 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00003059}
3060
Tim Peters2a799bf2002-12-16 20:18:38 +00003061/* ISO methods. */
3062
3063static PyObject *
3064date_isoweekday(PyDateTime_Date *self)
3065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003066 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003068 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003069}
3070
3071static PyObject *
3072date_isocalendar(PyDateTime_Date *self)
3073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003074 int year = GET_YEAR(self);
3075 int week1_monday = iso_week1_monday(year);
3076 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
3077 int week;
3078 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00003079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003080 week = divmod(today - week1_monday, 7, &day);
3081 if (week < 0) {
3082 --year;
3083 week1_monday = iso_week1_monday(year);
3084 week = divmod(today - week1_monday, 7, &day);
3085 }
3086 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
3087 ++year;
3088 week = 0;
3089 }
3090 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003091}
3092
3093/* Miscellaneous methods. */
3094
Tim Peters2a799bf2002-12-16 20:18:38 +00003095static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003096date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00003097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003098 if (PyDate_Check(other)) {
3099 int diff = memcmp(((PyDateTime_Date *)self)->data,
3100 ((PyDateTime_Date *)other)->data,
3101 _PyDateTime_DATE_DATASIZE);
3102 return diff_to_bool(diff, op);
3103 }
Brian Curtindfc80e32011-08-10 20:28:54 -05003104 else
3105 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00003106}
3107
3108static PyObject *
3109date_timetuple(PyDateTime_Date *self)
3110{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003111 return build_struct_time(GET_YEAR(self),
3112 GET_MONTH(self),
3113 GET_DAY(self),
3114 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003115}
3116
Tim Peters12bf3392002-12-24 05:41:27 +00003117static PyObject *
3118date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
3119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003120 PyObject *clone;
3121 PyObject *tuple;
3122 int year = GET_YEAR(self);
3123 int month = GET_MONTH(self);
3124 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003126 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
3127 &year, &month, &day))
3128 return NULL;
3129 tuple = Py_BuildValue("iii", year, month, day);
3130 if (tuple == NULL)
3131 return NULL;
3132 clone = date_new(Py_TYPE(self), tuple, NULL);
3133 Py_DECREF(tuple);
3134 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003135}
3136
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003137static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003138generic_hash(unsigned char *data, int len)
3139{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08003140 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003141}
3142
3143
3144static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003145
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003146static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00003147date_hash(PyDateTime_Date *self)
3148{
Benjamin Petersondec2df32016-09-09 17:46:24 -07003149 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003150 self->hashcode = generic_hash(
3151 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07003152 }
Guido van Rossum254348e2007-11-21 19:29:53 +00003153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003154 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00003155}
3156
3157static PyObject *
3158date_toordinal(PyDateTime_Date *self)
3159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003160 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
3161 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00003162}
3163
3164static PyObject *
3165date_weekday(PyDateTime_Date *self)
3166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003167 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003169 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00003170}
3171
Tim Peters371935f2003-02-01 01:52:50 +00003172/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003173
Tim Petersb57f8f02003-02-01 02:54:15 +00003174/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00003175static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00003176date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003178 PyObject* field;
3179 field = PyBytes_FromStringAndSize((char*)self->data,
3180 _PyDateTime_DATE_DATASIZE);
3181 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00003182}
3183
3184static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003185date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003187 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003188}
3189
3190static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003192 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00003193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003194 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
3195 METH_CLASS,
3196 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
3197 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003199 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
3200 METH_CLASS,
3201 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
3202 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003203
Paul Ganssle09dc2f52017-12-21 00:33:49 -05003204 {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O |
3205 METH_CLASS,
3206 PyDoc_STR("str -> Construct a date from the output of date.isoformat()")},
3207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
3209 PyDoc_STR("Current date or datetime: same as "
3210 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003212 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00003213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003214 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
3215 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
3218 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003220 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3221 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003223 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
3224 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003226 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
3227 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
3228 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003230 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
3231 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003233 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3234 PyDoc_STR("Return the day of the week represented by the date.\n"
3235 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003237 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3238 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3239 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003241 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3242 PyDoc_STR("Return the day of the week represented by the date.\n"
3243 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003245 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3246 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003248 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3249 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003251 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003252};
3253
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003254static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003255PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003256
3257static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003258 date_add, /* nb_add */
3259 date_subtract, /* nb_subtract */
3260 0, /* nb_multiply */
3261 0, /* nb_remainder */
3262 0, /* nb_divmod */
3263 0, /* nb_power */
3264 0, /* nb_negative */
3265 0, /* nb_positive */
3266 0, /* nb_absolute */
3267 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003268};
3269
3270static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003271 PyVarObject_HEAD_INIT(NULL, 0)
3272 "datetime.date", /* tp_name */
3273 sizeof(PyDateTime_Date), /* tp_basicsize */
3274 0, /* tp_itemsize */
3275 0, /* tp_dealloc */
3276 0, /* tp_print */
3277 0, /* tp_getattr */
3278 0, /* tp_setattr */
3279 0, /* tp_reserved */
3280 (reprfunc)date_repr, /* tp_repr */
3281 &date_as_number, /* tp_as_number */
3282 0, /* tp_as_sequence */
3283 0, /* tp_as_mapping */
3284 (hashfunc)date_hash, /* tp_hash */
3285 0, /* tp_call */
3286 (reprfunc)date_str, /* tp_str */
3287 PyObject_GenericGetAttr, /* tp_getattro */
3288 0, /* tp_setattro */
3289 0, /* tp_as_buffer */
3290 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3291 date_doc, /* tp_doc */
3292 0, /* tp_traverse */
3293 0, /* tp_clear */
3294 date_richcompare, /* tp_richcompare */
3295 0, /* tp_weaklistoffset */
3296 0, /* tp_iter */
3297 0, /* tp_iternext */
3298 date_methods, /* tp_methods */
3299 0, /* tp_members */
3300 date_getset, /* tp_getset */
3301 0, /* tp_base */
3302 0, /* tp_dict */
3303 0, /* tp_descr_get */
3304 0, /* tp_descr_set */
3305 0, /* tp_dictoffset */
3306 0, /* tp_init */
3307 0, /* tp_alloc */
3308 date_new, /* tp_new */
3309 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003310};
3311
3312/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003313 * PyDateTime_TZInfo implementation.
3314 */
3315
3316/* This is a pure abstract base class, so doesn't do anything beyond
3317 * raising NotImplemented exceptions. Real tzinfo classes need
3318 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003319 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003320 * be subclasses of this tzinfo class, which is easy and quick to check).
3321 *
3322 * Note: For reasons having to do with pickling of subclasses, we have
3323 * to allow tzinfo objects to be instantiated. This wasn't an issue
3324 * in the Python implementation (__init__() could raise NotImplementedError
3325 * there without ill effect), but doing so in the C implementation hit a
3326 * brick wall.
3327 */
3328
3329static PyObject *
3330tzinfo_nogo(const char* methodname)
3331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003332 PyErr_Format(PyExc_NotImplementedError,
3333 "a tzinfo subclass must implement %s()",
3334 methodname);
3335 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003336}
3337
3338/* Methods. A subclass must implement these. */
3339
Tim Peters52dcce22003-01-23 16:36:11 +00003340static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003341tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003343 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003344}
3345
Tim Peters52dcce22003-01-23 16:36:11 +00003346static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003347tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003349 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003350}
3351
Tim Peters52dcce22003-01-23 16:36:11 +00003352static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003353tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003355 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003356}
3357
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003358
3359static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3360 PyDateTime_Delta *delta,
3361 int factor);
3362static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3363static PyObject *datetime_dst(PyObject *self, PyObject *);
3364
Tim Peters52dcce22003-01-23 16:36:11 +00003365static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003366tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003367{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003368 PyObject *result = NULL;
3369 PyObject *off = NULL, *dst = NULL;
3370 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003371
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003372 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003373 PyErr_SetString(PyExc_TypeError,
3374 "fromutc: argument must be a datetime");
3375 return NULL;
3376 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003377 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003378 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3379 "is not self");
3380 return NULL;
3381 }
Tim Peters52dcce22003-01-23 16:36:11 +00003382
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003383 off = datetime_utcoffset(dt, NULL);
3384 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003385 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003386 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003387 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3388 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003389 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003390 }
Tim Peters52dcce22003-01-23 16:36:11 +00003391
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003392 dst = datetime_dst(dt, NULL);
3393 if (dst == NULL)
3394 goto Fail;
3395 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003396 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3397 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003398 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003399 }
Tim Peters52dcce22003-01-23 16:36:11 +00003400
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003401 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3402 if (delta == NULL)
3403 goto Fail;
3404 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003405 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003406 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003407
3408 Py_DECREF(dst);
3409 dst = call_dst(GET_DT_TZINFO(dt), result);
3410 if (dst == NULL)
3411 goto Fail;
3412 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003413 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003414 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003415 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003416 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003417 if (result == NULL)
3418 goto Fail;
3419 }
3420 Py_DECREF(delta);
3421 Py_DECREF(dst);
3422 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003423 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003424
3425Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003426 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3427 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003428
Miss Islington (bot)e86db342018-02-03 17:41:43 -08003429 /* fall through to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003430Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003431 Py_XDECREF(off);
3432 Py_XDECREF(dst);
3433 Py_XDECREF(delta);
3434 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003435 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003436}
3437
Tim Peters2a799bf2002-12-16 20:18:38 +00003438/*
3439 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003440 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003441 */
3442
Guido van Rossum177e41a2003-01-30 22:06:23 +00003443static PyObject *
3444tzinfo_reduce(PyObject *self)
3445{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003446 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003447 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003448 _Py_IDENTIFIER(__getinitargs__);
3449 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003450
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003451 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003452 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003453 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003454 Py_DECREF(getinitargs);
3455 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003456 return NULL;
3457 }
3458 }
3459 else {
3460 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003461
3462 args = PyTuple_New(0);
3463 if (args == NULL) {
3464 return NULL;
3465 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003466 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003467
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003468 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003469 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003470 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003471 Py_DECREF(getstate);
3472 if (state == NULL) {
3473 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003474 return NULL;
3475 }
3476 }
3477 else {
3478 PyObject **dictptr;
3479 PyErr_Clear();
3480 state = Py_None;
3481 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003482 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003483 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003484 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003485 Py_INCREF(state);
3486 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003488 if (state == Py_None) {
3489 Py_DECREF(state);
3490 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3491 }
3492 else
3493 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003494}
Tim Peters2a799bf2002-12-16 20:18:38 +00003495
3496static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003498 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3499 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003501 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003502 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3503 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003505 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003506 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003509 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003511 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3512 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003514 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003515};
3516
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003517static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003518PyDoc_STR("Abstract base class for time zone info objects.");
3519
Neal Norwitz227b5332006-03-22 09:28:35 +00003520static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003521 PyVarObject_HEAD_INIT(NULL, 0)
3522 "datetime.tzinfo", /* tp_name */
3523 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3524 0, /* tp_itemsize */
3525 0, /* tp_dealloc */
3526 0, /* tp_print */
3527 0, /* tp_getattr */
3528 0, /* tp_setattr */
3529 0, /* tp_reserved */
3530 0, /* tp_repr */
3531 0, /* tp_as_number */
3532 0, /* tp_as_sequence */
3533 0, /* tp_as_mapping */
3534 0, /* tp_hash */
3535 0, /* tp_call */
3536 0, /* tp_str */
3537 PyObject_GenericGetAttr, /* tp_getattro */
3538 0, /* tp_setattro */
3539 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003540 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003541 tzinfo_doc, /* tp_doc */
3542 0, /* tp_traverse */
3543 0, /* tp_clear */
3544 0, /* tp_richcompare */
3545 0, /* tp_weaklistoffset */
3546 0, /* tp_iter */
3547 0, /* tp_iternext */
3548 tzinfo_methods, /* tp_methods */
3549 0, /* tp_members */
3550 0, /* tp_getset */
3551 0, /* tp_base */
3552 0, /* tp_dict */
3553 0, /* tp_descr_get */
3554 0, /* tp_descr_set */
3555 0, /* tp_dictoffset */
3556 0, /* tp_init */
3557 0, /* tp_alloc */
3558 PyType_GenericNew, /* tp_new */
3559 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003560};
3561
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003562static char *timezone_kws[] = {"offset", "name", NULL};
3563
3564static PyObject *
3565timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3566{
3567 PyObject *offset;
3568 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003569 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3570 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003571 return new_timezone(offset, name);
3572
3573 return NULL;
3574}
3575
3576static void
3577timezone_dealloc(PyDateTime_TimeZone *self)
3578{
3579 Py_CLEAR(self->offset);
3580 Py_CLEAR(self->name);
3581 Py_TYPE(self)->tp_free((PyObject *)self);
3582}
3583
3584static PyObject *
3585timezone_richcompare(PyDateTime_TimeZone *self,
3586 PyDateTime_TimeZone *other, int op)
3587{
Brian Curtindfc80e32011-08-10 20:28:54 -05003588 if (op != Py_EQ && op != Py_NE)
3589 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003590 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003591 if (op == Py_EQ)
3592 Py_RETURN_FALSE;
3593 else
3594 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003595 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003596 return delta_richcompare(self->offset, other->offset, op);
3597}
3598
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003599static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003600timezone_hash(PyDateTime_TimeZone *self)
3601{
3602 return delta_hash((PyDateTime_Delta *)self->offset);
3603}
3604
3605/* Check argument type passed to tzname, utcoffset, or dst methods.
3606 Returns 0 for good argument. Returns -1 and sets exception info
3607 otherwise.
3608 */
3609static int
3610_timezone_check_argument(PyObject *dt, const char *meth)
3611{
3612 if (dt == Py_None || PyDateTime_Check(dt))
3613 return 0;
3614 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3615 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3616 return -1;
3617}
3618
3619static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003620timezone_repr(PyDateTime_TimeZone *self)
3621{
3622 /* Note that although timezone is not subclassable, it is convenient
3623 to use Py_TYPE(self)->tp_name here. */
3624 const char *type_name = Py_TYPE(self)->tp_name;
3625
3626 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3627 return PyUnicode_FromFormat("%s.utc", type_name);
3628
3629 if (self->name == NULL)
3630 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3631
3632 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3633 self->name);
3634}
3635
3636
3637static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003638timezone_str(PyDateTime_TimeZone *self)
3639{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003640 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003641 PyObject *offset;
3642 char sign;
3643
3644 if (self->name != NULL) {
3645 Py_INCREF(self->name);
3646 return self->name;
3647 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003648 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003649 (GET_TD_DAYS(self->offset) == 0 &&
3650 GET_TD_SECONDS(self->offset) == 0 &&
3651 GET_TD_MICROSECONDS(self->offset) == 0))
3652 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003653 /* Offset is normalized, so it is negative if days < 0 */
3654 if (GET_TD_DAYS(self->offset) < 0) {
3655 sign = '-';
3656 offset = delta_negative((PyDateTime_Delta *)self->offset);
3657 if (offset == NULL)
3658 return NULL;
3659 }
3660 else {
3661 sign = '+';
3662 offset = self->offset;
3663 Py_INCREF(offset);
3664 }
3665 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003666 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003667 seconds = GET_TD_SECONDS(offset);
3668 Py_DECREF(offset);
3669 minutes = divmod(seconds, 60, &seconds);
3670 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003671 if (microseconds != 0) {
3672 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3673 sign, hours, minutes,
3674 seconds, microseconds);
3675 }
3676 if (seconds != 0) {
3677 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3678 sign, hours, minutes, seconds);
3679 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003680 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003681}
3682
3683static PyObject *
3684timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3685{
3686 if (_timezone_check_argument(dt, "tzname") == -1)
3687 return NULL;
3688
3689 return timezone_str(self);
3690}
3691
3692static PyObject *
3693timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3694{
3695 if (_timezone_check_argument(dt, "utcoffset") == -1)
3696 return NULL;
3697
3698 Py_INCREF(self->offset);
3699 return self->offset;
3700}
3701
3702static PyObject *
3703timezone_dst(PyObject *self, PyObject *dt)
3704{
3705 if (_timezone_check_argument(dt, "dst") == -1)
3706 return NULL;
3707
3708 Py_RETURN_NONE;
3709}
3710
3711static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003712timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3713{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003714 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003715 PyErr_SetString(PyExc_TypeError,
3716 "fromutc: argument must be a datetime");
3717 return NULL;
3718 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003719 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003720 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3721 "is not self");
3722 return NULL;
3723 }
3724
3725 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3726}
3727
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003728static PyObject *
3729timezone_getinitargs(PyDateTime_TimeZone *self)
3730{
3731 if (self->name == NULL)
3732 return Py_BuildValue("(O)", self->offset);
3733 return Py_BuildValue("(OO)", self->offset, self->name);
3734}
3735
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003736static PyMethodDef timezone_methods[] = {
3737 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3738 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003739 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003740
3741 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003742 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003743
3744 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003745 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003746
3747 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3748 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3749
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003750 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3751 PyDoc_STR("pickle support")},
3752
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003753 {NULL, NULL}
3754};
3755
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003756static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003757PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3758
3759static PyTypeObject PyDateTime_TimeZoneType = {
3760 PyVarObject_HEAD_INIT(NULL, 0)
3761 "datetime.timezone", /* tp_name */
3762 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3763 0, /* tp_itemsize */
3764 (destructor)timezone_dealloc, /* tp_dealloc */
3765 0, /* tp_print */
3766 0, /* tp_getattr */
3767 0, /* tp_setattr */
3768 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003769 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003770 0, /* tp_as_number */
3771 0, /* tp_as_sequence */
3772 0, /* tp_as_mapping */
3773 (hashfunc)timezone_hash, /* tp_hash */
3774 0, /* tp_call */
3775 (reprfunc)timezone_str, /* tp_str */
3776 0, /* tp_getattro */
3777 0, /* tp_setattro */
3778 0, /* tp_as_buffer */
3779 Py_TPFLAGS_DEFAULT, /* tp_flags */
3780 timezone_doc, /* tp_doc */
3781 0, /* tp_traverse */
3782 0, /* tp_clear */
3783 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3784 0, /* tp_weaklistoffset */
3785 0, /* tp_iter */
3786 0, /* tp_iternext */
3787 timezone_methods, /* tp_methods */
3788 0, /* tp_members */
3789 0, /* tp_getset */
3790 &PyDateTime_TZInfoType, /* tp_base */
3791 0, /* tp_dict */
3792 0, /* tp_descr_get */
3793 0, /* tp_descr_set */
3794 0, /* tp_dictoffset */
3795 0, /* tp_init */
3796 0, /* tp_alloc */
3797 timezone_new, /* tp_new */
3798};
3799
Tim Peters2a799bf2002-12-16 20:18:38 +00003800/*
Tim Peters37f39822003-01-10 03:49:02 +00003801 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003802 */
3803
Tim Peters37f39822003-01-10 03:49:02 +00003804/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003805 */
3806
3807static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003808time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003810 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003811}
3812
Tim Peters37f39822003-01-10 03:49:02 +00003813static PyObject *
3814time_minute(PyDateTime_Time *self, void *unused)
3815{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003816 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003817}
3818
3819/* The name time_second conflicted with some platform header file. */
3820static PyObject *
3821py_time_second(PyDateTime_Time *self, void *unused)
3822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003823 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003824}
3825
3826static PyObject *
3827time_microsecond(PyDateTime_Time *self, void *unused)
3828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003829 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003830}
3831
3832static PyObject *
3833time_tzinfo(PyDateTime_Time *self, void *unused)
3834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3836 Py_INCREF(result);
3837 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003838}
3839
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003840static PyObject *
3841time_fold(PyDateTime_Time *self, void *unused)
3842{
3843 return PyLong_FromLong(TIME_GET_FOLD(self));
3844}
3845
Tim Peters37f39822003-01-10 03:49:02 +00003846static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003847 {"hour", (getter)time_hour},
3848 {"minute", (getter)time_minute},
3849 {"second", (getter)py_time_second},
3850 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003851 {"tzinfo", (getter)time_tzinfo},
3852 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003853 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003854};
3855
3856/*
3857 * Constructors.
3858 */
3859
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003860static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003861 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003862
Tim Peters2a799bf2002-12-16 20:18:38 +00003863static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003864time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003866 PyObject *self = NULL;
3867 PyObject *state;
3868 int hour = 0;
3869 int minute = 0;
3870 int second = 0;
3871 int usecond = 0;
3872 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003873 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003875 /* Check for invocation from pickle with __getstate__ state */
3876 if (PyTuple_GET_SIZE(args) >= 1 &&
3877 PyTuple_GET_SIZE(args) <= 2 &&
3878 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3879 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003880 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003881 {
3882 PyDateTime_Time *me;
3883 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003885 if (PyTuple_GET_SIZE(args) == 2) {
3886 tzinfo = PyTuple_GET_ITEM(args, 1);
3887 if (check_tzinfo_subclass(tzinfo) < 0) {
3888 PyErr_SetString(PyExc_TypeError, "bad "
3889 "tzinfo state arg");
3890 return NULL;
3891 }
3892 }
3893 aware = (char)(tzinfo != Py_None);
3894 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3895 if (me != NULL) {
3896 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003898 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3899 me->hashcode = -1;
3900 me->hastzinfo = aware;
3901 if (aware) {
3902 Py_INCREF(tzinfo);
3903 me->tzinfo = tzinfo;
3904 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003905 if (pdata[0] & (1 << 7)) {
3906 me->data[0] -= 128;
3907 me->fold = 1;
3908 }
3909 else {
3910 me->fold = 0;
3911 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003912 }
3913 return (PyObject *)me;
3914 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003915
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003916 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003917 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003918 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003919 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3920 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003921 }
3922 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003923}
3924
3925/*
3926 * Destructor.
3927 */
3928
3929static void
Tim Peters37f39822003-01-10 03:49:02 +00003930time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003932 if (HASTZINFO(self)) {
3933 Py_XDECREF(self->tzinfo);
3934 }
3935 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003936}
3937
3938/*
Tim Peters855fe882002-12-22 03:43:39 +00003939 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003940 */
3941
Tim Peters2a799bf2002-12-16 20:18:38 +00003942/* These are all METH_NOARGS, so don't need to check the arglist. */
3943static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003944time_utcoffset(PyObject *self, PyObject *unused) {
3945 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003946}
3947
3948static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003949time_dst(PyObject *self, PyObject *unused) {
3950 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003951}
3952
3953static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003954time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003955 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003956}
3957
3958/*
Tim Peters37f39822003-01-10 03:49:02 +00003959 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003960 */
3961
3962static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003963time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003964{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003965 const char *type_name = Py_TYPE(self)->tp_name;
3966 int h = TIME_GET_HOUR(self);
3967 int m = TIME_GET_MINUTE(self);
3968 int s = TIME_GET_SECOND(self);
3969 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003970 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003971 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003973 if (us)
3974 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3975 type_name, h, m, s, us);
3976 else if (s)
3977 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3978 type_name, h, m, s);
3979 else
3980 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3981 if (result != NULL && HASTZINFO(self))
3982 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003983 if (result != NULL && fold)
3984 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003985 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003986}
3987
Tim Peters37f39822003-01-10 03:49:02 +00003988static PyObject *
3989time_str(PyDateTime_Time *self)
3990{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003991 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003992}
Tim Peters2a799bf2002-12-16 20:18:38 +00003993
3994static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003995time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003996{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003997 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003998 char *timespec = NULL;
3999 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004000 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02004001 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004002 static char *specs[][2] = {
4003 {"hours", "%02d"},
4004 {"minutes", "%02d:%02d"},
4005 {"seconds", "%02d:%02d:%02d"},
4006 {"milliseconds", "%02d:%02d:%02d.%03d"},
4007 {"microseconds", "%02d:%02d:%02d.%06d"},
4008 };
4009 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004010
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004011 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
4012 return NULL;
4013
4014 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4015 if (us == 0) {
4016 /* seconds */
4017 given_spec = 2;
4018 }
4019 else {
4020 /* microseconds */
4021 given_spec = 4;
4022 }
4023 }
4024 else {
4025 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4026 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4027 if (given_spec == 3) {
4028 /* milliseconds */
4029 us = us / 1000;
4030 }
4031 break;
4032 }
4033 }
4034 }
4035
4036 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4037 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4038 return NULL;
4039 }
4040 else {
4041 result = PyUnicode_FromFormat(specs[given_spec][1],
4042 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
4043 TIME_GET_SECOND(self), us);
4044 }
Tim Peters37f39822003-01-10 03:49:02 +00004045
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004046 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004047 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004049 /* We need to append the UTC offset. */
4050 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4051 Py_None) < 0) {
4052 Py_DECREF(result);
4053 return NULL;
4054 }
4055 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
4056 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004057}
4058
Tim Peters37f39822003-01-10 03:49:02 +00004059static PyObject *
4060time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
4061{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004062 PyObject *result;
4063 PyObject *tuple;
4064 PyObject *format;
4065 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00004066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004067 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
4068 &format))
4069 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00004070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004071 /* Python's strftime does insane things with the year part of the
4072 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00004073 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004074 */
4075 tuple = Py_BuildValue("iiiiiiiii",
4076 1900, 1, 1, /* year, month, day */
4077 TIME_GET_HOUR(self),
4078 TIME_GET_MINUTE(self),
4079 TIME_GET_SECOND(self),
4080 0, 1, -1); /* weekday, daynum, dst */
4081 if (tuple == NULL)
4082 return NULL;
4083 assert(PyTuple_Size(tuple) == 9);
4084 result = wrap_strftime((PyObject *)self, format, tuple,
4085 Py_None);
4086 Py_DECREF(tuple);
4087 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004088}
Tim Peters2a799bf2002-12-16 20:18:38 +00004089
4090/*
4091 * Miscellaneous methods.
4092 */
4093
Tim Peters37f39822003-01-10 03:49:02 +00004094static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004095time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00004096{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004097 PyObject *result = NULL;
4098 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00004100
Brian Curtindfc80e32011-08-10 20:28:54 -05004101 if (! PyTime_Check(other))
4102 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004103
4104 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004105 diff = memcmp(((PyDateTime_Time *)self)->data,
4106 ((PyDateTime_Time *)other)->data,
4107 _PyDateTime_TIME_DATASIZE);
4108 return diff_to_bool(diff, op);
4109 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004110 offset1 = time_utcoffset(self, NULL);
4111 if (offset1 == NULL)
4112 return NULL;
4113 offset2 = time_utcoffset(other, NULL);
4114 if (offset2 == NULL)
4115 goto done;
4116 /* If they're both naive, or both aware and have the same offsets,
4117 * we get off cheap. Note that if they're both naive, offset1 ==
4118 * offset2 == Py_None at this point.
4119 */
4120 if ((offset1 == offset2) ||
4121 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4122 delta_cmp(offset1, offset2) == 0)) {
4123 diff = memcmp(((PyDateTime_Time *)self)->data,
4124 ((PyDateTime_Time *)other)->data,
4125 _PyDateTime_TIME_DATASIZE);
4126 result = diff_to_bool(diff, op);
4127 }
4128 /* The hard case: both aware with different UTC offsets */
4129 else if (offset1 != Py_None && offset2 != Py_None) {
4130 int offsecs1, offsecs2;
4131 assert(offset1 != offset2); /* else last "if" handled it */
4132 offsecs1 = TIME_GET_HOUR(self) * 3600 +
4133 TIME_GET_MINUTE(self) * 60 +
4134 TIME_GET_SECOND(self) -
4135 GET_TD_DAYS(offset1) * 86400 -
4136 GET_TD_SECONDS(offset1);
4137 offsecs2 = TIME_GET_HOUR(other) * 3600 +
4138 TIME_GET_MINUTE(other) * 60 +
4139 TIME_GET_SECOND(other) -
4140 GET_TD_DAYS(offset2) * 86400 -
4141 GET_TD_SECONDS(offset2);
4142 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004143 if (diff == 0)
4144 diff = TIME_GET_MICROSECOND(self) -
4145 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004146 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004147 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004148 else if (op == Py_EQ) {
4149 result = Py_False;
4150 Py_INCREF(result);
4151 }
4152 else if (op == Py_NE) {
4153 result = Py_True;
4154 Py_INCREF(result);
4155 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004156 else {
4157 PyErr_SetString(PyExc_TypeError,
4158 "can't compare offset-naive and "
4159 "offset-aware times");
4160 }
4161 done:
4162 Py_DECREF(offset1);
4163 Py_XDECREF(offset2);
4164 return result;
Tim Peters37f39822003-01-10 03:49:02 +00004165}
4166
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004167static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00004168time_hash(PyDateTime_Time *self)
4169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004170 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004171 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01004172 if (TIME_GET_FOLD(self)) {
4173 self0 = new_time_ex2(TIME_GET_HOUR(self),
4174 TIME_GET_MINUTE(self),
4175 TIME_GET_SECOND(self),
4176 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004177 HASTZINFO(self) ? self->tzinfo : Py_None,
4178 0, Py_TYPE(self));
4179 if (self0 == NULL)
4180 return -1;
4181 }
4182 else {
4183 self0 = (PyObject *)self;
4184 Py_INCREF(self0);
4185 }
4186 offset = time_utcoffset(self0, NULL);
4187 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004188
4189 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004190 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00004191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004192 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004193 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004194 self->hashcode = generic_hash(
4195 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004196 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004197 PyObject *temp1, *temp2;
4198 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004199 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004200 seconds = TIME_GET_HOUR(self) * 3600 +
4201 TIME_GET_MINUTE(self) * 60 +
4202 TIME_GET_SECOND(self);
4203 microseconds = TIME_GET_MICROSECOND(self);
4204 temp1 = new_delta(0, seconds, microseconds, 1);
4205 if (temp1 == NULL) {
4206 Py_DECREF(offset);
4207 return -1;
4208 }
4209 temp2 = delta_subtract(temp1, offset);
4210 Py_DECREF(temp1);
4211 if (temp2 == NULL) {
4212 Py_DECREF(offset);
4213 return -1;
4214 }
4215 self->hashcode = PyObject_Hash(temp2);
4216 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004217 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004218 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004219 }
4220 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00004221}
Tim Peters2a799bf2002-12-16 20:18:38 +00004222
Tim Peters12bf3392002-12-24 05:41:27 +00004223static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00004224time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 PyObject *clone;
4227 PyObject *tuple;
4228 int hh = TIME_GET_HOUR(self);
4229 int mm = TIME_GET_MINUTE(self);
4230 int ss = TIME_GET_SECOND(self);
4231 int us = TIME_GET_MICROSECOND(self);
4232 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004233 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004234
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004235 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004236 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004237 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004238 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004239 if (fold != 0 && fold != 1) {
4240 PyErr_SetString(PyExc_ValueError,
4241 "fold must be either 0 or 1");
4242 return NULL;
4243 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004244 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4245 if (tuple == NULL)
4246 return NULL;
4247 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004248 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004249 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004250 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004251 Py_DECREF(tuple);
4252 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004253}
4254
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004255static PyObject *
4256time_fromisoformat(PyObject *cls, PyObject *tstr) {
4257 assert(tstr != NULL);
4258
4259 if (!PyUnicode_Check(tstr)) {
4260 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4261 return NULL;
4262 }
4263
4264 Py_ssize_t len;
4265 const char *p = PyUnicode_AsUTF8AndSize(tstr, &len);
4266
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004267 if (p == NULL) {
4268 goto invalid_string_error;
4269 }
4270
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004271 int hour = 0, minute = 0, second = 0, microsecond = 0;
4272 int tzoffset, tzimicrosecond = 0;
4273 int rv = parse_isoformat_time(p, len,
4274 &hour, &minute, &second, &microsecond,
4275 &tzoffset, &tzimicrosecond);
4276
4277 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004278 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004279 }
4280
4281 PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset,
4282 tzimicrosecond);
4283
4284 if (tzinfo == NULL) {
4285 return NULL;
4286 }
4287
4288 PyObject *t;
4289 if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) {
4290 t = new_time(hour, minute, second, microsecond, tzinfo, 0);
4291 } else {
4292 t = PyObject_CallFunction(cls, "iiiiO",
4293 hour, minute, second, microsecond, tzinfo);
4294 }
4295
4296 Py_DECREF(tzinfo);
4297 return t;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004298
4299invalid_string_error:
4300 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
4301 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004302}
4303
4304
Tim Peters371935f2003-02-01 01:52:50 +00004305/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004306
Tim Peters33e0f382003-01-10 02:05:14 +00004307/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004308 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4309 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004310 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004311 */
4312static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004313time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004315 PyObject *basestate;
4316 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004318 basestate = PyBytes_FromStringAndSize((char *)self->data,
4319 _PyDateTime_TIME_DATASIZE);
4320 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004321 if (proto > 3 && TIME_GET_FOLD(self))
4322 /* Set the first bit of the first byte */
4323 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004324 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4325 result = PyTuple_Pack(1, basestate);
4326 else
4327 result = PyTuple_Pack(2, basestate, self->tzinfo);
4328 Py_DECREF(basestate);
4329 }
4330 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004331}
4332
4333static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004334time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004335{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004336 int proto;
4337 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004338 return NULL;
4339
4340 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004341}
4342
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004343static PyObject *
4344time_reduce(PyDateTime_Time *self, PyObject *arg)
4345{
4346 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4347}
4348
Tim Peters37f39822003-01-10 03:49:02 +00004349static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004350
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004351 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4352 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4353 "[+HH:MM].\n\n"
4354 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004356 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4357 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004359 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4360 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004362 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4363 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004365 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4366 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004368 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4369 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004371 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4372 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004373
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004374 {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS,
4375 PyDoc_STR("string -> time from time.isoformat() output")},
4376
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004377 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004378 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004379
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004380 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4381 PyDoc_STR("__reduce__() -> (cls, state)")},
4382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004383 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004384};
4385
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004386static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004387PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4388\n\
4389All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004390a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004391
Neal Norwitz227b5332006-03-22 09:28:35 +00004392static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004393 PyVarObject_HEAD_INIT(NULL, 0)
4394 "datetime.time", /* tp_name */
4395 sizeof(PyDateTime_Time), /* tp_basicsize */
4396 0, /* tp_itemsize */
4397 (destructor)time_dealloc, /* tp_dealloc */
4398 0, /* tp_print */
4399 0, /* tp_getattr */
4400 0, /* tp_setattr */
4401 0, /* tp_reserved */
4402 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004403 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004404 0, /* tp_as_sequence */
4405 0, /* tp_as_mapping */
4406 (hashfunc)time_hash, /* tp_hash */
4407 0, /* tp_call */
4408 (reprfunc)time_str, /* tp_str */
4409 PyObject_GenericGetAttr, /* tp_getattro */
4410 0, /* tp_setattro */
4411 0, /* tp_as_buffer */
4412 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4413 time_doc, /* tp_doc */
4414 0, /* tp_traverse */
4415 0, /* tp_clear */
4416 time_richcompare, /* tp_richcompare */
4417 0, /* tp_weaklistoffset */
4418 0, /* tp_iter */
4419 0, /* tp_iternext */
4420 time_methods, /* tp_methods */
4421 0, /* tp_members */
4422 time_getset, /* tp_getset */
4423 0, /* tp_base */
4424 0, /* tp_dict */
4425 0, /* tp_descr_get */
4426 0, /* tp_descr_set */
4427 0, /* tp_dictoffset */
4428 0, /* tp_init */
4429 time_alloc, /* tp_alloc */
4430 time_new, /* tp_new */
4431 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004432};
4433
4434/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004435 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004436 */
4437
Tim Petersa9bc1682003-01-11 03:39:11 +00004438/* Accessor properties. Properties for day, month, and year are inherited
4439 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004440 */
4441
4442static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004443datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004445 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004446}
4447
Tim Petersa9bc1682003-01-11 03:39:11 +00004448static PyObject *
4449datetime_minute(PyDateTime_DateTime *self, void *unused)
4450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004451 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004452}
4453
4454static PyObject *
4455datetime_second(PyDateTime_DateTime *self, void *unused)
4456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004457 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004458}
4459
4460static PyObject *
4461datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004463 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004464}
4465
4466static PyObject *
4467datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4468{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004469 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4470 Py_INCREF(result);
4471 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004472}
4473
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004474static PyObject *
4475datetime_fold(PyDateTime_DateTime *self, void *unused)
4476{
4477 return PyLong_FromLong(DATE_GET_FOLD(self));
4478}
4479
Tim Petersa9bc1682003-01-11 03:39:11 +00004480static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004481 {"hour", (getter)datetime_hour},
4482 {"minute", (getter)datetime_minute},
4483 {"second", (getter)datetime_second},
4484 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004485 {"tzinfo", (getter)datetime_tzinfo},
4486 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004487 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004488};
4489
4490/*
4491 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004492 */
4493
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004494static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004495 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004496 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004497};
4498
Tim Peters2a799bf2002-12-16 20:18:38 +00004499static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004500datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004502 PyObject *self = NULL;
4503 PyObject *state;
4504 int year;
4505 int month;
4506 int day;
4507 int hour = 0;
4508 int minute = 0;
4509 int second = 0;
4510 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004511 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004512 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004514 /* Check for invocation from pickle with __getstate__ state */
4515 if (PyTuple_GET_SIZE(args) >= 1 &&
4516 PyTuple_GET_SIZE(args) <= 2 &&
4517 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4518 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004519 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004520 {
4521 PyDateTime_DateTime *me;
4522 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004524 if (PyTuple_GET_SIZE(args) == 2) {
4525 tzinfo = PyTuple_GET_ITEM(args, 1);
4526 if (check_tzinfo_subclass(tzinfo) < 0) {
4527 PyErr_SetString(PyExc_TypeError, "bad "
4528 "tzinfo state arg");
4529 return NULL;
4530 }
4531 }
4532 aware = (char)(tzinfo != Py_None);
4533 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4534 if (me != NULL) {
4535 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004537 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4538 me->hashcode = -1;
4539 me->hastzinfo = aware;
4540 if (aware) {
4541 Py_INCREF(tzinfo);
4542 me->tzinfo = tzinfo;
4543 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004544 if (pdata[2] & (1 << 7)) {
4545 me->data[2] -= 128;
4546 me->fold = 1;
4547 }
4548 else {
4549 me->fold = 0;
4550 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004551 }
4552 return (PyObject *)me;
4553 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004554
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004555 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004556 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004557 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004558 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004559 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004560 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004561 }
4562 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004563}
4564
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004565/* TM_FUNC is the shared type of _PyTime_localtime() and
4566 * _PyTime_gmtime(). */
4567typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004568
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004569/* As of version 2015f max fold in IANA database is
4570 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004571static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004572/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004573static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004574
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004575static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004576utc_to_seconds(int year, int month, int day,
4577 int hour, int minute, int second)
4578{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004579 long long ordinal;
4580
4581 /* ymd_to_ord() doesn't support year <= 0 */
4582 if (year < MINYEAR || year > MAXYEAR) {
4583 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4584 return -1;
4585 }
4586
4587 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004588 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4589}
4590
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004591static long long
4592local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004593{
4594 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004595 time_t t;
4596 u -= epoch;
4597 t = u;
4598 if (t != u) {
4599 PyErr_SetString(PyExc_OverflowError,
4600 "timestamp out of range for platform time_t");
4601 return -1;
4602 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004603 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004604 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004605 return utc_to_seconds(local_time.tm_year + 1900,
4606 local_time.tm_mon + 1,
4607 local_time.tm_mday,
4608 local_time.tm_hour,
4609 local_time.tm_min,
4610 local_time.tm_sec);
4611}
4612
Tim Petersa9bc1682003-01-11 03:39:11 +00004613/* Internal helper.
4614 * Build datetime from a time_t and a distinct count of microseconds.
4615 * Pass localtime or gmtime for f, to control the interpretation of timet.
4616 */
4617static PyObject *
4618datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004619 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004620{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004621 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004622 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004623
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004624 if (f(timet, &tm) != 0)
4625 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004626
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004627 year = tm.tm_year + 1900;
4628 month = tm.tm_mon + 1;
4629 day = tm.tm_mday;
4630 hour = tm.tm_hour;
4631 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004632 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004633 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004634 * except to the extent that passing them on to the datetime
4635 * constructor would raise ValueError for a reason that
4636 * made no sense to the user.
4637 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004638 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004639
Victor Stinnerb67f0962017-02-10 10:34:02 +01004640 /* local timezone requires to compute fold */
Miss Islington (bot)97364932018-07-25 13:34:09 -07004641 if (tzinfo == Py_None && f == _PyTime_localtime
4642 /* On Windows, passing a negative value to local results
4643 * in an OSError because localtime_s on Windows does
4644 * not support negative timestamps. Unfortunately this
4645 * means that fold detection for time values between
4646 * 0 and max_fold_seconds will result in an identical
4647 * error since we subtract max_fold_seconds to detect a
4648 * fold. However, since we know there haven't been any
4649 * folds in the interval [0, max_fold_seconds) in any
4650 * timezone, we can hackily just forego fold detection
4651 * for this time range.
4652 */
4653#ifdef MS_WINDOWS
4654 && (timet - max_fold_seconds > 0)
4655#endif
4656 ) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004657 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004658
4659 result_seconds = utc_to_seconds(year, month, day,
4660 hour, minute, second);
4661 /* Probe max_fold_seconds to detect a fold. */
4662 probe_seconds = local(epoch + timet - max_fold_seconds);
4663 if (probe_seconds == -1)
4664 return NULL;
4665 transition = result_seconds - probe_seconds - max_fold_seconds;
4666 if (transition < 0) {
4667 probe_seconds = local(epoch + timet + transition);
4668 if (probe_seconds == -1)
4669 return NULL;
4670 if (probe_seconds == result_seconds)
4671 fold = 1;
4672 }
4673 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004674 return new_datetime_subclass_fold_ex(year, month, day, hour, minute,
4675 second, us, tzinfo, fold, cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004676}
4677
4678/* Internal helper.
4679 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4680 * to control the interpretation of the timestamp. Since a double doesn't
4681 * have enough bits to cover a datetime's full range of precision, it's
4682 * better to call datetime_from_timet_and_us provided you have a way
4683 * to get that much precision (e.g., C time() isn't good enough).
4684 */
4685static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004686datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004687 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004689 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004690 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004691
Victor Stinnere4a994d2015-03-30 01:10:14 +02004692 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004693 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004694 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004695
Victor Stinner21f58932012-03-14 00:15:40 +01004696 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004697}
4698
4699/* Internal helper.
4700 * Build most accurate possible datetime for current time. Pass localtime or
4701 * gmtime for f as appropriate.
4702 */
4703static PyObject *
4704datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4705{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004706 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004707 time_t secs;
4708 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004709
Victor Stinner1e2b6882015-09-18 13:23:02 +02004710 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004711 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004712 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004713
Victor Stinner1e2b6882015-09-18 13:23:02 +02004714 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004715}
4716
Larry Hastings61272b72014-01-07 12:41:53 -08004717/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004718
4719@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004720datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004721
4722 tz: object = None
4723 Timezone object.
4724
4725Returns new datetime object representing current time local to tz.
4726
4727If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004728[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004729
Larry Hastings31826802013-10-19 00:09:25 -07004730static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004731datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004732/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004733{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004734 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004735
Larry Hastings31826802013-10-19 00:09:25 -07004736 /* Return best possible local time -- this isn't constrained by the
4737 * precision of a timestamp.
4738 */
4739 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004740 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004741
Larry Hastings5c661892014-01-24 06:17:25 -08004742 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004743 tz == Py_None ? _PyTime_localtime :
4744 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004745 tz);
4746 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004747 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004748 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004749 }
4750 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004751}
4752
Tim Petersa9bc1682003-01-11 03:39:11 +00004753/* Return best possible UTC time -- this isn't constrained by the
4754 * precision of a timestamp.
4755 */
4756static PyObject *
4757datetime_utcnow(PyObject *cls, PyObject *dummy)
4758{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004759 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004760}
4761
Tim Peters2a799bf2002-12-16 20:18:38 +00004762/* Return new local datetime from timestamp (Python timestamp -- a double). */
4763static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004764datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004766 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004767 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004768 PyObject *tzinfo = Py_None;
4769 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004770
Victor Stinner5d272cc2012-03-13 13:35:55 +01004771 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004772 keywords, &timestamp, &tzinfo))
4773 return NULL;
4774 if (check_tzinfo_subclass(tzinfo) < 0)
4775 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004777 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004778 tzinfo == Py_None ? _PyTime_localtime :
4779 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004780 timestamp,
4781 tzinfo);
4782 if (self != NULL && tzinfo != Py_None) {
4783 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004784 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004785 }
4786 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004787}
4788
Tim Petersa9bc1682003-01-11 03:39:11 +00004789/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4790static PyObject *
4791datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4792{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004793 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004794 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004795
Victor Stinner5d272cc2012-03-13 13:35:55 +01004796 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004797 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004798 Py_None);
4799 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004800}
4801
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004802/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004803static PyObject *
4804datetime_strptime(PyObject *cls, PyObject *args)
4805{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004806 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004807 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004808 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004809
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004810 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004811 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004812
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004813 if (module == NULL) {
4814 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004815 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004816 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004817 }
Victor Stinner20401de2016-12-09 15:24:31 +01004818 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4819 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004820}
4821
Tim Petersa9bc1682003-01-11 03:39:11 +00004822/* Return new datetime from date/datetime and time arguments. */
4823static PyObject *
4824datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4825{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004826 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004827 PyObject *date;
4828 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004829 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004830 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004831
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004832 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004833 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004834 &PyDateTime_TimeType, &time, &tzinfo)) {
4835 if (tzinfo == NULL) {
4836 if (HASTZINFO(time))
4837 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4838 else
4839 tzinfo = Py_None;
4840 }
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004841 result = new_datetime_subclass_fold_ex(GET_YEAR(date),
4842 GET_MONTH(date),
4843 GET_DAY(date),
4844 TIME_GET_HOUR(time),
4845 TIME_GET_MINUTE(time),
4846 TIME_GET_SECOND(time),
4847 TIME_GET_MICROSECOND(time),
4848 tzinfo,
4849 TIME_GET_FOLD(time),
4850 cls);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004851 }
4852 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004853}
Tim Peters2a799bf2002-12-16 20:18:38 +00004854
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004855static PyObject *
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004856_sanitize_isoformat_str(PyObject *dtstr, int *needs_decref) {
4857 // `fromisoformat` allows surrogate characters in exactly one position,
4858 // the separator; to allow datetime_fromisoformat to make the simplifying
4859 // assumption that all valid strings can be encoded in UTF-8, this function
4860 // replaces any surrogate character separators with `T`.
4861 Py_ssize_t len = PyUnicode_GetLength(dtstr);
4862 *needs_decref = 0;
4863 if (len <= 10 || !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) {
4864 return dtstr;
4865 }
4866
4867 PyObject *str_out = PyUnicode_New(len, PyUnicode_MAX_CHAR_VALUE(dtstr));
4868 if (str_out == NULL) {
4869 return NULL;
4870 }
4871
4872 if (PyUnicode_CopyCharacters(str_out, 0, dtstr, 0, len) == -1 ||
4873 PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) {
4874 Py_DECREF(str_out);
4875 return NULL;
4876 }
4877
4878 *needs_decref = 1;
4879 return str_out;
4880}
4881
4882static PyObject *
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004883datetime_fromisoformat(PyObject* cls, PyObject *dtstr) {
4884 assert(dtstr != NULL);
4885
4886 if (!PyUnicode_Check(dtstr)) {
4887 PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str");
4888 return NULL;
4889 }
4890
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004891 int needs_decref = 0;
4892 dtstr = _sanitize_isoformat_str(dtstr, &needs_decref);
4893 if (dtstr == NULL) {
4894 goto error;
4895 }
4896
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004897 Py_ssize_t len;
4898 const char * dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004899
4900 if (dt_ptr == NULL) {
4901 goto invalid_string_error;
4902 }
4903
4904 const char *p = dt_ptr;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004905
4906 int year = 0, month = 0, day = 0;
4907 int hour = 0, minute = 0, second = 0, microsecond = 0;
4908 int tzoffset = 0, tzusec = 0;
4909
4910 // date has a fixed length of 10
4911 int rv = parse_isoformat_date(p, &year, &month, &day);
4912
4913 if (!rv && len > 10) {
4914 // In UTF-8, the length of multi-byte characters is encoded in the MSB
4915 if ((p[10] & 0x80) == 0) {
4916 p += 11;
4917 } else {
4918 switch(p[10] & 0xf0) {
4919 case 0xe0:
4920 p += 13;
4921 break;
4922 case 0xf0:
4923 p += 14;
4924 break;
4925 default:
4926 p += 12;
4927 break;
4928 }
4929 }
4930
4931 len -= (p - dt_ptr);
4932 rv = parse_isoformat_time(p, len,
4933 &hour, &minute, &second, &microsecond,
4934 &tzoffset, &tzusec);
4935 }
4936 if (rv < 0) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004937 goto invalid_string_error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004938 }
4939
4940 PyObject* tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec);
4941 if (tzinfo == NULL) {
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004942 goto error;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004943 }
4944
Paul Ganssle9f1b7b92018-01-16 13:06:31 -05004945 PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute,
4946 second, microsecond, tzinfo, cls);
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004947
4948 Py_DECREF(tzinfo);
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004949 if (needs_decref) {
4950 Py_DECREF(dtstr);
4951 }
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004952 return dt;
Miss Islington (bot)89b16542018-08-23 11:54:33 -04004953
4954invalid_string_error:
4955 PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr);
4956
4957error:
4958 if (needs_decref) {
4959 Py_DECREF(dtstr);
4960 }
4961
4962 return NULL;
Paul Ganssle09dc2f52017-12-21 00:33:49 -05004963}
4964
4965
Tim Peters2a799bf2002-12-16 20:18:38 +00004966/*
4967 * Destructor.
4968 */
4969
4970static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004971datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004973 if (HASTZINFO(self)) {
4974 Py_XDECREF(self->tzinfo);
4975 }
4976 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004977}
4978
4979/*
4980 * Indirect access to tzinfo methods.
4981 */
4982
Tim Peters2a799bf2002-12-16 20:18:38 +00004983/* These are all METH_NOARGS, so don't need to check the arglist. */
4984static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004985datetime_utcoffset(PyObject *self, PyObject *unused) {
4986 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004987}
4988
4989static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004990datetime_dst(PyObject *self, PyObject *unused) {
4991 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004992}
4993
4994static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004995datetime_tzname(PyObject *self, PyObject *unused) {
4996 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004997}
4998
4999/*
Tim Petersa9bc1682003-01-11 03:39:11 +00005000 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00005001 */
5002
Tim Petersa9bc1682003-01-11 03:39:11 +00005003/* factor must be 1 (to add) or -1 (to subtract). The result inherits
5004 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00005005 */
5006static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005007add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005008 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00005009{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005010 /* Note that the C-level additions can't overflow, because of
5011 * invariant bounds on the member values.
5012 */
5013 int year = GET_YEAR(date);
5014 int month = GET_MONTH(date);
5015 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
5016 int hour = DATE_GET_HOUR(date);
5017 int minute = DATE_GET_MINUTE(date);
5018 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
5019 int microsecond = DATE_GET_MICROSECOND(date) +
5020 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00005021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005022 assert(factor == 1 || factor == -1);
5023 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01005024 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005025 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01005026 }
5027
5028 return new_datetime(year, month, day,
5029 hour, minute, second, microsecond,
5030 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005031}
5032
5033static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005034datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005036 if (PyDateTime_Check(left)) {
5037 /* datetime + ??? */
5038 if (PyDelta_Check(right))
5039 /* datetime + delta */
5040 return add_datetime_timedelta(
5041 (PyDateTime_DateTime *)left,
5042 (PyDateTime_Delta *)right,
5043 1);
5044 }
5045 else if (PyDelta_Check(left)) {
5046 /* delta + datetime */
5047 return add_datetime_timedelta((PyDateTime_DateTime *) right,
5048 (PyDateTime_Delta *) left,
5049 1);
5050 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005051 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00005052}
5053
5054static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005055datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00005056{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005057 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00005058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005059 if (PyDateTime_Check(left)) {
5060 /* datetime - ??? */
5061 if (PyDateTime_Check(right)) {
5062 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005063 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005064 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00005065
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005066 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
5067 offset2 = offset1 = Py_None;
5068 Py_INCREF(offset1);
5069 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005070 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005071 else {
5072 offset1 = datetime_utcoffset(left, NULL);
5073 if (offset1 == NULL)
5074 return NULL;
5075 offset2 = datetime_utcoffset(right, NULL);
5076 if (offset2 == NULL) {
5077 Py_DECREF(offset1);
5078 return NULL;
5079 }
5080 if ((offset1 != Py_None) != (offset2 != Py_None)) {
5081 PyErr_SetString(PyExc_TypeError,
5082 "can't subtract offset-naive and "
5083 "offset-aware datetimes");
5084 Py_DECREF(offset1);
5085 Py_DECREF(offset2);
5086 return NULL;
5087 }
5088 }
5089 if ((offset1 != offset2) &&
5090 delta_cmp(offset1, offset2) != 0) {
5091 offdiff = delta_subtract(offset1, offset2);
5092 if (offdiff == NULL) {
5093 Py_DECREF(offset1);
5094 Py_DECREF(offset2);
5095 return NULL;
5096 }
5097 }
5098 Py_DECREF(offset1);
5099 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005100 delta_d = ymd_to_ord(GET_YEAR(left),
5101 GET_MONTH(left),
5102 GET_DAY(left)) -
5103 ymd_to_ord(GET_YEAR(right),
5104 GET_MONTH(right),
5105 GET_DAY(right));
5106 /* These can't overflow, since the values are
5107 * normalized. At most this gives the number of
5108 * seconds in one day.
5109 */
5110 delta_s = (DATE_GET_HOUR(left) -
5111 DATE_GET_HOUR(right)) * 3600 +
5112 (DATE_GET_MINUTE(left) -
5113 DATE_GET_MINUTE(right)) * 60 +
5114 (DATE_GET_SECOND(left) -
5115 DATE_GET_SECOND(right));
5116 delta_us = DATE_GET_MICROSECOND(left) -
5117 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005118 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01005119 if (result == NULL)
5120 return NULL;
5121
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005122 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03005123 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005124 Py_DECREF(offdiff);
5125 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005126 }
5127 else if (PyDelta_Check(right)) {
5128 /* datetime - delta */
5129 result = add_datetime_timedelta(
5130 (PyDateTime_DateTime *)left,
5131 (PyDateTime_Delta *)right,
5132 -1);
5133 }
5134 }
Tim Peters2a799bf2002-12-16 20:18:38 +00005135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005136 if (result == Py_NotImplemented)
5137 Py_INCREF(result);
5138 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005139}
5140
5141/* Various ways to turn a datetime into a string. */
5142
5143static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005144datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005146 const char *type_name = Py_TYPE(self)->tp_name;
5147 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00005148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005149 if (DATE_GET_MICROSECOND(self)) {
5150 baserepr = PyUnicode_FromFormat(
5151 "%s(%d, %d, %d, %d, %d, %d, %d)",
5152 type_name,
5153 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5154 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5155 DATE_GET_SECOND(self),
5156 DATE_GET_MICROSECOND(self));
5157 }
5158 else if (DATE_GET_SECOND(self)) {
5159 baserepr = PyUnicode_FromFormat(
5160 "%s(%d, %d, %d, %d, %d, %d)",
5161 type_name,
5162 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5163 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5164 DATE_GET_SECOND(self));
5165 }
5166 else {
5167 baserepr = PyUnicode_FromFormat(
5168 "%s(%d, %d, %d, %d, %d)",
5169 type_name,
5170 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
5171 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
5172 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005173 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
5174 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005175 if (baserepr == NULL || ! HASTZINFO(self))
5176 return baserepr;
5177 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00005178}
5179
Tim Petersa9bc1682003-01-11 03:39:11 +00005180static PyObject *
5181datetime_str(PyDateTime_DateTime *self)
5182{
Victor Stinner4c381542016-12-09 00:33:39 +01005183 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00005184}
Tim Peters2a799bf2002-12-16 20:18:38 +00005185
5186static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005187datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00005188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005189 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005190 char *timespec = NULL;
5191 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005192 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005193 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005194 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005195 static char *specs[][2] = {
5196 {"hours", "%04d-%02d-%02d%c%02d"},
5197 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
5198 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
5199 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
5200 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
5201 };
5202 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00005203
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005204 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005205 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005206
5207 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
5208 if (us == 0) {
5209 /* seconds */
5210 given_spec = 2;
5211 }
5212 else {
5213 /* microseconds */
5214 given_spec = 4;
5215 }
5216 }
5217 else {
5218 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
5219 if (strcmp(timespec, specs[given_spec][0]) == 0) {
5220 if (given_spec == 3) {
5221 us = us / 1000;
5222 }
5223 break;
5224 }
5225 }
5226 }
5227
5228 if (given_spec == Py_ARRAY_LENGTH(specs)) {
5229 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
5230 return NULL;
5231 }
5232 else {
5233 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005234 GET_YEAR(self), GET_MONTH(self),
5235 GET_DAY(self), (int)sep,
5236 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
5237 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005238 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00005239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005240 if (!result || !HASTZINFO(self))
5241 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 /* We need to append the UTC offset. */
5244 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
5245 (PyObject *)self) < 0) {
5246 Py_DECREF(result);
5247 return NULL;
5248 }
5249 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
5250 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005251}
5252
Tim Petersa9bc1682003-01-11 03:39:11 +00005253static PyObject *
5254datetime_ctime(PyDateTime_DateTime *self)
5255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005256 return format_ctime((PyDateTime_Date *)self,
5257 DATE_GET_HOUR(self),
5258 DATE_GET_MINUTE(self),
5259 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005260}
5261
Tim Peters2a799bf2002-12-16 20:18:38 +00005262/* Miscellaneous methods. */
5263
Tim Petersa9bc1682003-01-11 03:39:11 +00005264static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005265flip_fold(PyObject *dt)
5266{
5267 return new_datetime_ex2(GET_YEAR(dt),
5268 GET_MONTH(dt),
5269 GET_DAY(dt),
5270 DATE_GET_HOUR(dt),
5271 DATE_GET_MINUTE(dt),
5272 DATE_GET_SECOND(dt),
5273 DATE_GET_MICROSECOND(dt),
5274 HASTZINFO(dt) ?
5275 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
5276 !DATE_GET_FOLD(dt),
5277 Py_TYPE(dt));
5278}
5279
5280static PyObject *
5281get_flip_fold_offset(PyObject *dt)
5282{
5283 PyObject *result, *flip_dt;
5284
5285 flip_dt = flip_fold(dt);
5286 if (flip_dt == NULL)
5287 return NULL;
5288 result = datetime_utcoffset(flip_dt, NULL);
5289 Py_DECREF(flip_dt);
5290 return result;
5291}
5292
5293/* PEP 495 exception: Whenever one or both of the operands in
5294 * inter-zone comparison is such that its utcoffset() depends
Serhiy Storchakafd936662018-03-28 23:05:24 +03005295 * on the value of its fold attribute, the result is False.
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005296 *
5297 * Return 1 if exception applies, 0 if not, and -1 on error.
5298 */
5299static int
5300pep495_eq_exception(PyObject *self, PyObject *other,
5301 PyObject *offset_self, PyObject *offset_other)
5302{
5303 int result = 0;
5304 PyObject *flip_offset;
5305
5306 flip_offset = get_flip_fold_offset(self);
5307 if (flip_offset == NULL)
5308 return -1;
5309 if (flip_offset != offset_self &&
5310 delta_cmp(flip_offset, offset_self))
5311 {
5312 result = 1;
5313 goto done;
5314 }
5315 Py_DECREF(flip_offset);
5316
5317 flip_offset = get_flip_fold_offset(other);
5318 if (flip_offset == NULL)
5319 return -1;
5320 if (flip_offset != offset_other &&
5321 delta_cmp(flip_offset, offset_other))
5322 result = 1;
5323 done:
5324 Py_DECREF(flip_offset);
5325 return result;
5326}
5327
5328static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00005329datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00005330{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005331 PyObject *result = NULL;
5332 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005333 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00005334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005335 if (! PyDateTime_Check(other)) {
5336 if (PyDate_Check(other)) {
5337 /* Prevent invocation of date_richcompare. We want to
5338 return NotImplemented here to give the other object
5339 a chance. But since DateTime is a subclass of
5340 Date, if the other object is a Date, it would
5341 compute an ordering based on the date part alone,
5342 and we don't want that. So force unequal or
5343 uncomparable here in that case. */
5344 if (op == Py_EQ)
5345 Py_RETURN_FALSE;
5346 if (op == Py_NE)
5347 Py_RETURN_TRUE;
5348 return cmperror(self, other);
5349 }
Brian Curtindfc80e32011-08-10 20:28:54 -05005350 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005351 }
Tim Petersa9bc1682003-01-11 03:39:11 +00005352
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005353 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005354 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5355 ((PyDateTime_DateTime *)other)->data,
5356 _PyDateTime_DATETIME_DATASIZE);
5357 return diff_to_bool(diff, op);
5358 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005359 offset1 = datetime_utcoffset(self, NULL);
5360 if (offset1 == NULL)
5361 return NULL;
5362 offset2 = datetime_utcoffset(other, NULL);
5363 if (offset2 == NULL)
5364 goto done;
5365 /* If they're both naive, or both aware and have the same offsets,
5366 * we get off cheap. Note that if they're both naive, offset1 ==
5367 * offset2 == Py_None at this point.
5368 */
5369 if ((offset1 == offset2) ||
5370 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
5371 delta_cmp(offset1, offset2) == 0)) {
5372 diff = memcmp(((PyDateTime_DateTime *)self)->data,
5373 ((PyDateTime_DateTime *)other)->data,
5374 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005375 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5376 int ex = pep495_eq_exception(self, other, offset1, offset2);
5377 if (ex == -1)
5378 goto done;
5379 if (ex)
5380 diff = 1;
5381 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005382 result = diff_to_bool(diff, op);
5383 }
5384 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005385 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00005386
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005387 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005388 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
5389 other);
5390 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005391 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005392 diff = GET_TD_DAYS(delta);
5393 if (diff == 0)
5394 diff = GET_TD_SECONDS(delta) |
5395 GET_TD_MICROSECONDS(delta);
5396 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005397 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
5398 int ex = pep495_eq_exception(self, other, offset1, offset2);
5399 if (ex == -1)
5400 goto done;
5401 if (ex)
5402 diff = 1;
5403 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005404 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005405 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04005406 else if (op == Py_EQ) {
5407 result = Py_False;
5408 Py_INCREF(result);
5409 }
5410 else if (op == Py_NE) {
5411 result = Py_True;
5412 Py_INCREF(result);
5413 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005414 else {
5415 PyErr_SetString(PyExc_TypeError,
5416 "can't compare offset-naive and "
5417 "offset-aware datetimes");
5418 }
5419 done:
5420 Py_DECREF(offset1);
5421 Py_XDECREF(offset2);
5422 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005423}
5424
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005425static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005426datetime_hash(PyDateTime_DateTime *self)
5427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005428 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005429 PyObject *offset, *self0;
5430 if (DATE_GET_FOLD(self)) {
5431 self0 = new_datetime_ex2(GET_YEAR(self),
5432 GET_MONTH(self),
5433 GET_DAY(self),
5434 DATE_GET_HOUR(self),
5435 DATE_GET_MINUTE(self),
5436 DATE_GET_SECOND(self),
5437 DATE_GET_MICROSECOND(self),
5438 HASTZINFO(self) ? self->tzinfo : Py_None,
5439 0, Py_TYPE(self));
5440 if (self0 == NULL)
5441 return -1;
5442 }
5443 else {
5444 self0 = (PyObject *)self;
5445 Py_INCREF(self0);
5446 }
5447 offset = datetime_utcoffset(self0, NULL);
5448 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005449
5450 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005451 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005453 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005454 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005455 self->hashcode = generic_hash(
5456 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005457 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005458 PyObject *temp1, *temp2;
5459 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005461 assert(HASTZINFO(self));
5462 days = ymd_to_ord(GET_YEAR(self),
5463 GET_MONTH(self),
5464 GET_DAY(self));
5465 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005466 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005467 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005468 temp1 = new_delta(days, seconds,
5469 DATE_GET_MICROSECOND(self),
5470 1);
5471 if (temp1 == NULL) {
5472 Py_DECREF(offset);
5473 return -1;
5474 }
5475 temp2 = delta_subtract(temp1, offset);
5476 Py_DECREF(temp1);
5477 if (temp2 == NULL) {
5478 Py_DECREF(offset);
5479 return -1;
5480 }
5481 self->hashcode = PyObject_Hash(temp2);
5482 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005483 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005484 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005485 }
5486 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005487}
Tim Peters2a799bf2002-12-16 20:18:38 +00005488
5489static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005490datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005492 PyObject *clone;
5493 PyObject *tuple;
5494 int y = GET_YEAR(self);
5495 int m = GET_MONTH(self);
5496 int d = GET_DAY(self);
5497 int hh = DATE_GET_HOUR(self);
5498 int mm = DATE_GET_MINUTE(self);
5499 int ss = DATE_GET_SECOND(self);
5500 int us = DATE_GET_MICROSECOND(self);
5501 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005502 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005503
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005504 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005505 datetime_kws,
5506 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005507 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005508 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005509 if (fold != 0 && fold != 1) {
5510 PyErr_SetString(PyExc_ValueError,
5511 "fold must be either 0 or 1");
5512 return NULL;
5513 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005514 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5515 if (tuple == NULL)
5516 return NULL;
5517 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005518 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005519 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005520 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005521 Py_DECREF(tuple);
5522 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005523}
5524
5525static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005526local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005527{
5528 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005529 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005530 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005531 PyObject *nameo = NULL;
5532 const char *zone = NULL;
5533
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005534 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005535 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005536#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005537 zone = local_time_tm.tm_zone;
5538 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005539#else /* HAVE_STRUCT_TM_TM_ZONE */
5540 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005541 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005542 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005543 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005544 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005545 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005546 local_time = new_datetime(local_time_tm.tm_year + 1900,
5547 local_time_tm.tm_mon + 1,
5548 local_time_tm.tm_mday,
5549 local_time_tm.tm_hour,
5550 local_time_tm.tm_min,
5551 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005552 if (local_time == NULL) {
5553 return NULL;
5554 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005555 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005556 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005557 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5558 utc_time_tm.tm_mon + 1,
5559 utc_time_tm.tm_mday,
5560 utc_time_tm.tm_hour,
5561 utc_time_tm.tm_min,
5562 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005563 if (utc_time == NULL) {
5564 Py_DECREF(local_time);
5565 return NULL;
5566 }
5567 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005568 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005569 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005570 }
5571#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005572 if (delta == NULL) {
5573 return NULL;
5574 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005575 if (zone != NULL) {
5576 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5577 if (nameo == NULL)
5578 goto error;
5579 }
5580 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005581 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005582 error:
5583 Py_DECREF(delta);
5584 return result;
5585}
5586
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005587static PyObject *
5588local_timezone(PyDateTime_DateTime *utc_time)
5589{
5590 time_t timestamp;
5591 PyObject *delta;
5592 PyObject *one_second;
5593 PyObject *seconds;
5594
5595 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5596 if (delta == NULL)
5597 return NULL;
5598 one_second = new_delta(0, 1, 0, 0);
5599 if (one_second == NULL) {
5600 Py_DECREF(delta);
5601 return NULL;
5602 }
5603 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5604 (PyDateTime_Delta *)one_second);
5605 Py_DECREF(one_second);
5606 Py_DECREF(delta);
5607 if (seconds == NULL)
5608 return NULL;
5609 timestamp = _PyLong_AsTime_t(seconds);
5610 Py_DECREF(seconds);
5611 if (timestamp == -1 && PyErr_Occurred())
5612 return NULL;
5613 return local_timezone_from_timestamp(timestamp);
5614}
5615
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005616static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005617local_to_seconds(int year, int month, int day,
5618 int hour, int minute, int second, int fold);
5619
5620static PyObject *
5621local_timezone_from_local(PyDateTime_DateTime *local_dt)
5622{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005623 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005624 time_t timestamp;
5625 seconds = local_to_seconds(GET_YEAR(local_dt),
5626 GET_MONTH(local_dt),
5627 GET_DAY(local_dt),
5628 DATE_GET_HOUR(local_dt),
5629 DATE_GET_MINUTE(local_dt),
5630 DATE_GET_SECOND(local_dt),
5631 DATE_GET_FOLD(local_dt));
5632 if (seconds == -1)
5633 return NULL;
5634 /* XXX: add bounds check */
5635 timestamp = seconds - epoch;
5636 return local_timezone_from_timestamp(timestamp);
5637}
5638
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005639static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005640datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005641{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005642 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005643 PyObject *offset;
5644 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005645 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005646 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005647 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005648
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005649 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005650 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005651 return NULL;
5652
5653 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005654 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005655
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005656 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005657 naive:
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005658 self_tzinfo = local_timezone_from_local(self);
5659 if (self_tzinfo == NULL)
5660 return NULL;
5661 } else {
5662 self_tzinfo = self->tzinfo;
5663 Py_INCREF(self_tzinfo);
5664 }
Tim Peters521fc152002-12-31 17:36:56 +00005665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005666 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005667 if (self_tzinfo == tzinfo) {
5668 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005669 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005670 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005671 }
Tim Peters521fc152002-12-31 17:36:56 +00005672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005673 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005674 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5675 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005676 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005677 return NULL;
Miss Islington (bot)037e9122018-06-10 15:02:24 -07005678 else if(offset == Py_None) {
5679 Py_DECREF(offset);
5680 goto naive;
5681 }
5682 else if (!PyDelta_Check(offset)) {
5683 Py_DECREF(offset);
5684 PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s,"
5685 " expected timedelta or None", Py_TYPE(offset)->tp_name);
5686 return NULL;
5687 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005688 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005689 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5690 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005691 Py_DECREF(offset);
5692 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005693 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005694
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005695 /* Make sure result is aware and UTC. */
5696 if (!HASTZINFO(result)) {
5697 temp = (PyObject *)result;
5698 result = (PyDateTime_DateTime *)
5699 new_datetime_ex2(GET_YEAR(result),
5700 GET_MONTH(result),
5701 GET_DAY(result),
5702 DATE_GET_HOUR(result),
5703 DATE_GET_MINUTE(result),
5704 DATE_GET_SECOND(result),
5705 DATE_GET_MICROSECOND(result),
5706 PyDateTime_TimeZone_UTC,
5707 DATE_GET_FOLD(result),
5708 Py_TYPE(result));
5709 Py_DECREF(temp);
5710 if (result == NULL)
5711 return NULL;
5712 }
5713 else {
5714 /* Result is already aware - just replace tzinfo. */
5715 temp = result->tzinfo;
5716 result->tzinfo = PyDateTime_TimeZone_UTC;
5717 Py_INCREF(result->tzinfo);
5718 Py_DECREF(temp);
5719 }
5720
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005721 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005722 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005723 if (tzinfo == Py_None) {
5724 tzinfo = local_timezone(result);
5725 if (tzinfo == NULL) {
5726 Py_DECREF(result);
5727 return NULL;
5728 }
5729 }
5730 else
5731 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005732 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005733 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005734
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005735 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005736 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005737 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005738 Py_DECREF(temp);
5739
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005740 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005741}
5742
5743static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005744datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005746 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005748 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005749 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005750
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005751 dst = call_dst(self->tzinfo, (PyObject *)self);
5752 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005753 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005754
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005755 if (dst != Py_None)
5756 dstflag = delta_bool((PyDateTime_Delta *)dst);
5757 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005758 }
5759 return build_struct_time(GET_YEAR(self),
5760 GET_MONTH(self),
5761 GET_DAY(self),
5762 DATE_GET_HOUR(self),
5763 DATE_GET_MINUTE(self),
5764 DATE_GET_SECOND(self),
5765 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005766}
5767
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005768static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005769local_to_seconds(int year, int month, int day,
5770 int hour, int minute, int second, int fold)
5771{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005772 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005773 t = utc_to_seconds(year, month, day, hour, minute, second);
5774 /* Our goal is to solve t = local(u) for u. */
5775 lt = local(t);
5776 if (lt == -1)
5777 return -1;
5778 a = lt - t;
5779 u1 = t - a;
5780 t1 = local(u1);
5781 if (t1 == -1)
5782 return -1;
5783 if (t1 == t) {
5784 /* We found one solution, but it may not be the one we need.
5785 * Look for an earlier solution (if `fold` is 0), or a
5786 * later one (if `fold` is 1). */
5787 if (fold)
5788 u2 = u1 + max_fold_seconds;
5789 else
5790 u2 = u1 - max_fold_seconds;
5791 lt = local(u2);
5792 if (lt == -1)
5793 return -1;
5794 b = lt - u2;
5795 if (a == b)
5796 return u1;
5797 }
5798 else {
5799 b = t1 - u1;
5800 assert(a != b);
5801 }
5802 u2 = t - b;
5803 t2 = local(u2);
5804 if (t2 == -1)
5805 return -1;
5806 if (t2 == t)
5807 return u2;
5808 if (t1 == t)
5809 return u1;
5810 /* We have found both offsets a and b, but neither t - a nor t - b is
5811 * a solution. This means t is in the gap. */
5812 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5813}
5814
5815/* date(1970,1,1).toordinal() == 719163 */
5816#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5817
Tim Peters2a799bf2002-12-16 20:18:38 +00005818static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005819datetime_timestamp(PyDateTime_DateTime *self)
5820{
5821 PyObject *result;
5822
5823 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5824 PyObject *delta;
5825 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5826 if (delta == NULL)
5827 return NULL;
5828 result = delta_total_seconds(delta);
5829 Py_DECREF(delta);
5830 }
5831 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005832 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005833 seconds = local_to_seconds(GET_YEAR(self),
5834 GET_MONTH(self),
5835 GET_DAY(self),
5836 DATE_GET_HOUR(self),
5837 DATE_GET_MINUTE(self),
5838 DATE_GET_SECOND(self),
5839 DATE_GET_FOLD(self));
5840 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005841 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005842 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5843 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005844 }
5845 return result;
5846}
5847
5848static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005849datetime_getdate(PyDateTime_DateTime *self)
5850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005851 return new_date(GET_YEAR(self),
5852 GET_MONTH(self),
5853 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005854}
5855
5856static PyObject *
5857datetime_gettime(PyDateTime_DateTime *self)
5858{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005859 return new_time(DATE_GET_HOUR(self),
5860 DATE_GET_MINUTE(self),
5861 DATE_GET_SECOND(self),
5862 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005863 Py_None,
5864 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005865}
5866
5867static PyObject *
5868datetime_gettimetz(PyDateTime_DateTime *self)
5869{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005870 return new_time(DATE_GET_HOUR(self),
5871 DATE_GET_MINUTE(self),
5872 DATE_GET_SECOND(self),
5873 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005874 GET_DT_TZINFO(self),
5875 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005876}
5877
5878static PyObject *
5879datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005880{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005881 int y, m, d, hh, mm, ss;
5882 PyObject *tzinfo;
5883 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005884
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005885 tzinfo = GET_DT_TZINFO(self);
5886 if (tzinfo == Py_None) {
5887 utcself = self;
5888 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005889 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005890 else {
5891 PyObject *offset;
5892 offset = call_utcoffset(tzinfo, (PyObject *)self);
5893 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005894 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005895 if (offset == Py_None) {
5896 Py_DECREF(offset);
5897 utcself = self;
5898 Py_INCREF(utcself);
5899 }
5900 else {
5901 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5902 (PyDateTime_Delta *)offset, -1);
5903 Py_DECREF(offset);
5904 if (utcself == NULL)
5905 return NULL;
5906 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005907 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005908 y = GET_YEAR(utcself);
5909 m = GET_MONTH(utcself);
5910 d = GET_DAY(utcself);
5911 hh = DATE_GET_HOUR(utcself);
5912 mm = DATE_GET_MINUTE(utcself);
5913 ss = DATE_GET_SECOND(utcself);
5914
5915 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005916 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005917}
5918
Tim Peters371935f2003-02-01 01:52:50 +00005919/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005920
Tim Petersa9bc1682003-01-11 03:39:11 +00005921/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005922 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5923 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005924 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005925 */
5926static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005927datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005928{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005929 PyObject *basestate;
5930 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005932 basestate = PyBytes_FromStringAndSize((char *)self->data,
5933 _PyDateTime_DATETIME_DATASIZE);
5934 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005935 if (proto > 3 && DATE_GET_FOLD(self))
5936 /* Set the first bit of the third byte */
5937 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005938 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5939 result = PyTuple_Pack(1, basestate);
5940 else
5941 result = PyTuple_Pack(2, basestate, self->tzinfo);
5942 Py_DECREF(basestate);
5943 }
5944 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005945}
5946
5947static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005948datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005949{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005950 int proto;
5951 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005952 return NULL;
5953
5954 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005955}
5956
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005957static PyObject *
5958datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5959{
5960 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5961}
5962
Tim Petersa9bc1682003-01-11 03:39:11 +00005963static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005965 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005966
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005967 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005969 {"utcnow", (PyCFunction)datetime_utcnow,
5970 METH_NOARGS | METH_CLASS,
5971 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005973 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5974 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5975 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005977 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5978 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005979 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005981 {"strptime", (PyCFunction)datetime_strptime,
5982 METH_VARARGS | METH_CLASS,
5983 PyDoc_STR("string, format -> new datetime parsed from a string "
5984 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005986 {"combine", (PyCFunction)datetime_combine,
5987 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5988 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005989
Paul Ganssle09dc2f52017-12-21 00:33:49 -05005990 {"fromisoformat", (PyCFunction)datetime_fromisoformat,
5991 METH_O | METH_CLASS,
5992 PyDoc_STR("string -> datetime from datetime.isoformat() output")},
5993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005994 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005996 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5997 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005999 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
6000 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006002 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
6003 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006005 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
6006 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00006007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006008 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
6009 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006010
Alexander Belopolskya4415142012-06-08 12:33:09 -04006011 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
6012 PyDoc_STR("Return POSIX timestamp as float.")},
6013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006014 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
6015 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006017 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
6018 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006019 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006020 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05006021 "defaults to 'T'.\n"
6022 "timespec specifies what components of the time to include"
6023 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
6024 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006026 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
6027 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006029 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
6030 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006032 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
6033 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00006034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006035 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
6036 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00006037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006038 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
6039 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00006040
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006041 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006042 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00006043
Serhiy Storchaka546ce652016-11-22 00:29:42 +02006044 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
6045 PyDoc_STR("__reduce__() -> (cls, state)")},
6046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006047 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006048};
6049
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02006050static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00006051PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
6052\n\
6053The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03006054instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00006055
Tim Petersa9bc1682003-01-11 03:39:11 +00006056static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006057 datetime_add, /* nb_add */
6058 datetime_subtract, /* nb_subtract */
6059 0, /* nb_multiply */
6060 0, /* nb_remainder */
6061 0, /* nb_divmod */
6062 0, /* nb_power */
6063 0, /* nb_negative */
6064 0, /* nb_positive */
6065 0, /* nb_absolute */
6066 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00006067};
6068
Neal Norwitz227b5332006-03-22 09:28:35 +00006069static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006070 PyVarObject_HEAD_INIT(NULL, 0)
6071 "datetime.datetime", /* tp_name */
6072 sizeof(PyDateTime_DateTime), /* tp_basicsize */
6073 0, /* tp_itemsize */
6074 (destructor)datetime_dealloc, /* tp_dealloc */
6075 0, /* tp_print */
6076 0, /* tp_getattr */
6077 0, /* tp_setattr */
6078 0, /* tp_reserved */
6079 (reprfunc)datetime_repr, /* tp_repr */
6080 &datetime_as_number, /* tp_as_number */
6081 0, /* tp_as_sequence */
6082 0, /* tp_as_mapping */
6083 (hashfunc)datetime_hash, /* tp_hash */
6084 0, /* tp_call */
6085 (reprfunc)datetime_str, /* tp_str */
6086 PyObject_GenericGetAttr, /* tp_getattro */
6087 0, /* tp_setattro */
6088 0, /* tp_as_buffer */
6089 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
6090 datetime_doc, /* tp_doc */
6091 0, /* tp_traverse */
6092 0, /* tp_clear */
6093 datetime_richcompare, /* tp_richcompare */
6094 0, /* tp_weaklistoffset */
6095 0, /* tp_iter */
6096 0, /* tp_iternext */
6097 datetime_methods, /* tp_methods */
6098 0, /* tp_members */
6099 datetime_getset, /* tp_getset */
6100 &PyDateTime_DateType, /* tp_base */
6101 0, /* tp_dict */
6102 0, /* tp_descr_get */
6103 0, /* tp_descr_set */
6104 0, /* tp_dictoffset */
6105 0, /* tp_init */
6106 datetime_alloc, /* tp_alloc */
6107 datetime_new, /* tp_new */
6108 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00006109};
6110
6111/* ---------------------------------------------------------------------------
6112 * Module methods and initialization.
6113 */
6114
6115static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006116 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00006117};
6118
Tim Peters9ddf40b2004-06-20 22:41:32 +00006119/* C API. Clients get at this via PyDateTime_IMPORT, defined in
6120 * datetime.h.
6121 */
6122static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006123 &PyDateTime_DateType,
6124 &PyDateTime_DateTimeType,
6125 &PyDateTime_TimeType,
6126 &PyDateTime_DeltaType,
6127 &PyDateTime_TZInfoType,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006128 NULL, // PyDatetime_TimeZone_UTC not initialized yet
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006129 new_date_ex,
6130 new_datetime_ex,
6131 new_time_ex,
6132 new_delta_ex,
Paul Ganssle04af5b12018-01-24 17:29:30 -05006133 new_timezone,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006134 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006135 date_fromtimestamp,
6136 new_datetime_ex2,
6137 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00006138};
6139
6140
Martin v. Löwis1a214512008-06-11 05:26:20 +00006141
6142static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006143 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006144 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006145 "Fast implementation of the datetime type.",
6146 -1,
6147 module_methods,
6148 NULL,
6149 NULL,
6150 NULL,
6151 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00006152};
6153
Tim Peters2a799bf2002-12-16 20:18:38 +00006154PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00006155PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00006156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006157 PyObject *m; /* a module object */
6158 PyObject *d; /* its dict */
6159 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006160 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00006161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006162 m = PyModule_Create(&datetimemodule);
6163 if (m == NULL)
6164 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006166 if (PyType_Ready(&PyDateTime_DateType) < 0)
6167 return NULL;
6168 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
6169 return NULL;
6170 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
6171 return NULL;
6172 if (PyType_Ready(&PyDateTime_TimeType) < 0)
6173 return NULL;
6174 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
6175 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006176 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
6177 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006179 /* timedelta values */
6180 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006182 x = new_delta(0, 0, 1, 0);
6183 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6184 return NULL;
6185 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006187 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
6188 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6189 return NULL;
6190 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006192 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
6193 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6194 return NULL;
6195 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006197 /* date values */
6198 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006200 x = new_date(1, 1, 1);
6201 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6202 return NULL;
6203 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006205 x = new_date(MAXYEAR, 12, 31);
6206 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6207 return NULL;
6208 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006210 x = new_delta(1, 0, 0, 0);
6211 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6212 return NULL;
6213 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006215 /* time values */
6216 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006217
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006218 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006219 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6220 return NULL;
6221 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006222
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006223 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006224 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6225 return NULL;
6226 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006228 x = new_delta(0, 0, 1, 0);
6229 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6230 return NULL;
6231 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006233 /* datetime values */
6234 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00006235
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006236 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006237 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6238 return NULL;
6239 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006240
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006241 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006242 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6243 return NULL;
6244 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006246 x = new_delta(0, 0, 1, 0);
6247 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
6248 return NULL;
6249 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00006250
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006251 /* timezone values */
6252 d = PyDateTime_TimeZoneType.tp_dict;
6253
6254 delta = new_delta(0, 0, 0, 0);
6255 if (delta == NULL)
6256 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006257 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006258 Py_DECREF(delta);
6259 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
6260 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00006261 PyDateTime_TimeZone_UTC = x;
Paul Ganssle04af5b12018-01-24 17:29:30 -05006262 CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006263
6264 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
6265 if (delta == NULL)
6266 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006267 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006268 Py_DECREF(delta);
6269 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
6270 return NULL;
6271 Py_DECREF(x);
6272
6273 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
6274 if (delta == NULL)
6275 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00006276 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006277 Py_DECREF(delta);
6278 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
6279 return NULL;
6280 Py_DECREF(x);
6281
Alexander Belopolskya4415142012-06-08 12:33:09 -04006282 /* Epoch */
6283 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04006284 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04006285 if (PyDateTime_Epoch == NULL)
6286 return NULL;
6287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006288 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02006289 PyModule_AddIntMacro(m, MINYEAR);
6290 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00006291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006292 Py_INCREF(&PyDateTime_DateType);
6293 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006295 Py_INCREF(&PyDateTime_DateTimeType);
6296 PyModule_AddObject(m, "datetime",
6297 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006299 Py_INCREF(&PyDateTime_TimeType);
6300 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00006301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006302 Py_INCREF(&PyDateTime_DeltaType);
6303 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006305 Py_INCREF(&PyDateTime_TZInfoType);
6306 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00006307
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00006308 Py_INCREF(&PyDateTime_TimeZoneType);
6309 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
6310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006311 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
6312 if (x == NULL)
6313 return NULL;
6314 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00006315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006316 /* A 4-year cycle has an extra leap day over what we'd get from
6317 * pasting together 4 single years.
6318 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006319 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006320 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006322 /* Similarly, a 400-year cycle has an extra leap day over what we'd
6323 * get from pasting together 4 100-year cycles.
6324 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006325 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006326 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006328 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
6329 * pasting together 25 4-year cycles.
6330 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02006331 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006332 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00006333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006334 us_per_ms = PyLong_FromLong(1000);
6335 us_per_second = PyLong_FromLong(1000000);
6336 us_per_minute = PyLong_FromLong(60000000);
6337 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03006338 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006339 us_per_minute == NULL || seconds_per_day == NULL)
6340 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00006341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006342 /* The rest are too big for 32-bit ints, but even
6343 * us_per_week fits in 40 bits, so doubles should be exact.
6344 */
6345 us_per_hour = PyLong_FromDouble(3600000000.0);
6346 us_per_day = PyLong_FromDouble(86400000000.0);
6347 us_per_week = PyLong_FromDouble(604800000000.0);
6348 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
6349 return NULL;
6350 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00006351}
Tim Petersf3615152003-01-01 21:51:37 +00006352
6353/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00006354Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00006355 x.n = x stripped of its timezone -- its naive time.
6356 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006357 return None
Tim Petersf3615152003-01-01 21:51:37 +00006358 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006359 return None
Tim Petersf3615152003-01-01 21:51:37 +00006360 x.s = x's standard offset, x.o - x.d
6361
6362Now some derived rules, where k is a duration (timedelta).
6363
63641. x.o = x.s + x.d
6365 This follows from the definition of x.s.
6366
Tim Petersc5dc4da2003-01-02 17:55:03 +000063672. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00006368 This is actually a requirement, an assumption we need to make about
6369 sane tzinfo classes.
6370
63713. The naive UTC time corresponding to x is x.n - x.o.
6372 This is again a requirement for a sane tzinfo class.
6373
63744. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00006375 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00006376
Tim Petersc5dc4da2003-01-02 17:55:03 +000063775. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00006378 Again follows from how arithmetic is defined.
6379
Tim Peters8bb5ad22003-01-24 02:44:45 +00006380Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00006381(meaning that the various tzinfo methods exist, and don't blow up or return
6382None when called).
6383
Tim Petersa9bc1682003-01-11 03:39:11 +00006384The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00006385x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00006386
6387By #3, we want
6388
Tim Peters8bb5ad22003-01-24 02:44:45 +00006389 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00006390
6391The algorithm starts by attaching tz to x.n, and calling that y. So
6392x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
6393becomes true; in effect, we want to solve [2] for k:
6394
Tim Peters8bb5ad22003-01-24 02:44:45 +00006395 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00006396
6397By #1, this is the same as
6398
Tim Peters8bb5ad22003-01-24 02:44:45 +00006399 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00006400
6401By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
6402Substituting that into [3],
6403
Tim Peters8bb5ad22003-01-24 02:44:45 +00006404 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
6405 k - (y+k).s - (y+k).d = 0; rearranging,
6406 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
6407 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00006408
Tim Peters8bb5ad22003-01-24 02:44:45 +00006409On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
6410approximate k by ignoring the (y+k).d term at first. Note that k can't be
6411very large, since all offset-returning methods return a duration of magnitude
6412less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
6413be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00006414
6415In any case, the new value is
6416
Tim Peters8bb5ad22003-01-24 02:44:45 +00006417 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00006418
Tim Peters8bb5ad22003-01-24 02:44:45 +00006419It's helpful to step back at look at [4] from a higher level: it's simply
6420mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00006421
6422At this point, if
6423
Tim Peters8bb5ad22003-01-24 02:44:45 +00006424 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00006425
6426we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00006427at the start of daylight time. Picture US Eastern for concreteness. The wall
6428time 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 +00006429sense then. The docs ask that an Eastern tzinfo class consider such a time to
6430be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
6431on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00006432the only spelling that makes sense on the local wall clock.
6433
Tim Petersc5dc4da2003-01-02 17:55:03 +00006434In fact, if [5] holds at this point, we do have the standard-time spelling,
6435but that takes a bit of proof. We first prove a stronger result. What's the
6436difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006437
Tim Peters8bb5ad22003-01-24 02:44:45 +00006438 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006439
Tim Petersc5dc4da2003-01-02 17:55:03 +00006440Now
6441 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006442 (y + y.s).n = by #5
6443 y.n + y.s = since y.n = x.n
6444 x.n + y.s = since z and y are have the same tzinfo member,
6445 y.s = z.s by #2
6446 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006447
Tim Petersc5dc4da2003-01-02 17:55:03 +00006448Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006449
Tim Petersc5dc4da2003-01-02 17:55:03 +00006450 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006451 x.n - ((x.n + z.s) - z.o) = expanding
6452 x.n - x.n - z.s + z.o = cancelling
6453 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006454 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006455
Tim Petersc5dc4da2003-01-02 17:55:03 +00006456So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006457
Tim Petersc5dc4da2003-01-02 17:55:03 +00006458If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006459spelling we wanted in the endcase described above. We're done. Contrarily,
6460if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006461
Tim Petersc5dc4da2003-01-02 17:55:03 +00006462If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6463add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006464local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006465
Tim Petersc5dc4da2003-01-02 17:55:03 +00006466Let
Tim Petersf3615152003-01-01 21:51:37 +00006467
Tim Peters4fede1a2003-01-04 00:26:59 +00006468 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006469
Tim Peters4fede1a2003-01-04 00:26:59 +00006470and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006471
Tim Peters8bb5ad22003-01-24 02:44:45 +00006472 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006473
Tim Peters8bb5ad22003-01-24 02:44:45 +00006474If so, we're done. If not, the tzinfo class is insane, according to the
6475assumptions we've made. This also requires a bit of proof. As before, let's
6476compute the difference between the LHS and RHS of [8] (and skipping some of
6477the justifications for the kinds of substitutions we've done several times
6478already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006479
Tim Peters8bb5ad22003-01-24 02:44:45 +00006480 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006481 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6482 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6483 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6484 - z.n + z.n - z.o + z'.o = cancel z.n
6485 - z.o + z'.o = #1 twice
6486 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6487 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006488
6489So 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 +00006490we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6491return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006492
Tim Peters8bb5ad22003-01-24 02:44:45 +00006493How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6494a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6495would have to change the result dst() returns: we start in DST, and moving
6496a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006497
Tim Peters8bb5ad22003-01-24 02:44:45 +00006498There isn't a sane case where this can happen. The closest it gets is at
6499the end of DST, where there's an hour in UTC with no spelling in a hybrid
6500tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6501that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6502UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6503time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6504clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6505standard time. Since that's what the local clock *does*, we want to map both
6506UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006507in local time, but so it goes -- it's the way the local clock works.
6508
Tim Peters8bb5ad22003-01-24 02:44:45 +00006509When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6510so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6511z' = 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 +00006512(correctly) concludes that z' is not UTC-equivalent to x.
6513
6514Because we know z.d said z was in daylight time (else [5] would have held and
6515we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006516and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006517return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6518but the reasoning doesn't depend on the example -- it depends on there being
6519two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006520z' must be in standard time, and is the spelling we want in this case.
6521
6522Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6523concerned (because it takes z' as being in standard time rather than the
6524daylight time we intend here), but returning it gives the real-life "local
6525clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6526tz.
6527
6528When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6529the 1:MM standard time spelling we want.
6530
6531So how can this break? One of the assumptions must be violated. Two
6532possibilities:
6533
65341) [2] effectively says that y.s is invariant across all y belong to a given
6535 time zone. This isn't true if, for political reasons or continental drift,
6536 a region decides to change its base offset from UTC.
6537
65382) There may be versions of "double daylight" time where the tail end of
6539 the analysis gives up a step too early. I haven't thought about that
6540 enough to say.
6541
6542In any case, it's clear that the default fromutc() is strong enough to handle
6543"almost all" time zones: so long as the standard offset is invariant, it
6544doesn't matter if daylight time transition points change from year to year, or
6545if daylight time is skipped in some years; it doesn't matter how large or
6546small dst() may get within its bounds; and it doesn't even matter if some
6547perverse time zone returns a negative dst()). So a breaking case must be
6548pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006549--------------------------------------------------------------------------- */