blob: 619ac84bf747dfe8bb0b6909d6bcbb18e92ae30d [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/* ---------------------------------------------------------------------------
667 * Create various objects, mostly without range checking.
668 */
669
670/* Create a date instance with no range checking. */
671static PyObject *
672new_date_ex(int year, int month, int day, PyTypeObject *type)
673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000675
Victor Stinnerb67f0962017-02-10 10:34:02 +0100676 if (check_date_args(year, month, day) < 0) {
677 return NULL;
678 }
679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
681 if (self != NULL)
682 set_date_fields(self, year, month, day);
683 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000684}
685
686#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000688
689/* Create a datetime instance with no range checking. */
690static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400691new_datetime_ex2(int year, int month, int day, int hour, int minute,
692 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000693{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 PyDateTime_DateTime *self;
695 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000696
Victor Stinnerb67f0962017-02-10 10:34:02 +0100697 if (check_date_args(year, month, day) < 0) {
698 return NULL;
699 }
700 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
701 return NULL;
702 }
703 if (check_tzinfo_subclass(tzinfo) < 0) {
704 return NULL;
705 }
706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
708 if (self != NULL) {
709 self->hastzinfo = aware;
710 set_date_fields((PyDateTime_Date *)self, year, month, day);
711 DATE_SET_HOUR(self, hour);
712 DATE_SET_MINUTE(self, minute);
713 DATE_SET_SECOND(self, second);
714 DATE_SET_MICROSECOND(self, usecond);
715 if (aware) {
716 Py_INCREF(tzinfo);
717 self->tzinfo = tzinfo;
718 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400719 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 }
721 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000722}
723
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400724static PyObject *
725new_datetime_ex(int year, int month, int day, int hour, int minute,
726 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
727{
728 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
729 tzinfo, 0, type);
730}
731
732#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
733 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000735
736/* Create a time instance with no range checking. */
737static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400738new_time_ex2(int hour, int minute, int second, int usecond,
739 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 PyDateTime_Time *self;
742 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000743
Victor Stinnerb67f0962017-02-10 10:34:02 +0100744 if (check_time_args(hour, minute, second, usecond, fold) < 0) {
745 return NULL;
746 }
747 if (check_tzinfo_subclass(tzinfo) < 0) {
748 return NULL;
749 }
750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
752 if (self != NULL) {
753 self->hastzinfo = aware;
754 self->hashcode = -1;
755 TIME_SET_HOUR(self, hour);
756 TIME_SET_MINUTE(self, minute);
757 TIME_SET_SECOND(self, second);
758 TIME_SET_MICROSECOND(self, usecond);
759 if (aware) {
760 Py_INCREF(tzinfo);
761 self->tzinfo = tzinfo;
762 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400763 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 }
765 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000766}
767
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400768static PyObject *
769new_time_ex(int hour, int minute, int second, int usecond,
770 PyObject *tzinfo, PyTypeObject *type)
771{
772 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
773}
774
775#define new_time(hh, mm, ss, us, tzinfo, fold) \
776 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000777
778/* Create a timedelta instance. Normalize the members iff normalize is
779 * true. Passing false is a speed optimization, if you know for sure
780 * that seconds and microseconds are already in their proper ranges. In any
781 * case, raises OverflowError and returns NULL if the normalized days is out
782 * of range).
783 */
784static PyObject *
785new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000790 if (normalize)
791 normalize_d_s_us(&days, &seconds, &microseconds);
792 assert(0 <= seconds && seconds < 24*3600);
793 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000795 if (check_delta_day_range(days) < 0)
796 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
799 if (self != NULL) {
800 self->hashcode = -1;
801 SET_TD_DAYS(self, days);
802 SET_TD_SECONDS(self, seconds);
803 SET_TD_MICROSECONDS(self, microseconds);
804 }
805 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000806}
807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808#define new_delta(d, s, us, normalize) \
809 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000810
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000811
812typedef struct
813{
814 PyObject_HEAD
815 PyObject *offset;
816 PyObject *name;
817} PyDateTime_TimeZone;
818
Victor Stinner6ced7c42011-03-21 18:15:42 +0100819/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000820static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -0400821/* The interned Epoch datetime instance */
822static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000823
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000824/* Create new timezone instance checking offset range. This
825 function does not check the name argument. Caller must assure
826 that offset is a timedelta instance and name is either NULL
827 or a unicode object. */
828static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000829create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000830{
831 PyDateTime_TimeZone *self;
832 PyTypeObject *type = &PyDateTime_TimeZoneType;
833
834 assert(offset != NULL);
835 assert(PyDelta_Check(offset));
836 assert(name == NULL || PyUnicode_Check(name));
837
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000838 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
839 if (self == NULL) {
840 return NULL;
841 }
842 Py_INCREF(offset);
843 self->offset = offset;
844 Py_XINCREF(name);
845 self->name = name;
846 return (PyObject *)self;
847}
848
849static int delta_bool(PyDateTime_Delta *self);
850
851static PyObject *
852new_timezone(PyObject *offset, PyObject *name)
853{
854 assert(offset != NULL);
855 assert(PyDelta_Check(offset));
856 assert(name == NULL || PyUnicode_Check(name));
857
858 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
859 Py_INCREF(PyDateTime_TimeZone_UTC);
860 return PyDateTime_TimeZone_UTC;
861 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000862 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
863 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
864 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
865 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400866 " timedelta(hours=24),"
867 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000868 return NULL;
869 }
870
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000871 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000872}
873
Tim Petersb0c854d2003-05-17 15:57:00 +0000874/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000875 * tzinfo helpers.
876 */
877
Tim Peters855fe882002-12-22 03:43:39 +0000878/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
879 * raise TypeError and return -1.
880 */
881static int
882check_tzinfo_subclass(PyObject *p)
883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 if (p == Py_None || PyTZInfo_Check(p))
885 return 0;
886 PyErr_Format(PyExc_TypeError,
887 "tzinfo argument must be None or of a tzinfo subclass, "
888 "not type '%s'",
889 Py_TYPE(p)->tp_name);
890 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000891}
892
Tim Peters2a799bf2002-12-16 20:18:38 +0000893/* If self has a tzinfo member, return a BORROWED reference to it. Else
894 * return NULL, which is NOT AN ERROR. There are no error returns here,
895 * and the caller must not decref the result.
896 */
897static PyObject *
898get_tzinfo_member(PyObject *self)
899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 if (PyDateTime_Check(self) && HASTZINFO(self))
903 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
904 else if (PyTime_Check(self) && HASTZINFO(self))
905 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000908}
909
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000910/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
911 * be an instance of the tzinfo class. If the method returns None, this
912 * returns None. If the method doesn't return None or timedelta, TypeError is
913 * raised and this returns NULL. If it returns a timedelta and the value is
914 * out of range or isn't a whole number of minutes, ValueError is raised and
915 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000916 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000917static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200918call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000919{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000920 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000923 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000925
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000926 if (tzinfo == Py_None)
927 Py_RETURN_NONE;
928 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
929 if (offset == Py_None || offset == NULL)
930 return offset;
931 if (PyDelta_Check(offset)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000932 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
933 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
934 Py_DECREF(offset);
935 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
936 " strictly between -timedelta(hours=24) and"
937 " timedelta(hours=24).");
938 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 }
940 }
941 else {
942 PyErr_Format(PyExc_TypeError,
943 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000944 "timedelta, not '%.200s'",
945 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -0700946 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000947 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000949
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000950 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000951}
952
953/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
954 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
955 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000956 * doesn't return None or timedelta, TypeError is raised and this returns -1.
Alexander Belopolsky018d3532017-07-31 10:26:50 -0400957 * If utcoffset() returns an out of range timedelta,
958 * ValueError is raised and this returns -1. Else *none is
959 * set to 0 and the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000960 */
Tim Peters855fe882002-12-22 03:43:39 +0000961static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000962call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
963{
964 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000965}
966
Tim Peters2a799bf2002-12-16 20:18:38 +0000967/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
968 * result. tzinfo must be an instance of the tzinfo class. If dst()
969 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Alexander Belopolsky018d3532017-07-31 10:26:50 -0400970 * doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000971 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000972 * ValueError is raised and this returns -1. Else *none is set to 0 and
Alexander Belopolsky018d3532017-07-31 10:26:50 -0400973 * the offset is returned (as timedelta, positive east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000974 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000975static PyObject *
976call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000977{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000978 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000979}
980
Tim Petersbad8ff02002-12-30 20:52:32 +0000981/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000982 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000983 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000984 * returns NULL. If the result is a string, we ensure it is a Unicode
985 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000986 */
987static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000988call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200991 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 assert(tzinfo != NULL);
994 assert(check_tzinfo_subclass(tzinfo) >= 0);
995 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000998 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000999
Victor Stinner20401de2016-12-09 15:24:31 +01001000 result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname,
1001 tzinfoarg, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001002
1003 if (result == NULL || result == Py_None)
1004 return result;
1005
1006 if (!PyUnicode_Check(result)) {
1007 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1008 "return None or a string, not '%s'",
1009 Py_TYPE(result)->tp_name);
1010 Py_DECREF(result);
1011 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001013
1014 return result;
Tim Peters00237032002-12-27 02:21:51 +00001015}
1016
Tim Peters2a799bf2002-12-16 20:18:38 +00001017/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1018 * stuff
1019 * ", tzinfo=" + repr(tzinfo)
1020 * before the closing ")".
1021 */
1022static PyObject *
1023append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 assert(PyUnicode_Check(repr));
1028 assert(tzinfo);
1029 if (tzinfo == Py_None)
1030 return repr;
1031 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001032 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1033 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 Py_DECREF(repr);
1035 if (temp == NULL)
1036 return NULL;
1037 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1038 Py_DECREF(temp);
1039 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001040}
1041
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001042/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1043 * stuff
1044 * ", fold=" + repr(tzinfo)
1045 * before the closing ")".
1046 */
1047static PyObject *
1048append_keyword_fold(PyObject *repr, int fold)
1049{
1050 PyObject *temp;
1051
1052 assert(PyUnicode_Check(repr));
1053 if (fold == 0)
1054 return repr;
1055 /* Get rid of the trailing ')'. */
1056 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1057 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1058 Py_DECREF(repr);
1059 if (temp == NULL)
1060 return NULL;
1061 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1062 Py_DECREF(temp);
1063 return repr;
1064}
1065
Tim Peters2a799bf2002-12-16 20:18:38 +00001066/* ---------------------------------------------------------------------------
1067 * String format helpers.
1068 */
1069
1070static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001071format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001072{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001073 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1075 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001076 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1078 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1079 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1084 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1085 GET_DAY(date), hours, minutes, seconds,
1086 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001087}
1088
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001089static PyObject *delta_negative(PyDateTime_Delta *self);
1090
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001091/* Add formatted UTC offset string to buf. buf has no more than
Tim Peters2a799bf2002-12-16 20:18:38 +00001092 * buflen bytes remaining. The UTC offset is gotten by calling
1093 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1094 * *buf, and that's all. Else the returned value is checked for sanity (an
1095 * integer in range), and if that's OK it's converted to an hours & minutes
1096 * string of the form
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001097 * sign HH sep MM [sep SS [. UUUUUU]]
Tim Peters2a799bf2002-12-16 20:18:38 +00001098 * Returns 0 if everything is OK. If the return value from utcoffset() is
1099 * bogus, an appropriate exception is set and -1 is returned.
1100 */
1101static int
Tim Peters328fff72002-12-20 01:31:27 +00001102format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001104{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001105 PyObject *offset;
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001106 int hours, minutes, seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001110
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001111 offset = call_utcoffset(tzinfo, tzinfoarg);
1112 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001114 if (offset == Py_None) {
1115 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 *buf = '\0';
1117 return 0;
1118 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001119 /* Offset is normalized, so it is negative if days < 0 */
1120 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001122 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001123 if (offset == NULL)
1124 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001126 else {
1127 sign = '+';
1128 }
1129 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001130 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001131 seconds = GET_TD_SECONDS(offset);
1132 Py_DECREF(offset);
1133 minutes = divmod(seconds, 60, &seconds);
1134 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001135 if (microseconds) {
1136 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign,
1137 hours, sep, minutes, sep, seconds, microseconds);
1138 return 0;
1139 }
1140 if (seconds) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001141 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1142 sep, minutes, sep, seconds);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04001143 return 0;
1144 }
1145 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001147}
1148
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001149static PyObject *
1150make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 PyObject *temp;
1153 PyObject *tzinfo = get_tzinfo_member(object);
1154 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001155 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 if (Zreplacement == NULL)
1158 return NULL;
1159 if (tzinfo == Py_None || tzinfo == NULL)
1160 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 assert(tzinfoarg != NULL);
1163 temp = call_tzname(tzinfo, tzinfoarg);
1164 if (temp == NULL)
1165 goto Error;
1166 if (temp == Py_None) {
1167 Py_DECREF(temp);
1168 return Zreplacement;
1169 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 assert(PyUnicode_Check(temp));
1172 /* Since the tzname is getting stuffed into the
1173 * format, we have to double any % signs so that
1174 * strftime doesn't treat them as format codes.
1175 */
1176 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001177 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 Py_DECREF(temp);
1179 if (Zreplacement == NULL)
1180 return NULL;
1181 if (!PyUnicode_Check(Zreplacement)) {
1182 PyErr_SetString(PyExc_TypeError,
1183 "tzname.replace() did not return a string");
1184 goto Error;
1185 }
1186 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001187
1188 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 Py_DECREF(Zreplacement);
1190 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001191}
1192
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001193static PyObject *
1194make_freplacement(PyObject *object)
1195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 char freplacement[64];
1197 if (PyTime_Check(object))
1198 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1199 else if (PyDateTime_Check(object))
1200 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1201 else
1202 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001205}
1206
Tim Peters2a799bf2002-12-16 20:18:38 +00001207/* I sure don't want to reproduce the strftime code from the time module,
1208 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001209 * giving special meanings to the %z, %Z and %f format codes via a
1210 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001211 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1212 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001213 */
1214static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001215wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1221 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1222 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 const char *pin; /* pointer to next char in input format */
1225 Py_ssize_t flen; /* length of input format */
1226 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 PyObject *newfmt = NULL; /* py string, the output format */
1229 char *pnew; /* pointer to available byte in output format */
1230 size_t totalnew; /* number bytes total in output format buffer,
1231 exclusive of trailing \0 */
1232 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 const char *ptoappend; /* ptr to string to append to output buffer */
1235 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 assert(object && format && timetuple);
1238 assert(PyUnicode_Check(format));
1239 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001240 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 if (!pin)
1242 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 /* Scan the input format, looking for %z/%Z/%f escapes, building
1245 * a new format. Since computing the replacements for those codes
1246 * is expensive, don't unless they're actually used.
1247 */
1248 if (flen > INT_MAX - 1) {
1249 PyErr_NoMemory();
1250 goto Done;
1251 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 totalnew = flen + 1; /* realistic if no %z/%Z */
1254 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1255 if (newfmt == NULL) goto Done;
1256 pnew = PyBytes_AsString(newfmt);
1257 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 while ((ch = *pin++) != '\0') {
1260 if (ch != '%') {
1261 ptoappend = pin - 1;
1262 ntoappend = 1;
1263 }
1264 else if ((ch = *pin++) == '\0') {
1265 /* There's a lone trailing %; doesn't make sense. */
1266 PyErr_SetString(PyExc_ValueError, "strftime format "
1267 "ends with raw %");
1268 goto Done;
1269 }
1270 /* A % has been seen and ch is the character after it. */
1271 else if (ch == 'z') {
1272 if (zreplacement == NULL) {
1273 /* format utcoffset */
1274 char buf[100];
1275 PyObject *tzinfo = get_tzinfo_member(object);
1276 zreplacement = PyBytes_FromStringAndSize("", 0);
1277 if (zreplacement == NULL) goto Done;
1278 if (tzinfo != Py_None && tzinfo != NULL) {
1279 assert(tzinfoarg != NULL);
1280 if (format_utcoffset(buf,
1281 sizeof(buf),
1282 "",
1283 tzinfo,
1284 tzinfoarg) < 0)
1285 goto Done;
1286 Py_DECREF(zreplacement);
1287 zreplacement =
1288 PyBytes_FromStringAndSize(buf,
1289 strlen(buf));
1290 if (zreplacement == NULL)
1291 goto Done;
1292 }
1293 }
1294 assert(zreplacement != NULL);
1295 ptoappend = PyBytes_AS_STRING(zreplacement);
1296 ntoappend = PyBytes_GET_SIZE(zreplacement);
1297 }
1298 else if (ch == 'Z') {
1299 /* format tzname */
1300 if (Zreplacement == NULL) {
1301 Zreplacement = make_Zreplacement(object,
1302 tzinfoarg);
1303 if (Zreplacement == NULL)
1304 goto Done;
1305 }
1306 assert(Zreplacement != NULL);
1307 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001308 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001310 if (ptoappend == NULL)
1311 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 }
1313 else if (ch == 'f') {
1314 /* format microseconds */
1315 if (freplacement == NULL) {
1316 freplacement = make_freplacement(object);
1317 if (freplacement == NULL)
1318 goto Done;
1319 }
1320 assert(freplacement != NULL);
1321 assert(PyBytes_Check(freplacement));
1322 ptoappend = PyBytes_AS_STRING(freplacement);
1323 ntoappend = PyBytes_GET_SIZE(freplacement);
1324 }
1325 else {
1326 /* percent followed by neither z nor Z */
1327 ptoappend = pin - 2;
1328 ntoappend = 2;
1329 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 /* Append the ntoappend chars starting at ptoappend to
1332 * the new format.
1333 */
1334 if (ntoappend == 0)
1335 continue;
1336 assert(ptoappend != NULL);
1337 assert(ntoappend > 0);
1338 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001339 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 PyErr_NoMemory();
1341 goto Done;
1342 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001343 totalnew <<= 1;
1344 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 pnew = PyBytes_AsString(newfmt) + usednew;
1347 }
1348 memcpy(pnew, ptoappend, ntoappend);
1349 pnew += ntoappend;
1350 usednew += ntoappend;
1351 assert(usednew <= totalnew);
1352 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1355 goto Done;
1356 {
1357 PyObject *format;
1358 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 if (time == NULL)
1361 goto Done;
1362 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1363 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001364 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1365 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 Py_DECREF(format);
1367 }
1368 Py_DECREF(time);
1369 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001370 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 Py_XDECREF(freplacement);
1372 Py_XDECREF(zreplacement);
1373 Py_XDECREF(Zreplacement);
1374 Py_XDECREF(newfmt);
1375 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001376}
1377
Tim Peters2a799bf2002-12-16 20:18:38 +00001378/* ---------------------------------------------------------------------------
1379 * Wrap functions from the time module. These aren't directly available
1380 * from C. Perhaps they should be.
1381 */
1382
1383/* Call time.time() and return its result (a Python float). */
1384static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001385time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 PyObject *result = NULL;
1388 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001391 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001392
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001393 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 Py_DECREF(time);
1395 }
1396 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001397}
1398
1399/* Build a time.struct_time. The weekday and day number are automatically
1400 * computed from the y,m,d args.
1401 */
1402static PyObject *
1403build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001406 PyObject *result;
1407 _Py_IDENTIFIER(struct_time);
1408 PyObject *args;
1409
Tim Peters2a799bf2002-12-16 20:18:38 +00001410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001412 if (time == NULL) {
1413 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 }
Victor Stinner2b635972016-12-09 00:38:16 +01001415
1416 args = Py_BuildValue("iiiiiiiii",
1417 y, m, d,
1418 hh, mm, ss,
1419 weekday(y, m, d),
1420 days_before_month(y, m) + d,
1421 dstflag);
1422 if (args == NULL) {
1423 Py_DECREF(time);
1424 return NULL;
1425 }
1426
1427 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1428 args, NULL);
1429 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001430 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001432}
1433
1434/* ---------------------------------------------------------------------------
1435 * Miscellaneous helpers.
1436 */
1437
Mark Dickinsone94c6792009-02-02 20:36:42 +00001438/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001439 * The comparisons here all most naturally compute a cmp()-like result.
1440 * This little helper turns that into a bool result for rich comparisons.
1441 */
1442static PyObject *
1443diff_to_bool(int diff, int op)
1444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 PyObject *result;
1446 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 switch (op) {
1449 case Py_EQ: istrue = diff == 0; break;
1450 case Py_NE: istrue = diff != 0; break;
1451 case Py_LE: istrue = diff <= 0; break;
1452 case Py_GE: istrue = diff >= 0; break;
1453 case Py_LT: istrue = diff < 0; break;
1454 case Py_GT: istrue = diff > 0; break;
1455 default:
Barry Warsawb2e57942017-09-14 18:13:16 -07001456 Py_UNREACHABLE();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 }
1458 result = istrue ? Py_True : Py_False;
1459 Py_INCREF(result);
1460 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001461}
1462
Tim Peters07534a62003-02-07 22:50:28 +00001463/* Raises a "can't compare" TypeError and returns NULL. */
1464static PyObject *
1465cmperror(PyObject *a, PyObject *b)
1466{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 PyErr_Format(PyExc_TypeError,
1468 "can't compare %s to %s",
1469 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1470 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001471}
1472
Tim Peters2a799bf2002-12-16 20:18:38 +00001473/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001474 * Cached Python objects; these are set by the module init function.
1475 */
1476
1477/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478static PyObject *us_per_ms = NULL; /* 1000 */
1479static PyObject *us_per_second = NULL; /* 1000000 */
1480static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001481static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1482static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1483static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001484static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1485
Tim Peters2a799bf2002-12-16 20:18:38 +00001486/* ---------------------------------------------------------------------------
1487 * Class implementations.
1488 */
1489
1490/*
1491 * PyDateTime_Delta implementation.
1492 */
1493
1494/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001496 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001497 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1498 * due to ubiquitous overflow possibilities.
1499 */
1500static PyObject *
1501delta_to_microseconds(PyDateTime_Delta *self)
1502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 PyObject *x1 = NULL;
1504 PyObject *x2 = NULL;
1505 PyObject *x3 = NULL;
1506 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1509 if (x1 == NULL)
1510 goto Done;
1511 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1512 if (x2 == NULL)
1513 goto Done;
1514 Py_DECREF(x1);
1515 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 /* x2 has days in seconds */
1518 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1519 if (x1 == NULL)
1520 goto Done;
1521 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1522 if (x3 == NULL)
1523 goto Done;
1524 Py_DECREF(x1);
1525 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001526 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 /* x3 has days+seconds in seconds */
1529 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1530 if (x1 == NULL)
1531 goto Done;
1532 Py_DECREF(x3);
1533 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 /* x1 has days+seconds in us */
1536 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1537 if (x2 == NULL)
1538 goto Done;
1539 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001540
1541Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 Py_XDECREF(x1);
1543 Py_XDECREF(x2);
1544 Py_XDECREF(x3);
1545 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001546}
1547
Serhiy Storchaka95949422013-08-27 19:40:23 +03001548/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001549 */
1550static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001551microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001552{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 int us;
1554 int s;
1555 int d;
1556 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 PyObject *tuple = NULL;
1559 PyObject *num = NULL;
1560 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 tuple = PyNumber_Divmod(pyus, us_per_second);
1563 if (tuple == NULL)
1564 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 num = PyTuple_GetItem(tuple, 1); /* us */
1567 if (num == NULL)
1568 goto Done;
1569 temp = PyLong_AsLong(num);
1570 num = NULL;
1571 if (temp == -1 && PyErr_Occurred())
1572 goto Done;
1573 assert(0 <= temp && temp < 1000000);
1574 us = (int)temp;
1575 if (us < 0) {
1576 /* The divisor was positive, so this must be an error. */
1577 assert(PyErr_Occurred());
1578 goto Done;
1579 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1582 if (num == NULL)
1583 goto Done;
1584 Py_INCREF(num);
1585 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 tuple = PyNumber_Divmod(num, seconds_per_day);
1588 if (tuple == NULL)
1589 goto Done;
1590 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 num = PyTuple_GetItem(tuple, 1); /* seconds */
1593 if (num == NULL)
1594 goto Done;
1595 temp = PyLong_AsLong(num);
1596 num = NULL;
1597 if (temp == -1 && PyErr_Occurred())
1598 goto Done;
1599 assert(0 <= temp && temp < 24*3600);
1600 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 if (s < 0) {
1603 /* The divisor was positive, so this must be an error. */
1604 assert(PyErr_Occurred());
1605 goto Done;
1606 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1609 if (num == NULL)
1610 goto Done;
1611 Py_INCREF(num);
1612 temp = PyLong_AsLong(num);
1613 if (temp == -1 && PyErr_Occurred())
1614 goto Done;
1615 d = (int)temp;
1616 if ((long)d != temp) {
1617 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1618 "large to fit in a C int");
1619 goto Done;
1620 }
1621 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001622
1623Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 Py_XDECREF(tuple);
1625 Py_XDECREF(num);
1626 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001627}
1628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629#define microseconds_to_delta(pymicros) \
1630 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001631
Tim Peters2a799bf2002-12-16 20:18:38 +00001632static PyObject *
1633multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1634{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 PyObject *pyus_in;
1636 PyObject *pyus_out;
1637 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 pyus_in = delta_to_microseconds(delta);
1640 if (pyus_in == NULL)
1641 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1644 Py_DECREF(pyus_in);
1645 if (pyus_out == NULL)
1646 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 result = microseconds_to_delta(pyus_out);
1649 Py_DECREF(pyus_out);
1650 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001651}
1652
1653static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001654multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1655{
1656 PyObject *result = NULL;
1657 PyObject *pyus_in = NULL, *temp, *pyus_out;
1658 PyObject *ratio = NULL;
1659
1660 pyus_in = delta_to_microseconds(delta);
1661 if (pyus_in == NULL)
1662 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001663 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001664 if (ratio == NULL)
1665 goto error;
1666 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1667 Py_DECREF(pyus_in);
1668 pyus_in = NULL;
1669 if (temp == NULL)
1670 goto error;
1671 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1672 Py_DECREF(temp);
1673 if (pyus_out == NULL)
1674 goto error;
1675 result = microseconds_to_delta(pyus_out);
1676 Py_DECREF(pyus_out);
1677 error:
1678 Py_XDECREF(pyus_in);
1679 Py_XDECREF(ratio);
1680
1681 return result;
1682}
1683
1684static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001685divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 PyObject *pyus_in;
1688 PyObject *pyus_out;
1689 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 pyus_in = delta_to_microseconds(delta);
1692 if (pyus_in == NULL)
1693 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001695 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1696 Py_DECREF(pyus_in);
1697 if (pyus_out == NULL)
1698 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700 result = microseconds_to_delta(pyus_out);
1701 Py_DECREF(pyus_out);
1702 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001703}
1704
1705static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001706divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 PyObject *pyus_left;
1709 PyObject *pyus_right;
1710 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 pyus_left = delta_to_microseconds(left);
1713 if (pyus_left == NULL)
1714 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001715
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 pyus_right = delta_to_microseconds(right);
1717 if (pyus_right == NULL) {
1718 Py_DECREF(pyus_left);
1719 return NULL;
1720 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001721
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001722 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1723 Py_DECREF(pyus_left);
1724 Py_DECREF(pyus_right);
1725 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001726}
1727
1728static PyObject *
1729truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 PyObject *pyus_left;
1732 PyObject *pyus_right;
1733 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 pyus_left = delta_to_microseconds(left);
1736 if (pyus_left == NULL)
1737 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 pyus_right = delta_to_microseconds(right);
1740 if (pyus_right == NULL) {
1741 Py_DECREF(pyus_left);
1742 return NULL;
1743 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1746 Py_DECREF(pyus_left);
1747 Py_DECREF(pyus_right);
1748 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001749}
1750
1751static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001752truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1753{
1754 PyObject *result = NULL;
1755 PyObject *pyus_in = NULL, *temp, *pyus_out;
1756 PyObject *ratio = NULL;
1757
1758 pyus_in = delta_to_microseconds(delta);
1759 if (pyus_in == NULL)
1760 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001761 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001762 if (ratio == NULL)
1763 goto error;
1764 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1765 Py_DECREF(pyus_in);
1766 pyus_in = NULL;
1767 if (temp == NULL)
1768 goto error;
1769 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1770 Py_DECREF(temp);
1771 if (pyus_out == NULL)
1772 goto error;
1773 result = microseconds_to_delta(pyus_out);
1774 Py_DECREF(pyus_out);
1775 error:
1776 Py_XDECREF(pyus_in);
1777 Py_XDECREF(ratio);
1778
1779 return result;
1780}
1781
1782static PyObject *
1783truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1784{
1785 PyObject *result;
1786 PyObject *pyus_in, *pyus_out;
1787 pyus_in = delta_to_microseconds(delta);
1788 if (pyus_in == NULL)
1789 return NULL;
1790 pyus_out = divide_nearest(pyus_in, i);
1791 Py_DECREF(pyus_in);
1792 if (pyus_out == NULL)
1793 return NULL;
1794 result = microseconds_to_delta(pyus_out);
1795 Py_DECREF(pyus_out);
1796
1797 return result;
1798}
1799
1800static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001801delta_add(PyObject *left, PyObject *right)
1802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1806 /* delta + delta */
1807 /* The C-level additions can't overflow because of the
1808 * invariant bounds.
1809 */
1810 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1811 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1812 int microseconds = GET_TD_MICROSECONDS(left) +
1813 GET_TD_MICROSECONDS(right);
1814 result = new_delta(days, seconds, microseconds, 1);
1815 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 if (result == Py_NotImplemented)
1818 Py_INCREF(result);
1819 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001820}
1821
1822static PyObject *
1823delta_negative(PyDateTime_Delta *self)
1824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 return new_delta(-GET_TD_DAYS(self),
1826 -GET_TD_SECONDS(self),
1827 -GET_TD_MICROSECONDS(self),
1828 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001829}
1830
1831static PyObject *
1832delta_positive(PyDateTime_Delta *self)
1833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 /* Could optimize this (by returning self) if this isn't a
1835 * subclass -- but who uses unary + ? Approximately nobody.
1836 */
1837 return new_delta(GET_TD_DAYS(self),
1838 GET_TD_SECONDS(self),
1839 GET_TD_MICROSECONDS(self),
1840 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001841}
1842
1843static PyObject *
1844delta_abs(PyDateTime_Delta *self)
1845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 assert(GET_TD_MICROSECONDS(self) >= 0);
1849 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 if (GET_TD_DAYS(self) < 0)
1852 result = delta_negative(self);
1853 else
1854 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001857}
1858
1859static PyObject *
1860delta_subtract(PyObject *left, PyObject *right)
1861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1865 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001866 /* The C-level additions can't overflow because of the
1867 * invariant bounds.
1868 */
1869 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1870 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1871 int microseconds = GET_TD_MICROSECONDS(left) -
1872 GET_TD_MICROSECONDS(right);
1873 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 if (result == Py_NotImplemented)
1877 Py_INCREF(result);
1878 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001879}
1880
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001881static int
1882delta_cmp(PyObject *self, PyObject *other)
1883{
1884 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1885 if (diff == 0) {
1886 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1887 if (diff == 0)
1888 diff = GET_TD_MICROSECONDS(self) -
1889 GET_TD_MICROSECONDS(other);
1890 }
1891 return diff;
1892}
1893
Tim Peters2a799bf2002-12-16 20:18:38 +00001894static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001895delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001898 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 return diff_to_bool(diff, op);
1900 }
1901 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001902 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001904}
1905
1906static PyObject *delta_getstate(PyDateTime_Delta *self);
1907
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001908static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001909delta_hash(PyDateTime_Delta *self)
1910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (self->hashcode == -1) {
1912 PyObject *temp = delta_getstate(self);
1913 if (temp != NULL) {
1914 self->hashcode = PyObject_Hash(temp);
1915 Py_DECREF(temp);
1916 }
1917 }
1918 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001919}
1920
1921static PyObject *
1922delta_multiply(PyObject *left, PyObject *right)
1923{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 if (PyDelta_Check(left)) {
1927 /* delta * ??? */
1928 if (PyLong_Check(right))
1929 result = multiply_int_timedelta(right,
1930 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001931 else if (PyFloat_Check(right))
1932 result = multiply_float_timedelta(right,
1933 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 }
1935 else if (PyLong_Check(left))
1936 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001937 (PyDateTime_Delta *) right);
1938 else if (PyFloat_Check(left))
1939 result = multiply_float_timedelta(left,
1940 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 if (result == Py_NotImplemented)
1943 Py_INCREF(result);
1944 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001945}
1946
1947static PyObject *
1948delta_divide(PyObject *left, PyObject *right)
1949{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 if (PyDelta_Check(left)) {
1953 /* delta * ??? */
1954 if (PyLong_Check(right))
1955 result = divide_timedelta_int(
1956 (PyDateTime_Delta *)left,
1957 right);
1958 else if (PyDelta_Check(right))
1959 result = divide_timedelta_timedelta(
1960 (PyDateTime_Delta *)left,
1961 (PyDateTime_Delta *)right);
1962 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 if (result == Py_NotImplemented)
1965 Py_INCREF(result);
1966 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001967}
1968
Mark Dickinson7c186e22010-04-20 22:32:49 +00001969static PyObject *
1970delta_truedivide(PyObject *left, PyObject *right)
1971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 if (PyDelta_Check(left)) {
1975 if (PyDelta_Check(right))
1976 result = truedivide_timedelta_timedelta(
1977 (PyDateTime_Delta *)left,
1978 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001979 else if (PyFloat_Check(right))
1980 result = truedivide_timedelta_float(
1981 (PyDateTime_Delta *)left, right);
1982 else if (PyLong_Check(right))
1983 result = truedivide_timedelta_int(
1984 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 if (result == Py_NotImplemented)
1988 Py_INCREF(result);
1989 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001990}
1991
1992static PyObject *
1993delta_remainder(PyObject *left, PyObject *right)
1994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 PyObject *pyus_left;
1996 PyObject *pyus_right;
1997 PyObject *pyus_remainder;
1998 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001999
Brian Curtindfc80e32011-08-10 20:28:54 -05002000 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2001 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2004 if (pyus_left == NULL)
2005 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2008 if (pyus_right == NULL) {
2009 Py_DECREF(pyus_left);
2010 return NULL;
2011 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2014 Py_DECREF(pyus_left);
2015 Py_DECREF(pyus_right);
2016 if (pyus_remainder == NULL)
2017 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 remainder = microseconds_to_delta(pyus_remainder);
2020 Py_DECREF(pyus_remainder);
2021 if (remainder == NULL)
2022 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002025}
2026
2027static PyObject *
2028delta_divmod(PyObject *left, PyObject *right)
2029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 PyObject *pyus_left;
2031 PyObject *pyus_right;
2032 PyObject *divmod;
2033 PyObject *delta;
2034 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002035
Brian Curtindfc80e32011-08-10 20:28:54 -05002036 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2037 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2040 if (pyus_left == NULL)
2041 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2044 if (pyus_right == NULL) {
2045 Py_DECREF(pyus_left);
2046 return NULL;
2047 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2050 Py_DECREF(pyus_left);
2051 Py_DECREF(pyus_right);
2052 if (divmod == NULL)
2053 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002054
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002055 assert(PyTuple_Size(divmod) == 2);
2056 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2057 if (delta == NULL) {
2058 Py_DECREF(divmod);
2059 return NULL;
2060 }
2061 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2062 Py_DECREF(delta);
2063 Py_DECREF(divmod);
2064 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002065}
2066
Tim Peters2a799bf2002-12-16 20:18:38 +00002067/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2068 * timedelta constructor. sofar is the # of microseconds accounted for
2069 * so far, and there are factor microseconds per current unit, the number
2070 * of which is given by num. num * factor is added to sofar in a
2071 * numerically careful way, and that's the result. Any fractional
2072 * microseconds left over (this can happen if num is a float type) are
2073 * added into *leftover.
2074 * Note that there are many ways this can give an error (NULL) return.
2075 */
2076static PyObject *
2077accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2078 double *leftover)
2079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002080 PyObject *prod;
2081 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 if (PyLong_Check(num)) {
2086 prod = PyNumber_Multiply(num, factor);
2087 if (prod == NULL)
2088 return NULL;
2089 sum = PyNumber_Add(sofar, prod);
2090 Py_DECREF(prod);
2091 return sum;
2092 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 if (PyFloat_Check(num)) {
2095 double dnum;
2096 double fracpart;
2097 double intpart;
2098 PyObject *x;
2099 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 /* The Plan: decompose num into an integer part and a
2102 * fractional part, num = intpart + fracpart.
2103 * Then num * factor ==
2104 * intpart * factor + fracpart * factor
2105 * and the LHS can be computed exactly in long arithmetic.
2106 * The RHS is again broken into an int part and frac part.
2107 * and the frac part is added into *leftover.
2108 */
2109 dnum = PyFloat_AsDouble(num);
2110 if (dnum == -1.0 && PyErr_Occurred())
2111 return NULL;
2112 fracpart = modf(dnum, &intpart);
2113 x = PyLong_FromDouble(intpart);
2114 if (x == NULL)
2115 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 prod = PyNumber_Multiply(x, factor);
2118 Py_DECREF(x);
2119 if (prod == NULL)
2120 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 sum = PyNumber_Add(sofar, prod);
2123 Py_DECREF(prod);
2124 if (sum == NULL)
2125 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 if (fracpart == 0.0)
2128 return sum;
2129 /* So far we've lost no information. Dealing with the
2130 * fractional part requires float arithmetic, and may
2131 * lose a little info.
2132 */
2133 assert(PyLong_Check(factor));
2134 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 dnum *= fracpart;
2137 fracpart = modf(dnum, &intpart);
2138 x = PyLong_FromDouble(intpart);
2139 if (x == NULL) {
2140 Py_DECREF(sum);
2141 return NULL;
2142 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 y = PyNumber_Add(sum, x);
2145 Py_DECREF(sum);
2146 Py_DECREF(x);
2147 *leftover += fracpart;
2148 return y;
2149 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 PyErr_Format(PyExc_TypeError,
2152 "unsupported type for timedelta %s component: %s",
2153 tag, Py_TYPE(num)->tp_name);
2154 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002155}
2156
2157static PyObject *
2158delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 /* Argument objects. */
2163 PyObject *day = NULL;
2164 PyObject *second = NULL;
2165 PyObject *us = NULL;
2166 PyObject *ms = NULL;
2167 PyObject *minute = NULL;
2168 PyObject *hour = NULL;
2169 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 PyObject *x = NULL; /* running sum of microseconds */
2172 PyObject *y = NULL; /* temp sum of microseconds */
2173 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 static char *keywords[] = {
2176 "days", "seconds", "microseconds", "milliseconds",
2177 "minutes", "hours", "weeks", NULL
2178 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2181 keywords,
2182 &day, &second, &us,
2183 &ms, &minute, &hour, &week) == 0)
2184 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 x = PyLong_FromLong(0);
2187 if (x == NULL)
2188 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190#define CLEANUP \
2191 Py_DECREF(x); \
2192 x = y; \
2193 if (x == NULL) \
2194 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002197 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 CLEANUP;
2199 }
2200 if (ms) {
2201 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2202 CLEANUP;
2203 }
2204 if (second) {
2205 y = accum("seconds", x, second, us_per_second, &leftover_us);
2206 CLEANUP;
2207 }
2208 if (minute) {
2209 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2210 CLEANUP;
2211 }
2212 if (hour) {
2213 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2214 CLEANUP;
2215 }
2216 if (day) {
2217 y = accum("days", x, day, us_per_day, &leftover_us);
2218 CLEANUP;
2219 }
2220 if (week) {
2221 y = accum("weeks", x, week, us_per_week, &leftover_us);
2222 CLEANUP;
2223 }
2224 if (leftover_us) {
2225 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002226 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002227 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002228 PyObject *temp;
2229
Victor Stinner69cc4872015-09-08 23:58:54 +02002230 whole_us = round(leftover_us);
2231 if (fabs(whole_us - leftover_us) == 0.5) {
2232 /* We're exactly halfway between two integers. In order
2233 * to do round-half-to-even, we must determine whether x
2234 * is odd. Note that x is odd when it's last bit is 1. The
2235 * code below uses bitwise and operation to check the last
2236 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002237 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002238 if (temp == NULL) {
2239 Py_DECREF(x);
2240 goto Done;
2241 }
2242 x_is_odd = PyObject_IsTrue(temp);
2243 Py_DECREF(temp);
2244 if (x_is_odd == -1) {
2245 Py_DECREF(x);
2246 goto Done;
2247 }
2248 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2249 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002250
Victor Stinner36a5a062013-08-28 01:53:39 +02002251 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 if (temp == NULL) {
2254 Py_DECREF(x);
2255 goto Done;
2256 }
2257 y = PyNumber_Add(x, temp);
2258 Py_DECREF(temp);
2259 CLEANUP;
2260 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 self = microseconds_to_delta_ex(x, type);
2263 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002264Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002266
2267#undef CLEANUP
2268}
2269
2270static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002271delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002272{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 return (GET_TD_DAYS(self) != 0
2274 || GET_TD_SECONDS(self) != 0
2275 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002276}
2277
2278static PyObject *
2279delta_repr(PyDateTime_Delta *self)
2280{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002281 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002282
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002283 if (args == NULL) {
2284 return NULL;
2285 }
2286
2287 const char *sep = "";
2288
2289 if (GET_TD_DAYS(self) != 0) {
2290 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2291 if (args == NULL) {
2292 return NULL;
2293 }
2294 sep = ", ";
2295 }
2296
2297 if (GET_TD_SECONDS(self) != 0) {
2298 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2299 GET_TD_SECONDS(self)));
2300 if (args == NULL) {
2301 return NULL;
2302 }
2303 sep = ", ";
2304 }
2305
2306 if (GET_TD_MICROSECONDS(self) != 0) {
2307 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2308 GET_TD_MICROSECONDS(self)));
2309 if (args == NULL) {
2310 return NULL;
2311 }
2312 }
2313
2314 if (PyUnicode_GET_LENGTH(args) == 0) {
2315 Py_SETREF(args, PyUnicode_FromString("0"));
2316 if (args == NULL) {
2317 return NULL;
2318 }
2319 }
2320
2321 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2322 args);
2323 Py_DECREF(args);
2324 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002325}
2326
2327static PyObject *
2328delta_str(PyDateTime_Delta *self)
2329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002330 int us = GET_TD_MICROSECONDS(self);
2331 int seconds = GET_TD_SECONDS(self);
2332 int minutes = divmod(seconds, 60, &seconds);
2333 int hours = divmod(minutes, 60, &minutes);
2334 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336 if (days) {
2337 if (us)
2338 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2339 days, (days == 1 || days == -1) ? "" : "s",
2340 hours, minutes, seconds, us);
2341 else
2342 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2343 days, (days == 1 || days == -1) ? "" : "s",
2344 hours, minutes, seconds);
2345 } else {
2346 if (us)
2347 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2348 hours, minutes, seconds, us);
2349 else
2350 return PyUnicode_FromFormat("%d:%02d:%02d",
2351 hours, minutes, seconds);
2352 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002353
Tim Peters2a799bf2002-12-16 20:18:38 +00002354}
2355
Tim Peters371935f2003-02-01 01:52:50 +00002356/* Pickle support, a simple use of __reduce__. */
2357
Tim Petersb57f8f02003-02-01 02:54:15 +00002358/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002359static PyObject *
2360delta_getstate(PyDateTime_Delta *self)
2361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 return Py_BuildValue("iii", GET_TD_DAYS(self),
2363 GET_TD_SECONDS(self),
2364 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002365}
2366
Tim Peters2a799bf2002-12-16 20:18:38 +00002367static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002368delta_total_seconds(PyObject *self)
2369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370 PyObject *total_seconds;
2371 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2374 if (total_microseconds == NULL)
2375 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002376
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002377 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002381}
2382
2383static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002384delta_reduce(PyDateTime_Delta* self)
2385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002387}
2388
2389#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2390
2391static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 {"days", T_INT, OFFSET(days), READONLY,
2394 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 {"seconds", T_INT, OFFSET(seconds), READONLY,
2397 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2400 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2401 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002402};
2403
2404static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2406 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2409 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002412};
2413
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002414static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002415PyDoc_STR("Difference between two datetime values.");
2416
2417static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 delta_add, /* nb_add */
2419 delta_subtract, /* nb_subtract */
2420 delta_multiply, /* nb_multiply */
2421 delta_remainder, /* nb_remainder */
2422 delta_divmod, /* nb_divmod */
2423 0, /* nb_power */
2424 (unaryfunc)delta_negative, /* nb_negative */
2425 (unaryfunc)delta_positive, /* nb_positive */
2426 (unaryfunc)delta_abs, /* nb_absolute */
2427 (inquiry)delta_bool, /* nb_bool */
2428 0, /*nb_invert*/
2429 0, /*nb_lshift*/
2430 0, /*nb_rshift*/
2431 0, /*nb_and*/
2432 0, /*nb_xor*/
2433 0, /*nb_or*/
2434 0, /*nb_int*/
2435 0, /*nb_reserved*/
2436 0, /*nb_float*/
2437 0, /*nb_inplace_add*/
2438 0, /*nb_inplace_subtract*/
2439 0, /*nb_inplace_multiply*/
2440 0, /*nb_inplace_remainder*/
2441 0, /*nb_inplace_power*/
2442 0, /*nb_inplace_lshift*/
2443 0, /*nb_inplace_rshift*/
2444 0, /*nb_inplace_and*/
2445 0, /*nb_inplace_xor*/
2446 0, /*nb_inplace_or*/
2447 delta_divide, /* nb_floor_divide */
2448 delta_truedivide, /* nb_true_divide */
2449 0, /* nb_inplace_floor_divide */
2450 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002451};
2452
2453static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002454 PyVarObject_HEAD_INIT(NULL, 0)
2455 "datetime.timedelta", /* tp_name */
2456 sizeof(PyDateTime_Delta), /* tp_basicsize */
2457 0, /* tp_itemsize */
2458 0, /* tp_dealloc */
2459 0, /* tp_print */
2460 0, /* tp_getattr */
2461 0, /* tp_setattr */
2462 0, /* tp_reserved */
2463 (reprfunc)delta_repr, /* tp_repr */
2464 &delta_as_number, /* tp_as_number */
2465 0, /* tp_as_sequence */
2466 0, /* tp_as_mapping */
2467 (hashfunc)delta_hash, /* tp_hash */
2468 0, /* tp_call */
2469 (reprfunc)delta_str, /* tp_str */
2470 PyObject_GenericGetAttr, /* tp_getattro */
2471 0, /* tp_setattro */
2472 0, /* tp_as_buffer */
2473 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2474 delta_doc, /* tp_doc */
2475 0, /* tp_traverse */
2476 0, /* tp_clear */
2477 delta_richcompare, /* tp_richcompare */
2478 0, /* tp_weaklistoffset */
2479 0, /* tp_iter */
2480 0, /* tp_iternext */
2481 delta_methods, /* tp_methods */
2482 delta_members, /* tp_members */
2483 0, /* tp_getset */
2484 0, /* tp_base */
2485 0, /* tp_dict */
2486 0, /* tp_descr_get */
2487 0, /* tp_descr_set */
2488 0, /* tp_dictoffset */
2489 0, /* tp_init */
2490 0, /* tp_alloc */
2491 delta_new, /* tp_new */
2492 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002493};
2494
2495/*
2496 * PyDateTime_Date implementation.
2497 */
2498
2499/* Accessor properties. */
2500
2501static PyObject *
2502date_year(PyDateTime_Date *self, void *unused)
2503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002505}
2506
2507static PyObject *
2508date_month(PyDateTime_Date *self, void *unused)
2509{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002510 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002511}
2512
2513static PyObject *
2514date_day(PyDateTime_Date *self, void *unused)
2515{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002517}
2518
2519static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 {"year", (getter)date_year},
2521 {"month", (getter)date_month},
2522 {"day", (getter)date_day},
2523 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002524};
2525
2526/* Constructors. */
2527
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002528static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002529
Tim Peters2a799bf2002-12-16 20:18:38 +00002530static PyObject *
2531date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002533 PyObject *self = NULL;
2534 PyObject *state;
2535 int year;
2536 int month;
2537 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 /* Check for invocation from pickle with __getstate__ state */
2540 if (PyTuple_GET_SIZE(args) == 1 &&
2541 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2542 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2543 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2544 {
2545 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002547 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2548 if (me != NULL) {
2549 char *pdata = PyBytes_AS_STRING(state);
2550 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2551 me->hashcode = -1;
2552 }
2553 return (PyObject *)me;
2554 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2557 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558 self = new_date_ex(year, month, day, type);
2559 }
2560 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002561}
2562
2563/* Return new date from localtime(t). */
2564static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002565date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002566{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002567 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002568 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002569
Victor Stinnere4a994d2015-03-30 01:10:14 +02002570 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002572
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002573 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002574 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002575
2576 return PyObject_CallFunction(cls, "iii",
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002577 tm.tm_year + 1900,
2578 tm.tm_mon + 1,
2579 tm.tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002580}
2581
2582/* Return new date from current time.
2583 * We say this is equivalent to fromtimestamp(time.time()), and the
2584 * only way to be sure of that is to *call* time.time(). That's not
2585 * generally the same as calling C's time.
2586 */
2587static PyObject *
2588date_today(PyObject *cls, PyObject *dummy)
2589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002590 PyObject *time;
2591 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002592 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 time = time_time();
2595 if (time == NULL)
2596 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 /* Note well: today() is a class method, so this may not call
2599 * date.fromtimestamp. For example, it may call
2600 * datetime.fromtimestamp. That's why we need all the accuracy
2601 * time.time() delivers; if someone were gonzo about optimization,
2602 * date.today() could get away with plain C time().
2603 */
Victor Stinner20401de2016-12-09 15:24:31 +01002604 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2605 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606 Py_DECREF(time);
2607 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002608}
2609
2610/* Return new date from given timestamp (Python timestamp -- a double). */
2611static PyObject *
2612date_fromtimestamp(PyObject *cls, PyObject *args)
2613{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002614 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002615 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002616
Victor Stinner5d272cc2012-03-13 13:35:55 +01002617 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2618 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002619 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002620}
2621
2622/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2623 * the ordinal is out of range.
2624 */
2625static PyObject *
2626date_fromordinal(PyObject *cls, PyObject *args)
2627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002628 PyObject *result = NULL;
2629 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2632 int year;
2633 int month;
2634 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 if (ordinal < 1)
2637 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2638 ">= 1");
2639 else {
2640 ord_to_ymd(ordinal, &year, &month, &day);
2641 result = PyObject_CallFunction(cls, "iii",
2642 year, month, day);
2643 }
2644 }
2645 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002646}
2647
2648/*
2649 * Date arithmetic.
2650 */
2651
2652/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2653 * instead.
2654 */
2655static PyObject *
2656add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2657{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 PyObject *result = NULL;
2659 int year = GET_YEAR(date);
2660 int month = GET_MONTH(date);
2661 int deltadays = GET_TD_DAYS(delta);
2662 /* C-level overflow is impossible because |deltadays| < 1e9. */
2663 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002665 if (normalize_date(&year, &month, &day) >= 0)
2666 result = new_date(year, month, day);
2667 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002668}
2669
2670static PyObject *
2671date_add(PyObject *left, PyObject *right)
2672{
Brian Curtindfc80e32011-08-10 20:28:54 -05002673 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2674 Py_RETURN_NOTIMPLEMENTED;
2675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002676 if (PyDate_Check(left)) {
2677 /* date + ??? */
2678 if (PyDelta_Check(right))
2679 /* date + delta */
2680 return add_date_timedelta((PyDateTime_Date *) left,
2681 (PyDateTime_Delta *) right,
2682 0);
2683 }
2684 else {
2685 /* ??? + date
2686 * 'right' must be one of us, or we wouldn't have been called
2687 */
2688 if (PyDelta_Check(left))
2689 /* delta + date */
2690 return add_date_timedelta((PyDateTime_Date *) right,
2691 (PyDateTime_Delta *) left,
2692 0);
2693 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002694 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002695}
2696
2697static PyObject *
2698date_subtract(PyObject *left, PyObject *right)
2699{
Brian Curtindfc80e32011-08-10 20:28:54 -05002700 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2701 Py_RETURN_NOTIMPLEMENTED;
2702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002703 if (PyDate_Check(left)) {
2704 if (PyDate_Check(right)) {
2705 /* date - date */
2706 int left_ord = ymd_to_ord(GET_YEAR(left),
2707 GET_MONTH(left),
2708 GET_DAY(left));
2709 int right_ord = ymd_to_ord(GET_YEAR(right),
2710 GET_MONTH(right),
2711 GET_DAY(right));
2712 return new_delta(left_ord - right_ord, 0, 0, 0);
2713 }
2714 if (PyDelta_Check(right)) {
2715 /* date - delta */
2716 return add_date_timedelta((PyDateTime_Date *) left,
2717 (PyDateTime_Delta *) right,
2718 1);
2719 }
2720 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002721 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002722}
2723
2724
2725/* Various ways to turn a date into a string. */
2726
2727static PyObject *
2728date_repr(PyDateTime_Date *self)
2729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002730 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2731 Py_TYPE(self)->tp_name,
2732 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002733}
2734
2735static PyObject *
2736date_isoformat(PyDateTime_Date *self)
2737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002738 return PyUnicode_FromFormat("%04d-%02d-%02d",
2739 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002740}
2741
Tim Peterse2df5ff2003-05-02 18:39:55 +00002742/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002743static PyObject *
2744date_str(PyDateTime_Date *self)
2745{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002746 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002747}
2748
2749
2750static PyObject *
2751date_ctime(PyDateTime_Date *self)
2752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002753 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002754}
2755
2756static PyObject *
2757date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002759 /* This method can be inherited, and needs to call the
2760 * timetuple() method appropriate to self's class.
2761 */
2762 PyObject *result;
2763 PyObject *tuple;
2764 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002765 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002766 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002768 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2769 &format))
2770 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002771
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002772 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002773 if (tuple == NULL)
2774 return NULL;
2775 result = wrap_strftime((PyObject *)self, format, tuple,
2776 (PyObject *)self);
2777 Py_DECREF(tuple);
2778 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002779}
2780
Eric Smith1ba31142007-09-11 18:06:02 +00002781static PyObject *
2782date_format(PyDateTime_Date *self, PyObject *args)
2783{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002784 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002786 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2787 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002789 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002790 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002791 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002792
Victor Stinner20401de2016-12-09 15:24:31 +01002793 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
2794 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00002795}
2796
Tim Peters2a799bf2002-12-16 20:18:38 +00002797/* ISO methods. */
2798
2799static PyObject *
2800date_isoweekday(PyDateTime_Date *self)
2801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002802 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002804 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002805}
2806
2807static PyObject *
2808date_isocalendar(PyDateTime_Date *self)
2809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 int year = GET_YEAR(self);
2811 int week1_monday = iso_week1_monday(year);
2812 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2813 int week;
2814 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002816 week = divmod(today - week1_monday, 7, &day);
2817 if (week < 0) {
2818 --year;
2819 week1_monday = iso_week1_monday(year);
2820 week = divmod(today - week1_monday, 7, &day);
2821 }
2822 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2823 ++year;
2824 week = 0;
2825 }
2826 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002827}
2828
2829/* Miscellaneous methods. */
2830
Tim Peters2a799bf2002-12-16 20:18:38 +00002831static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002832date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002834 if (PyDate_Check(other)) {
2835 int diff = memcmp(((PyDateTime_Date *)self)->data,
2836 ((PyDateTime_Date *)other)->data,
2837 _PyDateTime_DATE_DATASIZE);
2838 return diff_to_bool(diff, op);
2839 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002840 else
2841 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002842}
2843
2844static PyObject *
2845date_timetuple(PyDateTime_Date *self)
2846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 return build_struct_time(GET_YEAR(self),
2848 GET_MONTH(self),
2849 GET_DAY(self),
2850 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002851}
2852
Tim Peters12bf3392002-12-24 05:41:27 +00002853static PyObject *
2854date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 PyObject *clone;
2857 PyObject *tuple;
2858 int year = GET_YEAR(self);
2859 int month = GET_MONTH(self);
2860 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2863 &year, &month, &day))
2864 return NULL;
2865 tuple = Py_BuildValue("iii", year, month, day);
2866 if (tuple == NULL)
2867 return NULL;
2868 clone = date_new(Py_TYPE(self), tuple, NULL);
2869 Py_DECREF(tuple);
2870 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002871}
2872
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002873static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002874generic_hash(unsigned char *data, int len)
2875{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002876 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002877}
2878
2879
2880static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002881
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002882static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002883date_hash(PyDateTime_Date *self)
2884{
Benjamin Petersondec2df32016-09-09 17:46:24 -07002885 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002886 self->hashcode = generic_hash(
2887 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07002888 }
Guido van Rossum254348e2007-11-21 19:29:53 +00002889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002891}
2892
2893static PyObject *
2894date_toordinal(PyDateTime_Date *self)
2895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002896 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2897 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002898}
2899
2900static PyObject *
2901date_weekday(PyDateTime_Date *self)
2902{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002903 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002905 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002906}
2907
Tim Peters371935f2003-02-01 01:52:50 +00002908/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002909
Tim Petersb57f8f02003-02-01 02:54:15 +00002910/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002911static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002912date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002913{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002914 PyObject* field;
2915 field = PyBytes_FromStringAndSize((char*)self->data,
2916 _PyDateTime_DATE_DATASIZE);
2917 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002918}
2919
2920static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002921date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002922{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002923 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002924}
2925
2926static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002928 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002930 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2931 METH_CLASS,
2932 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2933 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002935 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2936 METH_CLASS,
2937 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2938 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002940 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2941 PyDoc_STR("Current date or datetime: same as "
2942 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002944 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002946 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2947 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002949 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2950 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002952 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2953 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002955 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2956 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002958 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2959 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2960 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002962 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2963 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002965 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2966 PyDoc_STR("Return the day of the week represented by the date.\n"
2967 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002969 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2970 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2971 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002973 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2974 PyDoc_STR("Return the day of the week represented by the date.\n"
2975 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002977 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2978 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002980 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2981 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002983 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002984};
2985
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002986static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002987PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002988
2989static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002990 date_add, /* nb_add */
2991 date_subtract, /* nb_subtract */
2992 0, /* nb_multiply */
2993 0, /* nb_remainder */
2994 0, /* nb_divmod */
2995 0, /* nb_power */
2996 0, /* nb_negative */
2997 0, /* nb_positive */
2998 0, /* nb_absolute */
2999 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003000};
3001
3002static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003003 PyVarObject_HEAD_INIT(NULL, 0)
3004 "datetime.date", /* tp_name */
3005 sizeof(PyDateTime_Date), /* tp_basicsize */
3006 0, /* tp_itemsize */
3007 0, /* tp_dealloc */
3008 0, /* tp_print */
3009 0, /* tp_getattr */
3010 0, /* tp_setattr */
3011 0, /* tp_reserved */
3012 (reprfunc)date_repr, /* tp_repr */
3013 &date_as_number, /* tp_as_number */
3014 0, /* tp_as_sequence */
3015 0, /* tp_as_mapping */
3016 (hashfunc)date_hash, /* tp_hash */
3017 0, /* tp_call */
3018 (reprfunc)date_str, /* tp_str */
3019 PyObject_GenericGetAttr, /* tp_getattro */
3020 0, /* tp_setattro */
3021 0, /* tp_as_buffer */
3022 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3023 date_doc, /* tp_doc */
3024 0, /* tp_traverse */
3025 0, /* tp_clear */
3026 date_richcompare, /* tp_richcompare */
3027 0, /* tp_weaklistoffset */
3028 0, /* tp_iter */
3029 0, /* tp_iternext */
3030 date_methods, /* tp_methods */
3031 0, /* tp_members */
3032 date_getset, /* tp_getset */
3033 0, /* tp_base */
3034 0, /* tp_dict */
3035 0, /* tp_descr_get */
3036 0, /* tp_descr_set */
3037 0, /* tp_dictoffset */
3038 0, /* tp_init */
3039 0, /* tp_alloc */
3040 date_new, /* tp_new */
3041 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003042};
3043
3044/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003045 * PyDateTime_TZInfo implementation.
3046 */
3047
3048/* This is a pure abstract base class, so doesn't do anything beyond
3049 * raising NotImplemented exceptions. Real tzinfo classes need
3050 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003051 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003052 * be subclasses of this tzinfo class, which is easy and quick to check).
3053 *
3054 * Note: For reasons having to do with pickling of subclasses, we have
3055 * to allow tzinfo objects to be instantiated. This wasn't an issue
3056 * in the Python implementation (__init__() could raise NotImplementedError
3057 * there without ill effect), but doing so in the C implementation hit a
3058 * brick wall.
3059 */
3060
3061static PyObject *
3062tzinfo_nogo(const char* methodname)
3063{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003064 PyErr_Format(PyExc_NotImplementedError,
3065 "a tzinfo subclass must implement %s()",
3066 methodname);
3067 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003068}
3069
3070/* Methods. A subclass must implement these. */
3071
Tim Peters52dcce22003-01-23 16:36:11 +00003072static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003073tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003075 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003076}
3077
Tim Peters52dcce22003-01-23 16:36:11 +00003078static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003079tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003081 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003082}
3083
Tim Peters52dcce22003-01-23 16:36:11 +00003084static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003085tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003087 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003088}
3089
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003090
3091static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3092 PyDateTime_Delta *delta,
3093 int factor);
3094static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3095static PyObject *datetime_dst(PyObject *self, PyObject *);
3096
Tim Peters52dcce22003-01-23 16:36:11 +00003097static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003098tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003099{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003100 PyObject *result = NULL;
3101 PyObject *off = NULL, *dst = NULL;
3102 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003103
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003104 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003105 PyErr_SetString(PyExc_TypeError,
3106 "fromutc: argument must be a datetime");
3107 return NULL;
3108 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003109 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3111 "is not self");
3112 return NULL;
3113 }
Tim Peters52dcce22003-01-23 16:36:11 +00003114
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003115 off = datetime_utcoffset(dt, NULL);
3116 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003117 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003118 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003119 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3120 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003121 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 }
Tim Peters52dcce22003-01-23 16:36:11 +00003123
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003124 dst = datetime_dst(dt, NULL);
3125 if (dst == NULL)
3126 goto Fail;
3127 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3129 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003130 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003131 }
Tim Peters52dcce22003-01-23 16:36:11 +00003132
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003133 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3134 if (delta == NULL)
3135 goto Fail;
3136 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003137 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003138 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003139
3140 Py_DECREF(dst);
3141 dst = call_dst(GET_DT_TZINFO(dt), result);
3142 if (dst == NULL)
3143 goto Fail;
3144 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003145 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003146 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003147 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003148 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003149 if (result == NULL)
3150 goto Fail;
3151 }
3152 Py_DECREF(delta);
3153 Py_DECREF(dst);
3154 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003155 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003156
3157Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003158 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3159 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003161 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003162Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003163 Py_XDECREF(off);
3164 Py_XDECREF(dst);
3165 Py_XDECREF(delta);
3166 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003167 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003168}
3169
Tim Peters2a799bf2002-12-16 20:18:38 +00003170/*
3171 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003172 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003173 */
3174
Guido van Rossum177e41a2003-01-30 22:06:23 +00003175static PyObject *
3176tzinfo_reduce(PyObject *self)
3177{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003178 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003179 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003180 _Py_IDENTIFIER(__getinitargs__);
3181 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003182
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003183 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003184 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003185 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003186 Py_DECREF(getinitargs);
3187 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003188 return NULL;
3189 }
3190 }
3191 else {
3192 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003193
3194 args = PyTuple_New(0);
3195 if (args == NULL) {
3196 return NULL;
3197 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003199
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003200 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003201 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003202 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003203 Py_DECREF(getstate);
3204 if (state == NULL) {
3205 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003206 return NULL;
3207 }
3208 }
3209 else {
3210 PyObject **dictptr;
3211 PyErr_Clear();
3212 state = Py_None;
3213 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003214 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003216 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 Py_INCREF(state);
3218 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003220 if (state == Py_None) {
3221 Py_DECREF(state);
3222 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3223 }
3224 else
3225 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003226}
Tim Peters2a799bf2002-12-16 20:18:38 +00003227
3228static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003230 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3231 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003233 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003234 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3235 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003237 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003238 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003240 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003241 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003243 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3244 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003246 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003247};
3248
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003249static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003250PyDoc_STR("Abstract base class for time zone info objects.");
3251
Neal Norwitz227b5332006-03-22 09:28:35 +00003252static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003253 PyVarObject_HEAD_INIT(NULL, 0)
3254 "datetime.tzinfo", /* tp_name */
3255 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3256 0, /* tp_itemsize */
3257 0, /* tp_dealloc */
3258 0, /* tp_print */
3259 0, /* tp_getattr */
3260 0, /* tp_setattr */
3261 0, /* tp_reserved */
3262 0, /* tp_repr */
3263 0, /* tp_as_number */
3264 0, /* tp_as_sequence */
3265 0, /* tp_as_mapping */
3266 0, /* tp_hash */
3267 0, /* tp_call */
3268 0, /* tp_str */
3269 PyObject_GenericGetAttr, /* tp_getattro */
3270 0, /* tp_setattro */
3271 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003272 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003273 tzinfo_doc, /* tp_doc */
3274 0, /* tp_traverse */
3275 0, /* tp_clear */
3276 0, /* tp_richcompare */
3277 0, /* tp_weaklistoffset */
3278 0, /* tp_iter */
3279 0, /* tp_iternext */
3280 tzinfo_methods, /* tp_methods */
3281 0, /* tp_members */
3282 0, /* tp_getset */
3283 0, /* tp_base */
3284 0, /* tp_dict */
3285 0, /* tp_descr_get */
3286 0, /* tp_descr_set */
3287 0, /* tp_dictoffset */
3288 0, /* tp_init */
3289 0, /* tp_alloc */
3290 PyType_GenericNew, /* tp_new */
3291 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003292};
3293
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003294static char *timezone_kws[] = {"offset", "name", NULL};
3295
3296static PyObject *
3297timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3298{
3299 PyObject *offset;
3300 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003301 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3302 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003303 return new_timezone(offset, name);
3304
3305 return NULL;
3306}
3307
3308static void
3309timezone_dealloc(PyDateTime_TimeZone *self)
3310{
3311 Py_CLEAR(self->offset);
3312 Py_CLEAR(self->name);
3313 Py_TYPE(self)->tp_free((PyObject *)self);
3314}
3315
3316static PyObject *
3317timezone_richcompare(PyDateTime_TimeZone *self,
3318 PyDateTime_TimeZone *other, int op)
3319{
Brian Curtindfc80e32011-08-10 20:28:54 -05003320 if (op != Py_EQ && op != Py_NE)
3321 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003322 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003323 if (op == Py_EQ)
3324 Py_RETURN_FALSE;
3325 else
3326 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003327 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003328 return delta_richcompare(self->offset, other->offset, op);
3329}
3330
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003331static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003332timezone_hash(PyDateTime_TimeZone *self)
3333{
3334 return delta_hash((PyDateTime_Delta *)self->offset);
3335}
3336
3337/* Check argument type passed to tzname, utcoffset, or dst methods.
3338 Returns 0 for good argument. Returns -1 and sets exception info
3339 otherwise.
3340 */
3341static int
3342_timezone_check_argument(PyObject *dt, const char *meth)
3343{
3344 if (dt == Py_None || PyDateTime_Check(dt))
3345 return 0;
3346 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3347 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3348 return -1;
3349}
3350
3351static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003352timezone_repr(PyDateTime_TimeZone *self)
3353{
3354 /* Note that although timezone is not subclassable, it is convenient
3355 to use Py_TYPE(self)->tp_name here. */
3356 const char *type_name = Py_TYPE(self)->tp_name;
3357
3358 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3359 return PyUnicode_FromFormat("%s.utc", type_name);
3360
3361 if (self->name == NULL)
3362 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3363
3364 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3365 self->name);
3366}
3367
3368
3369static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003370timezone_str(PyDateTime_TimeZone *self)
3371{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003372 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003373 PyObject *offset;
3374 char sign;
3375
3376 if (self->name != NULL) {
3377 Py_INCREF(self->name);
3378 return self->name;
3379 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003380 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003381 (GET_TD_DAYS(self->offset) == 0 &&
3382 GET_TD_SECONDS(self->offset) == 0 &&
3383 GET_TD_MICROSECONDS(self->offset) == 0))
3384 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003385 /* Offset is normalized, so it is negative if days < 0 */
3386 if (GET_TD_DAYS(self->offset) < 0) {
3387 sign = '-';
3388 offset = delta_negative((PyDateTime_Delta *)self->offset);
3389 if (offset == NULL)
3390 return NULL;
3391 }
3392 else {
3393 sign = '+';
3394 offset = self->offset;
3395 Py_INCREF(offset);
3396 }
3397 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003398 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003399 seconds = GET_TD_SECONDS(offset);
3400 Py_DECREF(offset);
3401 minutes = divmod(seconds, 60, &seconds);
3402 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003403 if (microseconds != 0) {
3404 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3405 sign, hours, minutes,
3406 seconds, microseconds);
3407 }
3408 if (seconds != 0) {
3409 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3410 sign, hours, minutes, seconds);
3411 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003412 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003413}
3414
3415static PyObject *
3416timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3417{
3418 if (_timezone_check_argument(dt, "tzname") == -1)
3419 return NULL;
3420
3421 return timezone_str(self);
3422}
3423
3424static PyObject *
3425timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3426{
3427 if (_timezone_check_argument(dt, "utcoffset") == -1)
3428 return NULL;
3429
3430 Py_INCREF(self->offset);
3431 return self->offset;
3432}
3433
3434static PyObject *
3435timezone_dst(PyObject *self, PyObject *dt)
3436{
3437 if (_timezone_check_argument(dt, "dst") == -1)
3438 return NULL;
3439
3440 Py_RETURN_NONE;
3441}
3442
3443static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003444timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3445{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003446 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003447 PyErr_SetString(PyExc_TypeError,
3448 "fromutc: argument must be a datetime");
3449 return NULL;
3450 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003451 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003452 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3453 "is not self");
3454 return NULL;
3455 }
3456
3457 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3458}
3459
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003460static PyObject *
3461timezone_getinitargs(PyDateTime_TimeZone *self)
3462{
3463 if (self->name == NULL)
3464 return Py_BuildValue("(O)", self->offset);
3465 return Py_BuildValue("(OO)", self->offset, self->name);
3466}
3467
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003468static PyMethodDef timezone_methods[] = {
3469 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3470 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003471 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003472
3473 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003474 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003475
3476 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003477 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003478
3479 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3480 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3481
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003482 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3483 PyDoc_STR("pickle support")},
3484
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003485 {NULL, NULL}
3486};
3487
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003488static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003489PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3490
3491static PyTypeObject PyDateTime_TimeZoneType = {
3492 PyVarObject_HEAD_INIT(NULL, 0)
3493 "datetime.timezone", /* tp_name */
3494 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3495 0, /* tp_itemsize */
3496 (destructor)timezone_dealloc, /* tp_dealloc */
3497 0, /* tp_print */
3498 0, /* tp_getattr */
3499 0, /* tp_setattr */
3500 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003501 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003502 0, /* tp_as_number */
3503 0, /* tp_as_sequence */
3504 0, /* tp_as_mapping */
3505 (hashfunc)timezone_hash, /* tp_hash */
3506 0, /* tp_call */
3507 (reprfunc)timezone_str, /* tp_str */
3508 0, /* tp_getattro */
3509 0, /* tp_setattro */
3510 0, /* tp_as_buffer */
3511 Py_TPFLAGS_DEFAULT, /* tp_flags */
3512 timezone_doc, /* tp_doc */
3513 0, /* tp_traverse */
3514 0, /* tp_clear */
3515 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3516 0, /* tp_weaklistoffset */
3517 0, /* tp_iter */
3518 0, /* tp_iternext */
3519 timezone_methods, /* tp_methods */
3520 0, /* tp_members */
3521 0, /* tp_getset */
3522 &PyDateTime_TZInfoType, /* tp_base */
3523 0, /* tp_dict */
3524 0, /* tp_descr_get */
3525 0, /* tp_descr_set */
3526 0, /* tp_dictoffset */
3527 0, /* tp_init */
3528 0, /* tp_alloc */
3529 timezone_new, /* tp_new */
3530};
3531
Tim Peters2a799bf2002-12-16 20:18:38 +00003532/*
Tim Peters37f39822003-01-10 03:49:02 +00003533 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003534 */
3535
Tim Peters37f39822003-01-10 03:49:02 +00003536/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003537 */
3538
3539static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003540time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003541{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003542 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003543}
3544
Tim Peters37f39822003-01-10 03:49:02 +00003545static PyObject *
3546time_minute(PyDateTime_Time *self, void *unused)
3547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003548 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003549}
3550
3551/* The name time_second conflicted with some platform header file. */
3552static PyObject *
3553py_time_second(PyDateTime_Time *self, void *unused)
3554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003556}
3557
3558static PyObject *
3559time_microsecond(PyDateTime_Time *self, void *unused)
3560{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003561 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003562}
3563
3564static PyObject *
3565time_tzinfo(PyDateTime_Time *self, void *unused)
3566{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003567 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3568 Py_INCREF(result);
3569 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003570}
3571
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003572static PyObject *
3573time_fold(PyDateTime_Time *self, void *unused)
3574{
3575 return PyLong_FromLong(TIME_GET_FOLD(self));
3576}
3577
Tim Peters37f39822003-01-10 03:49:02 +00003578static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003579 {"hour", (getter)time_hour},
3580 {"minute", (getter)time_minute},
3581 {"second", (getter)py_time_second},
3582 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003583 {"tzinfo", (getter)time_tzinfo},
3584 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003585 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003586};
3587
3588/*
3589 * Constructors.
3590 */
3591
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003592static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003593 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003594
Tim Peters2a799bf2002-12-16 20:18:38 +00003595static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003596time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003598 PyObject *self = NULL;
3599 PyObject *state;
3600 int hour = 0;
3601 int minute = 0;
3602 int second = 0;
3603 int usecond = 0;
3604 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003605 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003607 /* Check for invocation from pickle with __getstate__ state */
3608 if (PyTuple_GET_SIZE(args) >= 1 &&
3609 PyTuple_GET_SIZE(args) <= 2 &&
3610 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3611 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003612 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003613 {
3614 PyDateTime_Time *me;
3615 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003617 if (PyTuple_GET_SIZE(args) == 2) {
3618 tzinfo = PyTuple_GET_ITEM(args, 1);
3619 if (check_tzinfo_subclass(tzinfo) < 0) {
3620 PyErr_SetString(PyExc_TypeError, "bad "
3621 "tzinfo state arg");
3622 return NULL;
3623 }
3624 }
3625 aware = (char)(tzinfo != Py_None);
3626 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3627 if (me != NULL) {
3628 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003630 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3631 me->hashcode = -1;
3632 me->hastzinfo = aware;
3633 if (aware) {
3634 Py_INCREF(tzinfo);
3635 me->tzinfo = tzinfo;
3636 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003637 if (pdata[0] & (1 << 7)) {
3638 me->data[0] -= 128;
3639 me->fold = 1;
3640 }
3641 else {
3642 me->fold = 0;
3643 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003644 }
3645 return (PyObject *)me;
3646 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003647
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003648 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003649 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003650 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003651 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3652 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003653 }
3654 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003655}
3656
3657/*
3658 * Destructor.
3659 */
3660
3661static void
Tim Peters37f39822003-01-10 03:49:02 +00003662time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003663{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003664 if (HASTZINFO(self)) {
3665 Py_XDECREF(self->tzinfo);
3666 }
3667 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003668}
3669
3670/*
Tim Peters855fe882002-12-22 03:43:39 +00003671 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003672 */
3673
Tim Peters2a799bf2002-12-16 20:18:38 +00003674/* These are all METH_NOARGS, so don't need to check the arglist. */
3675static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003676time_utcoffset(PyObject *self, PyObject *unused) {
3677 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003678}
3679
3680static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003681time_dst(PyObject *self, PyObject *unused) {
3682 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003683}
3684
3685static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003686time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003687 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003688}
3689
3690/*
Tim Peters37f39822003-01-10 03:49:02 +00003691 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003692 */
3693
3694static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003695time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003696{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003697 const char *type_name = Py_TYPE(self)->tp_name;
3698 int h = TIME_GET_HOUR(self);
3699 int m = TIME_GET_MINUTE(self);
3700 int s = TIME_GET_SECOND(self);
3701 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003702 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003703 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003705 if (us)
3706 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3707 type_name, h, m, s, us);
3708 else if (s)
3709 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3710 type_name, h, m, s);
3711 else
3712 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3713 if (result != NULL && HASTZINFO(self))
3714 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003715 if (result != NULL && fold)
3716 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003717 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003718}
3719
Tim Peters37f39822003-01-10 03:49:02 +00003720static PyObject *
3721time_str(PyDateTime_Time *self)
3722{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003723 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003724}
Tim Peters2a799bf2002-12-16 20:18:38 +00003725
3726static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003727time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003729 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003730 char *timespec = NULL;
3731 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003732 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003733 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003734 static char *specs[][2] = {
3735 {"hours", "%02d"},
3736 {"minutes", "%02d:%02d"},
3737 {"seconds", "%02d:%02d:%02d"},
3738 {"milliseconds", "%02d:%02d:%02d.%03d"},
3739 {"microseconds", "%02d:%02d:%02d.%06d"},
3740 };
3741 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003742
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003743 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3744 return NULL;
3745
3746 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3747 if (us == 0) {
3748 /* seconds */
3749 given_spec = 2;
3750 }
3751 else {
3752 /* microseconds */
3753 given_spec = 4;
3754 }
3755 }
3756 else {
3757 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3758 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3759 if (given_spec == 3) {
3760 /* milliseconds */
3761 us = us / 1000;
3762 }
3763 break;
3764 }
3765 }
3766 }
3767
3768 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3769 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3770 return NULL;
3771 }
3772 else {
3773 result = PyUnicode_FromFormat(specs[given_spec][1],
3774 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3775 TIME_GET_SECOND(self), us);
3776 }
Tim Peters37f39822003-01-10 03:49:02 +00003777
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003778 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003779 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003781 /* We need to append the UTC offset. */
3782 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3783 Py_None) < 0) {
3784 Py_DECREF(result);
3785 return NULL;
3786 }
3787 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3788 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003789}
3790
Tim Peters37f39822003-01-10 03:49:02 +00003791static PyObject *
3792time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003794 PyObject *result;
3795 PyObject *tuple;
3796 PyObject *format;
3797 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003799 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3800 &format))
3801 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003803 /* Python's strftime does insane things with the year part of the
3804 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003805 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003806 */
3807 tuple = Py_BuildValue("iiiiiiiii",
3808 1900, 1, 1, /* year, month, day */
3809 TIME_GET_HOUR(self),
3810 TIME_GET_MINUTE(self),
3811 TIME_GET_SECOND(self),
3812 0, 1, -1); /* weekday, daynum, dst */
3813 if (tuple == NULL)
3814 return NULL;
3815 assert(PyTuple_Size(tuple) == 9);
3816 result = wrap_strftime((PyObject *)self, format, tuple,
3817 Py_None);
3818 Py_DECREF(tuple);
3819 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003820}
Tim Peters2a799bf2002-12-16 20:18:38 +00003821
3822/*
3823 * Miscellaneous methods.
3824 */
3825
Tim Peters37f39822003-01-10 03:49:02 +00003826static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003827time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003828{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003829 PyObject *result = NULL;
3830 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003831 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003832
Brian Curtindfc80e32011-08-10 20:28:54 -05003833 if (! PyTime_Check(other))
3834 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003835
3836 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003837 diff = memcmp(((PyDateTime_Time *)self)->data,
3838 ((PyDateTime_Time *)other)->data,
3839 _PyDateTime_TIME_DATASIZE);
3840 return diff_to_bool(diff, op);
3841 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003842 offset1 = time_utcoffset(self, NULL);
3843 if (offset1 == NULL)
3844 return NULL;
3845 offset2 = time_utcoffset(other, NULL);
3846 if (offset2 == NULL)
3847 goto done;
3848 /* If they're both naive, or both aware and have the same offsets,
3849 * we get off cheap. Note that if they're both naive, offset1 ==
3850 * offset2 == Py_None at this point.
3851 */
3852 if ((offset1 == offset2) ||
3853 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3854 delta_cmp(offset1, offset2) == 0)) {
3855 diff = memcmp(((PyDateTime_Time *)self)->data,
3856 ((PyDateTime_Time *)other)->data,
3857 _PyDateTime_TIME_DATASIZE);
3858 result = diff_to_bool(diff, op);
3859 }
3860 /* The hard case: both aware with different UTC offsets */
3861 else if (offset1 != Py_None && offset2 != Py_None) {
3862 int offsecs1, offsecs2;
3863 assert(offset1 != offset2); /* else last "if" handled it */
3864 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3865 TIME_GET_MINUTE(self) * 60 +
3866 TIME_GET_SECOND(self) -
3867 GET_TD_DAYS(offset1) * 86400 -
3868 GET_TD_SECONDS(offset1);
3869 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3870 TIME_GET_MINUTE(other) * 60 +
3871 TIME_GET_SECOND(other) -
3872 GET_TD_DAYS(offset2) * 86400 -
3873 GET_TD_SECONDS(offset2);
3874 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003875 if (diff == 0)
3876 diff = TIME_GET_MICROSECOND(self) -
3877 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003878 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003879 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003880 else if (op == Py_EQ) {
3881 result = Py_False;
3882 Py_INCREF(result);
3883 }
3884 else if (op == Py_NE) {
3885 result = Py_True;
3886 Py_INCREF(result);
3887 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003888 else {
3889 PyErr_SetString(PyExc_TypeError,
3890 "can't compare offset-naive and "
3891 "offset-aware times");
3892 }
3893 done:
3894 Py_DECREF(offset1);
3895 Py_XDECREF(offset2);
3896 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003897}
3898
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003899static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003900time_hash(PyDateTime_Time *self)
3901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003902 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003903 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01003904 if (TIME_GET_FOLD(self)) {
3905 self0 = new_time_ex2(TIME_GET_HOUR(self),
3906 TIME_GET_MINUTE(self),
3907 TIME_GET_SECOND(self),
3908 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003909 HASTZINFO(self) ? self->tzinfo : Py_None,
3910 0, Py_TYPE(self));
3911 if (self0 == NULL)
3912 return -1;
3913 }
3914 else {
3915 self0 = (PyObject *)self;
3916 Py_INCREF(self0);
3917 }
3918 offset = time_utcoffset(self0, NULL);
3919 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003920
3921 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003922 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003924 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003925 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003926 self->hashcode = generic_hash(
3927 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003928 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003929 PyObject *temp1, *temp2;
3930 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003931 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003932 seconds = TIME_GET_HOUR(self) * 3600 +
3933 TIME_GET_MINUTE(self) * 60 +
3934 TIME_GET_SECOND(self);
3935 microseconds = TIME_GET_MICROSECOND(self);
3936 temp1 = new_delta(0, seconds, microseconds, 1);
3937 if (temp1 == NULL) {
3938 Py_DECREF(offset);
3939 return -1;
3940 }
3941 temp2 = delta_subtract(temp1, offset);
3942 Py_DECREF(temp1);
3943 if (temp2 == NULL) {
3944 Py_DECREF(offset);
3945 return -1;
3946 }
3947 self->hashcode = PyObject_Hash(temp2);
3948 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003949 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003950 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003951 }
3952 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003953}
Tim Peters2a799bf2002-12-16 20:18:38 +00003954
Tim Peters12bf3392002-12-24 05:41:27 +00003955static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003956time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003958 PyObject *clone;
3959 PyObject *tuple;
3960 int hh = TIME_GET_HOUR(self);
3961 int mm = TIME_GET_MINUTE(self);
3962 int ss = TIME_GET_SECOND(self);
3963 int us = TIME_GET_MICROSECOND(self);
3964 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003965 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003966
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003967 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003968 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003969 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003970 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03003971 if (fold != 0 && fold != 1) {
3972 PyErr_SetString(PyExc_ValueError,
3973 "fold must be either 0 or 1");
3974 return NULL;
3975 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003976 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3977 if (tuple == NULL)
3978 return NULL;
3979 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003980 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003981 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003982 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003983 Py_DECREF(tuple);
3984 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003985}
3986
Tim Peters371935f2003-02-01 01:52:50 +00003987/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003988
Tim Peters33e0f382003-01-10 02:05:14 +00003989/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003990 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3991 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003992 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003993 */
3994static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003995time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00003996{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003997 PyObject *basestate;
3998 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004000 basestate = PyBytes_FromStringAndSize((char *)self->data,
4001 _PyDateTime_TIME_DATASIZE);
4002 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004003 if (proto > 3 && TIME_GET_FOLD(self))
4004 /* Set the first bit of the first byte */
4005 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004006 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4007 result = PyTuple_Pack(1, basestate);
4008 else
4009 result = PyTuple_Pack(2, basestate, self->tzinfo);
4010 Py_DECREF(basestate);
4011 }
4012 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004013}
4014
4015static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004016time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004017{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004018 int proto;
4019 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004020 return NULL;
4021
4022 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004023}
4024
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004025static PyObject *
4026time_reduce(PyDateTime_Time *self, PyObject *arg)
4027{
4028 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4029}
4030
Tim Peters37f39822003-01-10 03:49:02 +00004031static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004032
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004033 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4034 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4035 "[+HH:MM].\n\n"
4036 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004038 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4039 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004041 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4042 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004044 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4045 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004047 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4048 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004050 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4051 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004053 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4054 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004055
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004056 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004057 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004058
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004059 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4060 PyDoc_STR("__reduce__() -> (cls, state)")},
4061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004062 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004063};
4064
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004065static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004066PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4067\n\
4068All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004069a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004070
Neal Norwitz227b5332006-03-22 09:28:35 +00004071static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004072 PyVarObject_HEAD_INIT(NULL, 0)
4073 "datetime.time", /* tp_name */
4074 sizeof(PyDateTime_Time), /* tp_basicsize */
4075 0, /* tp_itemsize */
4076 (destructor)time_dealloc, /* tp_dealloc */
4077 0, /* tp_print */
4078 0, /* tp_getattr */
4079 0, /* tp_setattr */
4080 0, /* tp_reserved */
4081 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004082 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004083 0, /* tp_as_sequence */
4084 0, /* tp_as_mapping */
4085 (hashfunc)time_hash, /* tp_hash */
4086 0, /* tp_call */
4087 (reprfunc)time_str, /* tp_str */
4088 PyObject_GenericGetAttr, /* tp_getattro */
4089 0, /* tp_setattro */
4090 0, /* tp_as_buffer */
4091 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4092 time_doc, /* tp_doc */
4093 0, /* tp_traverse */
4094 0, /* tp_clear */
4095 time_richcompare, /* tp_richcompare */
4096 0, /* tp_weaklistoffset */
4097 0, /* tp_iter */
4098 0, /* tp_iternext */
4099 time_methods, /* tp_methods */
4100 0, /* tp_members */
4101 time_getset, /* tp_getset */
4102 0, /* tp_base */
4103 0, /* tp_dict */
4104 0, /* tp_descr_get */
4105 0, /* tp_descr_set */
4106 0, /* tp_dictoffset */
4107 0, /* tp_init */
4108 time_alloc, /* tp_alloc */
4109 time_new, /* tp_new */
4110 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004111};
4112
4113/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004114 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004115 */
4116
Tim Petersa9bc1682003-01-11 03:39:11 +00004117/* Accessor properties. Properties for day, month, and year are inherited
4118 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004119 */
4120
4121static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004122datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004123{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004124 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004125}
4126
Tim Petersa9bc1682003-01-11 03:39:11 +00004127static PyObject *
4128datetime_minute(PyDateTime_DateTime *self, void *unused)
4129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004131}
4132
4133static PyObject *
4134datetime_second(PyDateTime_DateTime *self, void *unused)
4135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004136 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004137}
4138
4139static PyObject *
4140datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004142 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004143}
4144
4145static PyObject *
4146datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004148 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4149 Py_INCREF(result);
4150 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004151}
4152
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004153static PyObject *
4154datetime_fold(PyDateTime_DateTime *self, void *unused)
4155{
4156 return PyLong_FromLong(DATE_GET_FOLD(self));
4157}
4158
Tim Petersa9bc1682003-01-11 03:39:11 +00004159static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004160 {"hour", (getter)datetime_hour},
4161 {"minute", (getter)datetime_minute},
4162 {"second", (getter)datetime_second},
4163 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004164 {"tzinfo", (getter)datetime_tzinfo},
4165 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004166 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004167};
4168
4169/*
4170 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004171 */
4172
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004173static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004174 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004175 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004176};
4177
Tim Peters2a799bf2002-12-16 20:18:38 +00004178static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004179datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004181 PyObject *self = NULL;
4182 PyObject *state;
4183 int year;
4184 int month;
4185 int day;
4186 int hour = 0;
4187 int minute = 0;
4188 int second = 0;
4189 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004190 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 /* Check for invocation from pickle with __getstate__ state */
4194 if (PyTuple_GET_SIZE(args) >= 1 &&
4195 PyTuple_GET_SIZE(args) <= 2 &&
4196 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4197 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004198 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004199 {
4200 PyDateTime_DateTime *me;
4201 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004203 if (PyTuple_GET_SIZE(args) == 2) {
4204 tzinfo = PyTuple_GET_ITEM(args, 1);
4205 if (check_tzinfo_subclass(tzinfo) < 0) {
4206 PyErr_SetString(PyExc_TypeError, "bad "
4207 "tzinfo state arg");
4208 return NULL;
4209 }
4210 }
4211 aware = (char)(tzinfo != Py_None);
4212 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4213 if (me != NULL) {
4214 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004216 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4217 me->hashcode = -1;
4218 me->hastzinfo = aware;
4219 if (aware) {
4220 Py_INCREF(tzinfo);
4221 me->tzinfo = tzinfo;
4222 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004223 if (pdata[2] & (1 << 7)) {
4224 me->data[2] -= 128;
4225 me->fold = 1;
4226 }
4227 else {
4228 me->fold = 0;
4229 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004230 }
4231 return (PyObject *)me;
4232 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004233
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004234 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004235 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004236 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004237 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004238 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004239 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004240 }
4241 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004242}
4243
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004244/* TM_FUNC is the shared type of _PyTime_localtime() and
4245 * _PyTime_gmtime(). */
4246typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004247
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004248/* As of version 2015f max fold in IANA database is
4249 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004250static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004251/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004252static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004253
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004254static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004255utc_to_seconds(int year, int month, int day,
4256 int hour, int minute, int second)
4257{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004258 long long ordinal;
4259
4260 /* ymd_to_ord() doesn't support year <= 0 */
4261 if (year < MINYEAR || year > MAXYEAR) {
4262 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4263 return -1;
4264 }
4265
4266 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004267 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4268}
4269
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004270static long long
4271local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004272{
4273 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004274 time_t t;
4275 u -= epoch;
4276 t = u;
4277 if (t != u) {
4278 PyErr_SetString(PyExc_OverflowError,
4279 "timestamp out of range for platform time_t");
4280 return -1;
4281 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004282 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004283 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004284 return utc_to_seconds(local_time.tm_year + 1900,
4285 local_time.tm_mon + 1,
4286 local_time.tm_mday,
4287 local_time.tm_hour,
4288 local_time.tm_min,
4289 local_time.tm_sec);
4290}
4291
Tim Petersa9bc1682003-01-11 03:39:11 +00004292/* Internal helper.
4293 * Build datetime from a time_t and a distinct count of microseconds.
4294 * Pass localtime or gmtime for f, to control the interpretation of timet.
4295 */
4296static PyObject *
4297datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004298 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004299{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004300 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004301 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004302
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004303 if (f(timet, &tm) != 0)
4304 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004305
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004306 year = tm.tm_year + 1900;
4307 month = tm.tm_mon + 1;
4308 day = tm.tm_mday;
4309 hour = tm.tm_hour;
4310 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004311 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004312 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004313 * except to the extent that passing them on to the datetime
4314 * constructor would raise ValueError for a reason that
4315 * made no sense to the user.
4316 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004317 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004318
Victor Stinnerb67f0962017-02-10 10:34:02 +01004319 /* local timezone requires to compute fold */
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004320 if (tzinfo == Py_None && f == _PyTime_localtime) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004321 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004322
4323 result_seconds = utc_to_seconds(year, month, day,
4324 hour, minute, second);
4325 /* Probe max_fold_seconds to detect a fold. */
4326 probe_seconds = local(epoch + timet - max_fold_seconds);
4327 if (probe_seconds == -1)
4328 return NULL;
4329 transition = result_seconds - probe_seconds - max_fold_seconds;
4330 if (transition < 0) {
4331 probe_seconds = local(epoch + timet + transition);
4332 if (probe_seconds == -1)
4333 return NULL;
4334 if (probe_seconds == result_seconds)
4335 fold = 1;
4336 }
4337 }
4338 return new_datetime_ex2(year, month, day, hour,
4339 minute, second, us, tzinfo, fold,
4340 (PyTypeObject *)cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004341}
4342
4343/* Internal helper.
4344 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4345 * to control the interpretation of the timestamp. Since a double doesn't
4346 * have enough bits to cover a datetime's full range of precision, it's
4347 * better to call datetime_from_timet_and_us provided you have a way
4348 * to get that much precision (e.g., C time() isn't good enough).
4349 */
4350static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004351datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004352 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004354 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004355 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004356
Victor Stinnere4a994d2015-03-30 01:10:14 +02004357 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004358 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004359 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004360
Victor Stinner21f58932012-03-14 00:15:40 +01004361 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004362}
4363
4364/* Internal helper.
4365 * Build most accurate possible datetime for current time. Pass localtime or
4366 * gmtime for f as appropriate.
4367 */
4368static PyObject *
4369datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4370{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004371 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004372 time_t secs;
4373 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004374
Victor Stinner1e2b6882015-09-18 13:23:02 +02004375 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004376 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004377 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004378
Victor Stinner1e2b6882015-09-18 13:23:02 +02004379 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004380}
4381
Larry Hastings61272b72014-01-07 12:41:53 -08004382/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004383
4384@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004385datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004386
4387 tz: object = None
4388 Timezone object.
4389
4390Returns new datetime object representing current time local to tz.
4391
4392If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004393[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004394
Larry Hastings31826802013-10-19 00:09:25 -07004395static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004396datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004397/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004399 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004400
Larry Hastings31826802013-10-19 00:09:25 -07004401 /* Return best possible local time -- this isn't constrained by the
4402 * precision of a timestamp.
4403 */
4404 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004405 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004406
Larry Hastings5c661892014-01-24 06:17:25 -08004407 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004408 tz == Py_None ? _PyTime_localtime :
4409 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004410 tz);
4411 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004412 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004413 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004414 }
4415 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004416}
4417
Tim Petersa9bc1682003-01-11 03:39:11 +00004418/* Return best possible UTC time -- this isn't constrained by the
4419 * precision of a timestamp.
4420 */
4421static PyObject *
4422datetime_utcnow(PyObject *cls, PyObject *dummy)
4423{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004424 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004425}
4426
Tim Peters2a799bf2002-12-16 20:18:38 +00004427/* Return new local datetime from timestamp (Python timestamp -- a double). */
4428static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004429datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004430{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004431 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004432 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004433 PyObject *tzinfo = Py_None;
4434 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004435
Victor Stinner5d272cc2012-03-13 13:35:55 +01004436 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004437 keywords, &timestamp, &tzinfo))
4438 return NULL;
4439 if (check_tzinfo_subclass(tzinfo) < 0)
4440 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004442 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004443 tzinfo == Py_None ? _PyTime_localtime :
4444 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004445 timestamp,
4446 tzinfo);
4447 if (self != NULL && tzinfo != Py_None) {
4448 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004449 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004450 }
4451 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004452}
4453
Tim Petersa9bc1682003-01-11 03:39:11 +00004454/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4455static PyObject *
4456datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4457{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004458 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004459 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004460
Victor Stinner5d272cc2012-03-13 13:35:55 +01004461 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004462 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004463 Py_None);
4464 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004465}
4466
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004467/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004468static PyObject *
4469datetime_strptime(PyObject *cls, PyObject *args)
4470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004471 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004472 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004473 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004474
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004475 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004476 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004477
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004478 if (module == NULL) {
4479 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004480 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004481 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004482 }
Victor Stinner20401de2016-12-09 15:24:31 +01004483 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4484 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004485}
4486
Tim Petersa9bc1682003-01-11 03:39:11 +00004487/* Return new datetime from date/datetime and time arguments. */
4488static PyObject *
4489datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4490{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004491 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004492 PyObject *date;
4493 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004494 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004495 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004496
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004497 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004498 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004499 &PyDateTime_TimeType, &time, &tzinfo)) {
4500 if (tzinfo == NULL) {
4501 if (HASTZINFO(time))
4502 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4503 else
4504 tzinfo = Py_None;
4505 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004506 result = PyObject_CallFunction(cls, "iiiiiiiO",
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004507 GET_YEAR(date),
4508 GET_MONTH(date),
4509 GET_DAY(date),
4510 TIME_GET_HOUR(time),
4511 TIME_GET_MINUTE(time),
4512 TIME_GET_SECOND(time),
4513 TIME_GET_MICROSECOND(time),
4514 tzinfo);
4515 if (result)
4516 DATE_SET_FOLD(result, TIME_GET_FOLD(time));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004517 }
4518 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004519}
Tim Peters2a799bf2002-12-16 20:18:38 +00004520
4521/*
4522 * Destructor.
4523 */
4524
4525static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004526datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004528 if (HASTZINFO(self)) {
4529 Py_XDECREF(self->tzinfo);
4530 }
4531 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004532}
4533
4534/*
4535 * Indirect access to tzinfo methods.
4536 */
4537
Tim Peters2a799bf2002-12-16 20:18:38 +00004538/* These are all METH_NOARGS, so don't need to check the arglist. */
4539static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004540datetime_utcoffset(PyObject *self, PyObject *unused) {
4541 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004542}
4543
4544static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004545datetime_dst(PyObject *self, PyObject *unused) {
4546 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004547}
4548
4549static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004550datetime_tzname(PyObject *self, PyObject *unused) {
4551 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004552}
4553
4554/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004555 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004556 */
4557
Tim Petersa9bc1682003-01-11 03:39:11 +00004558/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4559 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004560 */
4561static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004562add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004563 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004564{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004565 /* Note that the C-level additions can't overflow, because of
4566 * invariant bounds on the member values.
4567 */
4568 int year = GET_YEAR(date);
4569 int month = GET_MONTH(date);
4570 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4571 int hour = DATE_GET_HOUR(date);
4572 int minute = DATE_GET_MINUTE(date);
4573 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4574 int microsecond = DATE_GET_MICROSECOND(date) +
4575 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004577 assert(factor == 1 || factor == -1);
4578 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01004579 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004580 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01004581 }
4582
4583 return new_datetime(year, month, day,
4584 hour, minute, second, microsecond,
4585 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004586}
4587
4588static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004589datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004590{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004591 if (PyDateTime_Check(left)) {
4592 /* datetime + ??? */
4593 if (PyDelta_Check(right))
4594 /* datetime + delta */
4595 return add_datetime_timedelta(
4596 (PyDateTime_DateTime *)left,
4597 (PyDateTime_Delta *)right,
4598 1);
4599 }
4600 else if (PyDelta_Check(left)) {
4601 /* delta + datetime */
4602 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4603 (PyDateTime_Delta *) left,
4604 1);
4605 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004606 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004607}
4608
4609static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004610datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004612 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004614 if (PyDateTime_Check(left)) {
4615 /* datetime - ??? */
4616 if (PyDateTime_Check(right)) {
4617 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004618 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004619 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004620
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004621 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4622 offset2 = offset1 = Py_None;
4623 Py_INCREF(offset1);
4624 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004625 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004626 else {
4627 offset1 = datetime_utcoffset(left, NULL);
4628 if (offset1 == NULL)
4629 return NULL;
4630 offset2 = datetime_utcoffset(right, NULL);
4631 if (offset2 == NULL) {
4632 Py_DECREF(offset1);
4633 return NULL;
4634 }
4635 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4636 PyErr_SetString(PyExc_TypeError,
4637 "can't subtract offset-naive and "
4638 "offset-aware datetimes");
4639 Py_DECREF(offset1);
4640 Py_DECREF(offset2);
4641 return NULL;
4642 }
4643 }
4644 if ((offset1 != offset2) &&
4645 delta_cmp(offset1, offset2) != 0) {
4646 offdiff = delta_subtract(offset1, offset2);
4647 if (offdiff == NULL) {
4648 Py_DECREF(offset1);
4649 Py_DECREF(offset2);
4650 return NULL;
4651 }
4652 }
4653 Py_DECREF(offset1);
4654 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004655 delta_d = ymd_to_ord(GET_YEAR(left),
4656 GET_MONTH(left),
4657 GET_DAY(left)) -
4658 ymd_to_ord(GET_YEAR(right),
4659 GET_MONTH(right),
4660 GET_DAY(right));
4661 /* These can't overflow, since the values are
4662 * normalized. At most this gives the number of
4663 * seconds in one day.
4664 */
4665 delta_s = (DATE_GET_HOUR(left) -
4666 DATE_GET_HOUR(right)) * 3600 +
4667 (DATE_GET_MINUTE(left) -
4668 DATE_GET_MINUTE(right)) * 60 +
4669 (DATE_GET_SECOND(left) -
4670 DATE_GET_SECOND(right));
4671 delta_us = DATE_GET_MICROSECOND(left) -
4672 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004673 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004674 if (result == NULL)
4675 return NULL;
4676
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004677 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004678 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004679 Py_DECREF(offdiff);
4680 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 }
4682 else if (PyDelta_Check(right)) {
4683 /* datetime - delta */
4684 result = add_datetime_timedelta(
4685 (PyDateTime_DateTime *)left,
4686 (PyDateTime_Delta *)right,
4687 -1);
4688 }
4689 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004691 if (result == Py_NotImplemented)
4692 Py_INCREF(result);
4693 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004694}
4695
4696/* Various ways to turn a datetime into a string. */
4697
4698static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004699datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004700{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004701 const char *type_name = Py_TYPE(self)->tp_name;
4702 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004704 if (DATE_GET_MICROSECOND(self)) {
4705 baserepr = PyUnicode_FromFormat(
4706 "%s(%d, %d, %d, %d, %d, %d, %d)",
4707 type_name,
4708 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4709 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4710 DATE_GET_SECOND(self),
4711 DATE_GET_MICROSECOND(self));
4712 }
4713 else if (DATE_GET_SECOND(self)) {
4714 baserepr = PyUnicode_FromFormat(
4715 "%s(%d, %d, %d, %d, %d, %d)",
4716 type_name,
4717 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4718 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4719 DATE_GET_SECOND(self));
4720 }
4721 else {
4722 baserepr = PyUnicode_FromFormat(
4723 "%s(%d, %d, %d, %d, %d)",
4724 type_name,
4725 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4726 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4727 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004728 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4729 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004730 if (baserepr == NULL || ! HASTZINFO(self))
4731 return baserepr;
4732 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004733}
4734
Tim Petersa9bc1682003-01-11 03:39:11 +00004735static PyObject *
4736datetime_str(PyDateTime_DateTime *self)
4737{
Victor Stinner4c381542016-12-09 00:33:39 +01004738 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004739}
Tim Peters2a799bf2002-12-16 20:18:38 +00004740
4741static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004742datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004743{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004744 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004745 char *timespec = NULL;
4746 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004747 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004748 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004749 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004750 static char *specs[][2] = {
4751 {"hours", "%04d-%02d-%02d%c%02d"},
4752 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4753 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4754 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4755 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4756 };
4757 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004758
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004759 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004760 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004761
4762 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4763 if (us == 0) {
4764 /* seconds */
4765 given_spec = 2;
4766 }
4767 else {
4768 /* microseconds */
4769 given_spec = 4;
4770 }
4771 }
4772 else {
4773 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4774 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4775 if (given_spec == 3) {
4776 us = us / 1000;
4777 }
4778 break;
4779 }
4780 }
4781 }
4782
4783 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4784 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4785 return NULL;
4786 }
4787 else {
4788 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004789 GET_YEAR(self), GET_MONTH(self),
4790 GET_DAY(self), (int)sep,
4791 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4792 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004793 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004795 if (!result || !HASTZINFO(self))
4796 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004798 /* We need to append the UTC offset. */
4799 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4800 (PyObject *)self) < 0) {
4801 Py_DECREF(result);
4802 return NULL;
4803 }
4804 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4805 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004806}
4807
Tim Petersa9bc1682003-01-11 03:39:11 +00004808static PyObject *
4809datetime_ctime(PyDateTime_DateTime *self)
4810{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004811 return format_ctime((PyDateTime_Date *)self,
4812 DATE_GET_HOUR(self),
4813 DATE_GET_MINUTE(self),
4814 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004815}
4816
Tim Peters2a799bf2002-12-16 20:18:38 +00004817/* Miscellaneous methods. */
4818
Tim Petersa9bc1682003-01-11 03:39:11 +00004819static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004820flip_fold(PyObject *dt)
4821{
4822 return new_datetime_ex2(GET_YEAR(dt),
4823 GET_MONTH(dt),
4824 GET_DAY(dt),
4825 DATE_GET_HOUR(dt),
4826 DATE_GET_MINUTE(dt),
4827 DATE_GET_SECOND(dt),
4828 DATE_GET_MICROSECOND(dt),
4829 HASTZINFO(dt) ?
4830 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4831 !DATE_GET_FOLD(dt),
4832 Py_TYPE(dt));
4833}
4834
4835static PyObject *
4836get_flip_fold_offset(PyObject *dt)
4837{
4838 PyObject *result, *flip_dt;
4839
4840 flip_dt = flip_fold(dt);
4841 if (flip_dt == NULL)
4842 return NULL;
4843 result = datetime_utcoffset(flip_dt, NULL);
4844 Py_DECREF(flip_dt);
4845 return result;
4846}
4847
4848/* PEP 495 exception: Whenever one or both of the operands in
4849 * inter-zone comparison is such that its utcoffset() depends
4850 * on the value of its fold fold attribute, the result is False.
4851 *
4852 * Return 1 if exception applies, 0 if not, and -1 on error.
4853 */
4854static int
4855pep495_eq_exception(PyObject *self, PyObject *other,
4856 PyObject *offset_self, PyObject *offset_other)
4857{
4858 int result = 0;
4859 PyObject *flip_offset;
4860
4861 flip_offset = get_flip_fold_offset(self);
4862 if (flip_offset == NULL)
4863 return -1;
4864 if (flip_offset != offset_self &&
4865 delta_cmp(flip_offset, offset_self))
4866 {
4867 result = 1;
4868 goto done;
4869 }
4870 Py_DECREF(flip_offset);
4871
4872 flip_offset = get_flip_fold_offset(other);
4873 if (flip_offset == NULL)
4874 return -1;
4875 if (flip_offset != offset_other &&
4876 delta_cmp(flip_offset, offset_other))
4877 result = 1;
4878 done:
4879 Py_DECREF(flip_offset);
4880 return result;
4881}
4882
4883static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004884datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004885{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004886 PyObject *result = NULL;
4887 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004888 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 if (! PyDateTime_Check(other)) {
4891 if (PyDate_Check(other)) {
4892 /* Prevent invocation of date_richcompare. We want to
4893 return NotImplemented here to give the other object
4894 a chance. But since DateTime is a subclass of
4895 Date, if the other object is a Date, it would
4896 compute an ordering based on the date part alone,
4897 and we don't want that. So force unequal or
4898 uncomparable here in that case. */
4899 if (op == Py_EQ)
4900 Py_RETURN_FALSE;
4901 if (op == Py_NE)
4902 Py_RETURN_TRUE;
4903 return cmperror(self, other);
4904 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004905 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004906 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004907
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004908 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004909 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4910 ((PyDateTime_DateTime *)other)->data,
4911 _PyDateTime_DATETIME_DATASIZE);
4912 return diff_to_bool(diff, op);
4913 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004914 offset1 = datetime_utcoffset(self, NULL);
4915 if (offset1 == NULL)
4916 return NULL;
4917 offset2 = datetime_utcoffset(other, NULL);
4918 if (offset2 == NULL)
4919 goto done;
4920 /* If they're both naive, or both aware and have the same offsets,
4921 * we get off cheap. Note that if they're both naive, offset1 ==
4922 * offset2 == Py_None at this point.
4923 */
4924 if ((offset1 == offset2) ||
4925 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4926 delta_cmp(offset1, offset2) == 0)) {
4927 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4928 ((PyDateTime_DateTime *)other)->data,
4929 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004930 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4931 int ex = pep495_eq_exception(self, other, offset1, offset2);
4932 if (ex == -1)
4933 goto done;
4934 if (ex)
4935 diff = 1;
4936 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004937 result = diff_to_bool(diff, op);
4938 }
4939 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004940 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004941
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004942 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004943 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4944 other);
4945 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004946 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004947 diff = GET_TD_DAYS(delta);
4948 if (diff == 0)
4949 diff = GET_TD_SECONDS(delta) |
4950 GET_TD_MICROSECONDS(delta);
4951 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004952 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4953 int ex = pep495_eq_exception(self, other, offset1, offset2);
4954 if (ex == -1)
4955 goto done;
4956 if (ex)
4957 diff = 1;
4958 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004959 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004960 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004961 else if (op == Py_EQ) {
4962 result = Py_False;
4963 Py_INCREF(result);
4964 }
4965 else if (op == Py_NE) {
4966 result = Py_True;
4967 Py_INCREF(result);
4968 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004969 else {
4970 PyErr_SetString(PyExc_TypeError,
4971 "can't compare offset-naive and "
4972 "offset-aware datetimes");
4973 }
4974 done:
4975 Py_DECREF(offset1);
4976 Py_XDECREF(offset2);
4977 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004978}
4979
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004980static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004981datetime_hash(PyDateTime_DateTime *self)
4982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004983 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004984 PyObject *offset, *self0;
4985 if (DATE_GET_FOLD(self)) {
4986 self0 = new_datetime_ex2(GET_YEAR(self),
4987 GET_MONTH(self),
4988 GET_DAY(self),
4989 DATE_GET_HOUR(self),
4990 DATE_GET_MINUTE(self),
4991 DATE_GET_SECOND(self),
4992 DATE_GET_MICROSECOND(self),
4993 HASTZINFO(self) ? self->tzinfo : Py_None,
4994 0, Py_TYPE(self));
4995 if (self0 == NULL)
4996 return -1;
4997 }
4998 else {
4999 self0 = (PyObject *)self;
5000 Py_INCREF(self0);
5001 }
5002 offset = datetime_utcoffset(self0, NULL);
5003 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005004
5005 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005006 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005008 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005009 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005010 self->hashcode = generic_hash(
5011 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005012 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005013 PyObject *temp1, *temp2;
5014 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005016 assert(HASTZINFO(self));
5017 days = ymd_to_ord(GET_YEAR(self),
5018 GET_MONTH(self),
5019 GET_DAY(self));
5020 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005021 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005022 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005023 temp1 = new_delta(days, seconds,
5024 DATE_GET_MICROSECOND(self),
5025 1);
5026 if (temp1 == NULL) {
5027 Py_DECREF(offset);
5028 return -1;
5029 }
5030 temp2 = delta_subtract(temp1, offset);
5031 Py_DECREF(temp1);
5032 if (temp2 == NULL) {
5033 Py_DECREF(offset);
5034 return -1;
5035 }
5036 self->hashcode = PyObject_Hash(temp2);
5037 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005038 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005039 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005040 }
5041 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005042}
Tim Peters2a799bf2002-12-16 20:18:38 +00005043
5044static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005045datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005046{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005047 PyObject *clone;
5048 PyObject *tuple;
5049 int y = GET_YEAR(self);
5050 int m = GET_MONTH(self);
5051 int d = GET_DAY(self);
5052 int hh = DATE_GET_HOUR(self);
5053 int mm = DATE_GET_MINUTE(self);
5054 int ss = DATE_GET_SECOND(self);
5055 int us = DATE_GET_MICROSECOND(self);
5056 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005057 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005058
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005059 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005060 datetime_kws,
5061 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005062 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005063 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005064 if (fold != 0 && fold != 1) {
5065 PyErr_SetString(PyExc_ValueError,
5066 "fold must be either 0 or 1");
5067 return NULL;
5068 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005069 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5070 if (tuple == NULL)
5071 return NULL;
5072 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005073 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005074 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005075 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005076 Py_DECREF(tuple);
5077 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005078}
5079
5080static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005081local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005082{
5083 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005084 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005085 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005086 PyObject *nameo = NULL;
5087 const char *zone = NULL;
5088
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005089 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005090 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005091#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005092 zone = local_time_tm.tm_zone;
5093 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005094#else /* HAVE_STRUCT_TM_TM_ZONE */
5095 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005096 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005097 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005098 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005099 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005100 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005101 local_time = new_datetime(local_time_tm.tm_year + 1900,
5102 local_time_tm.tm_mon + 1,
5103 local_time_tm.tm_mday,
5104 local_time_tm.tm_hour,
5105 local_time_tm.tm_min,
5106 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005107 if (local_time == NULL) {
5108 return NULL;
5109 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005110 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005111 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005112 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5113 utc_time_tm.tm_mon + 1,
5114 utc_time_tm.tm_mday,
5115 utc_time_tm.tm_hour,
5116 utc_time_tm.tm_min,
5117 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005118 if (utc_time == NULL) {
5119 Py_DECREF(local_time);
5120 return NULL;
5121 }
5122 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005123 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005124 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005125 }
5126#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005127 if (delta == NULL) {
5128 return NULL;
5129 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005130 if (zone != NULL) {
5131 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5132 if (nameo == NULL)
5133 goto error;
5134 }
5135 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005136 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005137 error:
5138 Py_DECREF(delta);
5139 return result;
5140}
5141
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005142static PyObject *
5143local_timezone(PyDateTime_DateTime *utc_time)
5144{
5145 time_t timestamp;
5146 PyObject *delta;
5147 PyObject *one_second;
5148 PyObject *seconds;
5149
5150 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5151 if (delta == NULL)
5152 return NULL;
5153 one_second = new_delta(0, 1, 0, 0);
5154 if (one_second == NULL) {
5155 Py_DECREF(delta);
5156 return NULL;
5157 }
5158 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5159 (PyDateTime_Delta *)one_second);
5160 Py_DECREF(one_second);
5161 Py_DECREF(delta);
5162 if (seconds == NULL)
5163 return NULL;
5164 timestamp = _PyLong_AsTime_t(seconds);
5165 Py_DECREF(seconds);
5166 if (timestamp == -1 && PyErr_Occurred())
5167 return NULL;
5168 return local_timezone_from_timestamp(timestamp);
5169}
5170
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005171static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005172local_to_seconds(int year, int month, int day,
5173 int hour, int minute, int second, int fold);
5174
5175static PyObject *
5176local_timezone_from_local(PyDateTime_DateTime *local_dt)
5177{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005178 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005179 time_t timestamp;
5180 seconds = local_to_seconds(GET_YEAR(local_dt),
5181 GET_MONTH(local_dt),
5182 GET_DAY(local_dt),
5183 DATE_GET_HOUR(local_dt),
5184 DATE_GET_MINUTE(local_dt),
5185 DATE_GET_SECOND(local_dt),
5186 DATE_GET_FOLD(local_dt));
5187 if (seconds == -1)
5188 return NULL;
5189 /* XXX: add bounds check */
5190 timestamp = seconds - epoch;
5191 return local_timezone_from_timestamp(timestamp);
5192}
5193
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005194static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005195datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005196{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005197 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005198 PyObject *offset;
5199 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005200 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005201 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005202 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005203
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005204 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005205 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005206 return NULL;
5207
5208 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005209 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005210
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005211 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5212 self_tzinfo = local_timezone_from_local(self);
5213 if (self_tzinfo == NULL)
5214 return NULL;
5215 } else {
5216 self_tzinfo = self->tzinfo;
5217 Py_INCREF(self_tzinfo);
5218 }
Tim Peters521fc152002-12-31 17:36:56 +00005219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005220 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005221 if (self_tzinfo == tzinfo) {
5222 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005223 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005224 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005225 }
Tim Peters521fc152002-12-31 17:36:56 +00005226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005227 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005228 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5229 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005230 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005231 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005232 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005233 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5234 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005235 Py_DECREF(offset);
5236 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005237 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005238
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005239 /* Make sure result is aware and UTC. */
5240 if (!HASTZINFO(result)) {
5241 temp = (PyObject *)result;
5242 result = (PyDateTime_DateTime *)
5243 new_datetime_ex2(GET_YEAR(result),
5244 GET_MONTH(result),
5245 GET_DAY(result),
5246 DATE_GET_HOUR(result),
5247 DATE_GET_MINUTE(result),
5248 DATE_GET_SECOND(result),
5249 DATE_GET_MICROSECOND(result),
5250 PyDateTime_TimeZone_UTC,
5251 DATE_GET_FOLD(result),
5252 Py_TYPE(result));
5253 Py_DECREF(temp);
5254 if (result == NULL)
5255 return NULL;
5256 }
5257 else {
5258 /* Result is already aware - just replace tzinfo. */
5259 temp = result->tzinfo;
5260 result->tzinfo = PyDateTime_TimeZone_UTC;
5261 Py_INCREF(result->tzinfo);
5262 Py_DECREF(temp);
5263 }
5264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005265 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005266 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005267 if (tzinfo == Py_None) {
5268 tzinfo = local_timezone(result);
5269 if (tzinfo == NULL) {
5270 Py_DECREF(result);
5271 return NULL;
5272 }
5273 }
5274 else
5275 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005276 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005277 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005278
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005279 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005280 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005281 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005282 Py_DECREF(temp);
5283
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005284 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005285}
5286
5287static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005288datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005290 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005292 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005293 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005294
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005295 dst = call_dst(self->tzinfo, (PyObject *)self);
5296 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005297 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005298
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005299 if (dst != Py_None)
5300 dstflag = delta_bool((PyDateTime_Delta *)dst);
5301 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005302 }
5303 return build_struct_time(GET_YEAR(self),
5304 GET_MONTH(self),
5305 GET_DAY(self),
5306 DATE_GET_HOUR(self),
5307 DATE_GET_MINUTE(self),
5308 DATE_GET_SECOND(self),
5309 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005310}
5311
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005312static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005313local_to_seconds(int year, int month, int day,
5314 int hour, int minute, int second, int fold)
5315{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005316 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005317 t = utc_to_seconds(year, month, day, hour, minute, second);
5318 /* Our goal is to solve t = local(u) for u. */
5319 lt = local(t);
5320 if (lt == -1)
5321 return -1;
5322 a = lt - t;
5323 u1 = t - a;
5324 t1 = local(u1);
5325 if (t1 == -1)
5326 return -1;
5327 if (t1 == t) {
5328 /* We found one solution, but it may not be the one we need.
5329 * Look for an earlier solution (if `fold` is 0), or a
5330 * later one (if `fold` is 1). */
5331 if (fold)
5332 u2 = u1 + max_fold_seconds;
5333 else
5334 u2 = u1 - max_fold_seconds;
5335 lt = local(u2);
5336 if (lt == -1)
5337 return -1;
5338 b = lt - u2;
5339 if (a == b)
5340 return u1;
5341 }
5342 else {
5343 b = t1 - u1;
5344 assert(a != b);
5345 }
5346 u2 = t - b;
5347 t2 = local(u2);
5348 if (t2 == -1)
5349 return -1;
5350 if (t2 == t)
5351 return u2;
5352 if (t1 == t)
5353 return u1;
5354 /* We have found both offsets a and b, but neither t - a nor t - b is
5355 * a solution. This means t is in the gap. */
5356 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5357}
5358
5359/* date(1970,1,1).toordinal() == 719163 */
5360#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5361
Tim Peters2a799bf2002-12-16 20:18:38 +00005362static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005363datetime_timestamp(PyDateTime_DateTime *self)
5364{
5365 PyObject *result;
5366
5367 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5368 PyObject *delta;
5369 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5370 if (delta == NULL)
5371 return NULL;
5372 result = delta_total_seconds(delta);
5373 Py_DECREF(delta);
5374 }
5375 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005376 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005377 seconds = local_to_seconds(GET_YEAR(self),
5378 GET_MONTH(self),
5379 GET_DAY(self),
5380 DATE_GET_HOUR(self),
5381 DATE_GET_MINUTE(self),
5382 DATE_GET_SECOND(self),
5383 DATE_GET_FOLD(self));
5384 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005385 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005386 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5387 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005388 }
5389 return result;
5390}
5391
5392static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005393datetime_getdate(PyDateTime_DateTime *self)
5394{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005395 return new_date(GET_YEAR(self),
5396 GET_MONTH(self),
5397 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005398}
5399
5400static PyObject *
5401datetime_gettime(PyDateTime_DateTime *self)
5402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005403 return new_time(DATE_GET_HOUR(self),
5404 DATE_GET_MINUTE(self),
5405 DATE_GET_SECOND(self),
5406 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005407 Py_None,
5408 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005409}
5410
5411static PyObject *
5412datetime_gettimetz(PyDateTime_DateTime *self)
5413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005414 return new_time(DATE_GET_HOUR(self),
5415 DATE_GET_MINUTE(self),
5416 DATE_GET_SECOND(self),
5417 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005418 GET_DT_TZINFO(self),
5419 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005420}
5421
5422static PyObject *
5423datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005424{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005425 int y, m, d, hh, mm, ss;
5426 PyObject *tzinfo;
5427 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005428
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005429 tzinfo = GET_DT_TZINFO(self);
5430 if (tzinfo == Py_None) {
5431 utcself = self;
5432 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005433 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005434 else {
5435 PyObject *offset;
5436 offset = call_utcoffset(tzinfo, (PyObject *)self);
5437 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005438 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005439 if (offset == Py_None) {
5440 Py_DECREF(offset);
5441 utcself = self;
5442 Py_INCREF(utcself);
5443 }
5444 else {
5445 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5446 (PyDateTime_Delta *)offset, -1);
5447 Py_DECREF(offset);
5448 if (utcself == NULL)
5449 return NULL;
5450 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005451 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005452 y = GET_YEAR(utcself);
5453 m = GET_MONTH(utcself);
5454 d = GET_DAY(utcself);
5455 hh = DATE_GET_HOUR(utcself);
5456 mm = DATE_GET_MINUTE(utcself);
5457 ss = DATE_GET_SECOND(utcself);
5458
5459 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005460 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005461}
5462
Tim Peters371935f2003-02-01 01:52:50 +00005463/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005464
Tim Petersa9bc1682003-01-11 03:39:11 +00005465/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005466 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5467 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005468 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005469 */
5470static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005471datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005472{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005473 PyObject *basestate;
5474 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005476 basestate = PyBytes_FromStringAndSize((char *)self->data,
5477 _PyDateTime_DATETIME_DATASIZE);
5478 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005479 if (proto > 3 && DATE_GET_FOLD(self))
5480 /* Set the first bit of the third byte */
5481 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005482 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5483 result = PyTuple_Pack(1, basestate);
5484 else
5485 result = PyTuple_Pack(2, basestate, self->tzinfo);
5486 Py_DECREF(basestate);
5487 }
5488 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005489}
5490
5491static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005492datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005493{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005494 int proto;
5495 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005496 return NULL;
5497
5498 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005499}
5500
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005501static PyObject *
5502datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5503{
5504 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5505}
5506
Tim Petersa9bc1682003-01-11 03:39:11 +00005507static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005509 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005510
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005511 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005513 {"utcnow", (PyCFunction)datetime_utcnow,
5514 METH_NOARGS | METH_CLASS,
5515 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005517 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5518 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5519 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005521 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5522 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005523 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005525 {"strptime", (PyCFunction)datetime_strptime,
5526 METH_VARARGS | METH_CLASS,
5527 PyDoc_STR("string, format -> new datetime parsed from a string "
5528 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005530 {"combine", (PyCFunction)datetime_combine,
5531 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5532 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005534 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005536 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5537 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005539 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5540 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005542 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5543 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005545 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5546 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005548 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5549 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005550
Alexander Belopolskya4415142012-06-08 12:33:09 -04005551 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5552 PyDoc_STR("Return POSIX timestamp as float.")},
5553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005554 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5555 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005557 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5558 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005559 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005560 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005561 "defaults to 'T'.\n"
5562 "timespec specifies what components of the time to include"
5563 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5564 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005566 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5567 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005569 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5570 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005572 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5573 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005575 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5576 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005578 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5579 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005580
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005581 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005582 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005583
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005584 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5585 PyDoc_STR("__reduce__() -> (cls, state)")},
5586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005587 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005588};
5589
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005590static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005591PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5592\n\
5593The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005594instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005595
Tim Petersa9bc1682003-01-11 03:39:11 +00005596static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005597 datetime_add, /* nb_add */
5598 datetime_subtract, /* nb_subtract */
5599 0, /* nb_multiply */
5600 0, /* nb_remainder */
5601 0, /* nb_divmod */
5602 0, /* nb_power */
5603 0, /* nb_negative */
5604 0, /* nb_positive */
5605 0, /* nb_absolute */
5606 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005607};
5608
Neal Norwitz227b5332006-03-22 09:28:35 +00005609static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005610 PyVarObject_HEAD_INIT(NULL, 0)
5611 "datetime.datetime", /* tp_name */
5612 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5613 0, /* tp_itemsize */
5614 (destructor)datetime_dealloc, /* tp_dealloc */
5615 0, /* tp_print */
5616 0, /* tp_getattr */
5617 0, /* tp_setattr */
5618 0, /* tp_reserved */
5619 (reprfunc)datetime_repr, /* tp_repr */
5620 &datetime_as_number, /* tp_as_number */
5621 0, /* tp_as_sequence */
5622 0, /* tp_as_mapping */
5623 (hashfunc)datetime_hash, /* tp_hash */
5624 0, /* tp_call */
5625 (reprfunc)datetime_str, /* tp_str */
5626 PyObject_GenericGetAttr, /* tp_getattro */
5627 0, /* tp_setattro */
5628 0, /* tp_as_buffer */
5629 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5630 datetime_doc, /* tp_doc */
5631 0, /* tp_traverse */
5632 0, /* tp_clear */
5633 datetime_richcompare, /* tp_richcompare */
5634 0, /* tp_weaklistoffset */
5635 0, /* tp_iter */
5636 0, /* tp_iternext */
5637 datetime_methods, /* tp_methods */
5638 0, /* tp_members */
5639 datetime_getset, /* tp_getset */
5640 &PyDateTime_DateType, /* tp_base */
5641 0, /* tp_dict */
5642 0, /* tp_descr_get */
5643 0, /* tp_descr_set */
5644 0, /* tp_dictoffset */
5645 0, /* tp_init */
5646 datetime_alloc, /* tp_alloc */
5647 datetime_new, /* tp_new */
5648 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005649};
5650
5651/* ---------------------------------------------------------------------------
5652 * Module methods and initialization.
5653 */
5654
5655static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005656 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005657};
5658
Tim Peters9ddf40b2004-06-20 22:41:32 +00005659/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5660 * datetime.h.
5661 */
5662static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005663 &PyDateTime_DateType,
5664 &PyDateTime_DateTimeType,
5665 &PyDateTime_TimeType,
5666 &PyDateTime_DeltaType,
5667 &PyDateTime_TZInfoType,
5668 new_date_ex,
5669 new_datetime_ex,
5670 new_time_ex,
5671 new_delta_ex,
5672 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005673 date_fromtimestamp,
5674 new_datetime_ex2,
5675 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00005676};
5677
5678
Martin v. Löwis1a214512008-06-11 05:26:20 +00005679
5680static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005681 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005682 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005683 "Fast implementation of the datetime type.",
5684 -1,
5685 module_methods,
5686 NULL,
5687 NULL,
5688 NULL,
5689 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005690};
5691
Tim Peters2a799bf2002-12-16 20:18:38 +00005692PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005693PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005695 PyObject *m; /* a module object */
5696 PyObject *d; /* its dict */
5697 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005698 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005700 m = PyModule_Create(&datetimemodule);
5701 if (m == NULL)
5702 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005704 if (PyType_Ready(&PyDateTime_DateType) < 0)
5705 return NULL;
5706 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5707 return NULL;
5708 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5709 return NULL;
5710 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5711 return NULL;
5712 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5713 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005714 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5715 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005717 /* timedelta values */
5718 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005720 x = new_delta(0, 0, 1, 0);
5721 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5722 return NULL;
5723 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005725 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5726 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5727 return NULL;
5728 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005730 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5731 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5732 return NULL;
5733 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005735 /* date values */
5736 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005738 x = new_date(1, 1, 1);
5739 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5740 return NULL;
5741 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005743 x = new_date(MAXYEAR, 12, 31);
5744 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5745 return NULL;
5746 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005748 x = new_delta(1, 0, 0, 0);
5749 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5750 return NULL;
5751 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005752
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005753 /* time values */
5754 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005755
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005756 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005757 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5758 return NULL;
5759 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005760
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005761 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005762 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5763 return NULL;
5764 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005766 x = new_delta(0, 0, 1, 0);
5767 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5768 return NULL;
5769 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005771 /* datetime values */
5772 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005773
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005774 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005775 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5776 return NULL;
5777 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005778
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005779 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005780 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5781 return NULL;
5782 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005784 x = new_delta(0, 0, 1, 0);
5785 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5786 return NULL;
5787 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005788
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005789 /* timezone values */
5790 d = PyDateTime_TimeZoneType.tp_dict;
5791
5792 delta = new_delta(0, 0, 0, 0);
5793 if (delta == NULL)
5794 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005795 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005796 Py_DECREF(delta);
5797 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5798 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005799 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005800
5801 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5802 if (delta == NULL)
5803 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005804 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005805 Py_DECREF(delta);
5806 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5807 return NULL;
5808 Py_DECREF(x);
5809
5810 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5811 if (delta == NULL)
5812 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005813 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005814 Py_DECREF(delta);
5815 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5816 return NULL;
5817 Py_DECREF(x);
5818
Alexander Belopolskya4415142012-06-08 12:33:09 -04005819 /* Epoch */
5820 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005821 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005822 if (PyDateTime_Epoch == NULL)
5823 return NULL;
5824
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005825 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005826 PyModule_AddIntMacro(m, MINYEAR);
5827 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005829 Py_INCREF(&PyDateTime_DateType);
5830 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005832 Py_INCREF(&PyDateTime_DateTimeType);
5833 PyModule_AddObject(m, "datetime",
5834 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005836 Py_INCREF(&PyDateTime_TimeType);
5837 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005839 Py_INCREF(&PyDateTime_DeltaType);
5840 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005842 Py_INCREF(&PyDateTime_TZInfoType);
5843 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005844
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005845 Py_INCREF(&PyDateTime_TimeZoneType);
5846 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005848 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5849 if (x == NULL)
5850 return NULL;
5851 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005853 /* A 4-year cycle has an extra leap day over what we'd get from
5854 * pasting together 4 single years.
5855 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005856 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005857 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005859 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5860 * get from pasting together 4 100-year cycles.
5861 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005862 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005863 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005865 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5866 * pasting together 25 4-year cycles.
5867 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005868 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005869 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005871 us_per_ms = PyLong_FromLong(1000);
5872 us_per_second = PyLong_FromLong(1000000);
5873 us_per_minute = PyLong_FromLong(60000000);
5874 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03005875 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005876 us_per_minute == NULL || seconds_per_day == NULL)
5877 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005879 /* The rest are too big for 32-bit ints, but even
5880 * us_per_week fits in 40 bits, so doubles should be exact.
5881 */
5882 us_per_hour = PyLong_FromDouble(3600000000.0);
5883 us_per_day = PyLong_FromDouble(86400000000.0);
5884 us_per_week = PyLong_FromDouble(604800000000.0);
5885 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5886 return NULL;
5887 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005888}
Tim Petersf3615152003-01-01 21:51:37 +00005889
5890/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005891Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005892 x.n = x stripped of its timezone -- its naive time.
5893 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005894 return None
Tim Petersf3615152003-01-01 21:51:37 +00005895 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005896 return None
Tim Petersf3615152003-01-01 21:51:37 +00005897 x.s = x's standard offset, x.o - x.d
5898
5899Now some derived rules, where k is a duration (timedelta).
5900
59011. x.o = x.s + x.d
5902 This follows from the definition of x.s.
5903
Tim Petersc5dc4da2003-01-02 17:55:03 +000059042. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005905 This is actually a requirement, an assumption we need to make about
5906 sane tzinfo classes.
5907
59083. The naive UTC time corresponding to x is x.n - x.o.
5909 This is again a requirement for a sane tzinfo class.
5910
59114. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005912 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005913
Tim Petersc5dc4da2003-01-02 17:55:03 +000059145. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005915 Again follows from how arithmetic is defined.
5916
Tim Peters8bb5ad22003-01-24 02:44:45 +00005917Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005918(meaning that the various tzinfo methods exist, and don't blow up or return
5919None when called).
5920
Tim Petersa9bc1682003-01-11 03:39:11 +00005921The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005922x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005923
5924By #3, we want
5925
Tim Peters8bb5ad22003-01-24 02:44:45 +00005926 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005927
5928The algorithm starts by attaching tz to x.n, and calling that y. So
5929x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5930becomes true; in effect, we want to solve [2] for k:
5931
Tim Peters8bb5ad22003-01-24 02:44:45 +00005932 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005933
5934By #1, this is the same as
5935
Tim Peters8bb5ad22003-01-24 02:44:45 +00005936 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005937
5938By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5939Substituting that into [3],
5940
Tim Peters8bb5ad22003-01-24 02:44:45 +00005941 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5942 k - (y+k).s - (y+k).d = 0; rearranging,
5943 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5944 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005945
Tim Peters8bb5ad22003-01-24 02:44:45 +00005946On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5947approximate k by ignoring the (y+k).d term at first. Note that k can't be
5948very large, since all offset-returning methods return a duration of magnitude
5949less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5950be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005951
5952In any case, the new value is
5953
Tim Peters8bb5ad22003-01-24 02:44:45 +00005954 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005955
Tim Peters8bb5ad22003-01-24 02:44:45 +00005956It's helpful to step back at look at [4] from a higher level: it's simply
5957mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005958
5959At this point, if
5960
Tim Peters8bb5ad22003-01-24 02:44:45 +00005961 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005962
5963we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005964at the start of daylight time. Picture US Eastern for concreteness. The wall
5965time 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 +00005966sense then. The docs ask that an Eastern tzinfo class consider such a time to
5967be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5968on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005969the only spelling that makes sense on the local wall clock.
5970
Tim Petersc5dc4da2003-01-02 17:55:03 +00005971In fact, if [5] holds at this point, we do have the standard-time spelling,
5972but that takes a bit of proof. We first prove a stronger result. What's the
5973difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005974
Tim Peters8bb5ad22003-01-24 02:44:45 +00005975 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005976
Tim Petersc5dc4da2003-01-02 17:55:03 +00005977Now
5978 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005979 (y + y.s).n = by #5
5980 y.n + y.s = since y.n = x.n
5981 x.n + y.s = since z and y are have the same tzinfo member,
5982 y.s = z.s by #2
5983 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005984
Tim Petersc5dc4da2003-01-02 17:55:03 +00005985Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005986
Tim Petersc5dc4da2003-01-02 17:55:03 +00005987 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005988 x.n - ((x.n + z.s) - z.o) = expanding
5989 x.n - x.n - z.s + z.o = cancelling
5990 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005991 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005992
Tim Petersc5dc4da2003-01-02 17:55:03 +00005993So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005994
Tim Petersc5dc4da2003-01-02 17:55:03 +00005995If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005996spelling we wanted in the endcase described above. We're done. Contrarily,
5997if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005998
Tim Petersc5dc4da2003-01-02 17:55:03 +00005999If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6000add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006001local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006002
Tim Petersc5dc4da2003-01-02 17:55:03 +00006003Let
Tim Petersf3615152003-01-01 21:51:37 +00006004
Tim Peters4fede1a2003-01-04 00:26:59 +00006005 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006006
Tim Peters4fede1a2003-01-04 00:26:59 +00006007and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006008
Tim Peters8bb5ad22003-01-24 02:44:45 +00006009 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006010
Tim Peters8bb5ad22003-01-24 02:44:45 +00006011If so, we're done. If not, the tzinfo class is insane, according to the
6012assumptions we've made. This also requires a bit of proof. As before, let's
6013compute the difference between the LHS and RHS of [8] (and skipping some of
6014the justifications for the kinds of substitutions we've done several times
6015already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006016
Tim Peters8bb5ad22003-01-24 02:44:45 +00006017 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006018 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6019 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6020 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6021 - z.n + z.n - z.o + z'.o = cancel z.n
6022 - z.o + z'.o = #1 twice
6023 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6024 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006025
6026So 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 +00006027we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6028return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006029
Tim Peters8bb5ad22003-01-24 02:44:45 +00006030How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6031a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6032would have to change the result dst() returns: we start in DST, and moving
6033a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006034
Tim Peters8bb5ad22003-01-24 02:44:45 +00006035There isn't a sane case where this can happen. The closest it gets is at
6036the end of DST, where there's an hour in UTC with no spelling in a hybrid
6037tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6038that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6039UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6040time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6041clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6042standard time. Since that's what the local clock *does*, we want to map both
6043UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006044in local time, but so it goes -- it's the way the local clock works.
6045
Tim Peters8bb5ad22003-01-24 02:44:45 +00006046When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6047so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6048z' = 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 +00006049(correctly) concludes that z' is not UTC-equivalent to x.
6050
6051Because we know z.d said z was in daylight time (else [5] would have held and
6052we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006053and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006054return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6055but the reasoning doesn't depend on the example -- it depends on there being
6056two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006057z' must be in standard time, and is the spelling we want in this case.
6058
6059Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6060concerned (because it takes z' as being in standard time rather than the
6061daylight time we intend here), but returning it gives the real-life "local
6062clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6063tz.
6064
6065When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6066the 1:MM standard time spelling we want.
6067
6068So how can this break? One of the assumptions must be violated. Two
6069possibilities:
6070
60711) [2] effectively says that y.s is invariant across all y belong to a given
6072 time zone. This isn't true if, for political reasons or continental drift,
6073 a region decides to change its base offset from UTC.
6074
60752) There may be versions of "double daylight" time where the tail end of
6076 the analysis gives up a step too early. I haven't thought about that
6077 enough to say.
6078
6079In any case, it's clear that the default fromutc() is strong enough to handle
6080"almost all" time zones: so long as the standard offset is invariant, it
6081doesn't matter if daylight time transition points change from year to year, or
6082if daylight time is skipped in some years; it doesn't matter how large or
6083small dst() may get within its bounds; and it doesn't even matter if some
6084perverse time zone returns a negative dst()). So a breaking case must be
6085pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006086--------------------------------------------------------------------------- */