blob: 3dd7f827509afcdb385d68e452ccccf6c5cd3e3e [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 *
Oren Milman865e4b42017-09-19 15:58:11 +03001654get_float_as_integer_ratio(PyObject *floatobj)
1655{
1656 PyObject *ratio;
1657
1658 assert(floatobj && PyFloat_Check(floatobj));
1659 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1660 if (ratio == NULL) {
1661 return NULL;
1662 }
1663 if (!PyTuple_Check(ratio)) {
1664 PyErr_Format(PyExc_TypeError,
1665 "unexpected return type from as_integer_ratio(): "
1666 "expected tuple, got '%.200s'",
1667 Py_TYPE(ratio)->tp_name);
1668 Py_DECREF(ratio);
1669 return NULL;
1670 }
1671 if (PyTuple_Size(ratio) != 2) {
1672 PyErr_SetString(PyExc_ValueError,
1673 "as_integer_ratio() must return a 2-tuple");
1674 Py_DECREF(ratio);
1675 return NULL;
1676 }
1677 return ratio;
1678}
1679
1680static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001681multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1682{
1683 PyObject *result = NULL;
1684 PyObject *pyus_in = NULL, *temp, *pyus_out;
1685 PyObject *ratio = NULL;
1686
1687 pyus_in = delta_to_microseconds(delta);
1688 if (pyus_in == NULL)
1689 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001690 ratio = get_float_as_integer_ratio(floatobj);
1691 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001692 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001693 }
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001694 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1695 Py_DECREF(pyus_in);
1696 pyus_in = NULL;
1697 if (temp == NULL)
1698 goto error;
1699 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1700 Py_DECREF(temp);
1701 if (pyus_out == NULL)
1702 goto error;
1703 result = microseconds_to_delta(pyus_out);
1704 Py_DECREF(pyus_out);
1705 error:
1706 Py_XDECREF(pyus_in);
1707 Py_XDECREF(ratio);
1708
1709 return result;
1710}
1711
1712static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001713divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 PyObject *pyus_in;
1716 PyObject *pyus_out;
1717 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001718
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001719 pyus_in = delta_to_microseconds(delta);
1720 if (pyus_in == NULL)
1721 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001723 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1724 Py_DECREF(pyus_in);
1725 if (pyus_out == NULL)
1726 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 result = microseconds_to_delta(pyus_out);
1729 Py_DECREF(pyus_out);
1730 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001731}
1732
1733static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001734divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 PyObject *pyus_left;
1737 PyObject *pyus_right;
1738 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 pyus_left = delta_to_microseconds(left);
1741 if (pyus_left == NULL)
1742 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001743
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 pyus_right = delta_to_microseconds(right);
1745 if (pyus_right == NULL) {
1746 Py_DECREF(pyus_left);
1747 return NULL;
1748 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1751 Py_DECREF(pyus_left);
1752 Py_DECREF(pyus_right);
1753 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001754}
1755
1756static PyObject *
1757truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 PyObject *pyus_left;
1760 PyObject *pyus_right;
1761 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 pyus_left = delta_to_microseconds(left);
1764 if (pyus_left == NULL)
1765 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 pyus_right = delta_to_microseconds(right);
1768 if (pyus_right == NULL) {
1769 Py_DECREF(pyus_left);
1770 return NULL;
1771 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1774 Py_DECREF(pyus_left);
1775 Py_DECREF(pyus_right);
1776 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001777}
1778
1779static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001780truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1781{
1782 PyObject *result = NULL;
1783 PyObject *pyus_in = NULL, *temp, *pyus_out;
1784 PyObject *ratio = NULL;
1785
1786 pyus_in = delta_to_microseconds(delta);
1787 if (pyus_in == NULL)
1788 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001789 ratio = get_float_as_integer_ratio(f);
1790 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001791 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001792 }
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001793 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1794 Py_DECREF(pyus_in);
1795 pyus_in = NULL;
1796 if (temp == NULL)
1797 goto error;
1798 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1799 Py_DECREF(temp);
1800 if (pyus_out == NULL)
1801 goto error;
1802 result = microseconds_to_delta(pyus_out);
1803 Py_DECREF(pyus_out);
1804 error:
1805 Py_XDECREF(pyus_in);
1806 Py_XDECREF(ratio);
1807
1808 return result;
1809}
1810
1811static PyObject *
1812truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1813{
1814 PyObject *result;
1815 PyObject *pyus_in, *pyus_out;
1816 pyus_in = delta_to_microseconds(delta);
1817 if (pyus_in == NULL)
1818 return NULL;
1819 pyus_out = divide_nearest(pyus_in, i);
1820 Py_DECREF(pyus_in);
1821 if (pyus_out == NULL)
1822 return NULL;
1823 result = microseconds_to_delta(pyus_out);
1824 Py_DECREF(pyus_out);
1825
1826 return result;
1827}
1828
1829static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001830delta_add(PyObject *left, PyObject *right)
1831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1835 /* delta + delta */
1836 /* The C-level additions can't overflow because of the
1837 * invariant bounds.
1838 */
1839 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1840 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1841 int microseconds = GET_TD_MICROSECONDS(left) +
1842 GET_TD_MICROSECONDS(right);
1843 result = new_delta(days, seconds, microseconds, 1);
1844 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 if (result == Py_NotImplemented)
1847 Py_INCREF(result);
1848 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001849}
1850
1851static PyObject *
1852delta_negative(PyDateTime_Delta *self)
1853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 return new_delta(-GET_TD_DAYS(self),
1855 -GET_TD_SECONDS(self),
1856 -GET_TD_MICROSECONDS(self),
1857 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001858}
1859
1860static PyObject *
1861delta_positive(PyDateTime_Delta *self)
1862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 /* Could optimize this (by returning self) if this isn't a
1864 * subclass -- but who uses unary + ? Approximately nobody.
1865 */
1866 return new_delta(GET_TD_DAYS(self),
1867 GET_TD_SECONDS(self),
1868 GET_TD_MICROSECONDS(self),
1869 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001870}
1871
1872static PyObject *
1873delta_abs(PyDateTime_Delta *self)
1874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 assert(GET_TD_MICROSECONDS(self) >= 0);
1878 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 if (GET_TD_DAYS(self) < 0)
1881 result = delta_negative(self);
1882 else
1883 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001886}
1887
1888static PyObject *
1889delta_subtract(PyObject *left, PyObject *right)
1890{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1894 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001895 /* The C-level additions can't overflow because of the
1896 * invariant bounds.
1897 */
1898 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1899 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1900 int microseconds = GET_TD_MICROSECONDS(left) -
1901 GET_TD_MICROSECONDS(right);
1902 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 if (result == Py_NotImplemented)
1906 Py_INCREF(result);
1907 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001908}
1909
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001910static int
1911delta_cmp(PyObject *self, PyObject *other)
1912{
1913 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1914 if (diff == 0) {
1915 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1916 if (diff == 0)
1917 diff = GET_TD_MICROSECONDS(self) -
1918 GET_TD_MICROSECONDS(other);
1919 }
1920 return diff;
1921}
1922
Tim Peters2a799bf2002-12-16 20:18:38 +00001923static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001924delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001927 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 return diff_to_bool(diff, op);
1929 }
1930 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001931 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001933}
1934
1935static PyObject *delta_getstate(PyDateTime_Delta *self);
1936
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001937static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001938delta_hash(PyDateTime_Delta *self)
1939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 if (self->hashcode == -1) {
1941 PyObject *temp = delta_getstate(self);
1942 if (temp != NULL) {
1943 self->hashcode = PyObject_Hash(temp);
1944 Py_DECREF(temp);
1945 }
1946 }
1947 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001948}
1949
1950static PyObject *
1951delta_multiply(PyObject *left, PyObject *right)
1952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 if (PyDelta_Check(left)) {
1956 /* delta * ??? */
1957 if (PyLong_Check(right))
1958 result = multiply_int_timedelta(right,
1959 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001960 else if (PyFloat_Check(right))
1961 result = multiply_float_timedelta(right,
1962 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001963 }
1964 else if (PyLong_Check(left))
1965 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001966 (PyDateTime_Delta *) right);
1967 else if (PyFloat_Check(left))
1968 result = multiply_float_timedelta(left,
1969 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 if (result == Py_NotImplemented)
1972 Py_INCREF(result);
1973 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001974}
1975
1976static PyObject *
1977delta_divide(PyObject *left, PyObject *right)
1978{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 if (PyDelta_Check(left)) {
1982 /* delta * ??? */
1983 if (PyLong_Check(right))
1984 result = divide_timedelta_int(
1985 (PyDateTime_Delta *)left,
1986 right);
1987 else if (PyDelta_Check(right))
1988 result = divide_timedelta_timedelta(
1989 (PyDateTime_Delta *)left,
1990 (PyDateTime_Delta *)right);
1991 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 if (result == Py_NotImplemented)
1994 Py_INCREF(result);
1995 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001996}
1997
Mark Dickinson7c186e22010-04-20 22:32:49 +00001998static PyObject *
1999delta_truedivide(PyObject *left, PyObject *right)
2000{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 if (PyDelta_Check(left)) {
2004 if (PyDelta_Check(right))
2005 result = truedivide_timedelta_timedelta(
2006 (PyDateTime_Delta *)left,
2007 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002008 else if (PyFloat_Check(right))
2009 result = truedivide_timedelta_float(
2010 (PyDateTime_Delta *)left, right);
2011 else if (PyLong_Check(right))
2012 result = truedivide_timedelta_int(
2013 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 if (result == Py_NotImplemented)
2017 Py_INCREF(result);
2018 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002019}
2020
2021static PyObject *
2022delta_remainder(PyObject *left, PyObject *right)
2023{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 PyObject *pyus_left;
2025 PyObject *pyus_right;
2026 PyObject *pyus_remainder;
2027 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002028
Brian Curtindfc80e32011-08-10 20:28:54 -05002029 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2030 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2033 if (pyus_left == NULL)
2034 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2037 if (pyus_right == NULL) {
2038 Py_DECREF(pyus_left);
2039 return NULL;
2040 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2043 Py_DECREF(pyus_left);
2044 Py_DECREF(pyus_right);
2045 if (pyus_remainder == NULL)
2046 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 remainder = microseconds_to_delta(pyus_remainder);
2049 Py_DECREF(pyus_remainder);
2050 if (remainder == NULL)
2051 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002054}
2055
2056static PyObject *
2057delta_divmod(PyObject *left, PyObject *right)
2058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 PyObject *pyus_left;
2060 PyObject *pyus_right;
2061 PyObject *divmod;
2062 PyObject *delta;
2063 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002064
Brian Curtindfc80e32011-08-10 20:28:54 -05002065 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2066 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2069 if (pyus_left == NULL)
2070 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002072 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2073 if (pyus_right == NULL) {
2074 Py_DECREF(pyus_left);
2075 return NULL;
2076 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2079 Py_DECREF(pyus_left);
2080 Py_DECREF(pyus_right);
2081 if (divmod == NULL)
2082 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 assert(PyTuple_Size(divmod) == 2);
2085 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2086 if (delta == NULL) {
2087 Py_DECREF(divmod);
2088 return NULL;
2089 }
2090 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2091 Py_DECREF(delta);
2092 Py_DECREF(divmod);
2093 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002094}
2095
Tim Peters2a799bf2002-12-16 20:18:38 +00002096/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2097 * timedelta constructor. sofar is the # of microseconds accounted for
2098 * so far, and there are factor microseconds per current unit, the number
2099 * of which is given by num. num * factor is added to sofar in a
2100 * numerically careful way, and that's the result. Any fractional
2101 * microseconds left over (this can happen if num is a float type) are
2102 * added into *leftover.
2103 * Note that there are many ways this can give an error (NULL) return.
2104 */
2105static PyObject *
2106accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2107 double *leftover)
2108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 PyObject *prod;
2110 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 if (PyLong_Check(num)) {
2115 prod = PyNumber_Multiply(num, factor);
2116 if (prod == NULL)
2117 return NULL;
2118 sum = PyNumber_Add(sofar, prod);
2119 Py_DECREF(prod);
2120 return sum;
2121 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 if (PyFloat_Check(num)) {
2124 double dnum;
2125 double fracpart;
2126 double intpart;
2127 PyObject *x;
2128 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 /* The Plan: decompose num into an integer part and a
2131 * fractional part, num = intpart + fracpart.
2132 * Then num * factor ==
2133 * intpart * factor + fracpart * factor
2134 * and the LHS can be computed exactly in long arithmetic.
2135 * The RHS is again broken into an int part and frac part.
2136 * and the frac part is added into *leftover.
2137 */
2138 dnum = PyFloat_AsDouble(num);
2139 if (dnum == -1.0 && PyErr_Occurred())
2140 return NULL;
2141 fracpart = modf(dnum, &intpart);
2142 x = PyLong_FromDouble(intpart);
2143 if (x == NULL)
2144 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 prod = PyNumber_Multiply(x, factor);
2147 Py_DECREF(x);
2148 if (prod == NULL)
2149 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 sum = PyNumber_Add(sofar, prod);
2152 Py_DECREF(prod);
2153 if (sum == NULL)
2154 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 if (fracpart == 0.0)
2157 return sum;
2158 /* So far we've lost no information. Dealing with the
2159 * fractional part requires float arithmetic, and may
2160 * lose a little info.
2161 */
2162 assert(PyLong_Check(factor));
2163 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 dnum *= fracpart;
2166 fracpart = modf(dnum, &intpart);
2167 x = PyLong_FromDouble(intpart);
2168 if (x == NULL) {
2169 Py_DECREF(sum);
2170 return NULL;
2171 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 y = PyNumber_Add(sum, x);
2174 Py_DECREF(sum);
2175 Py_DECREF(x);
2176 *leftover += fracpart;
2177 return y;
2178 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 PyErr_Format(PyExc_TypeError,
2181 "unsupported type for timedelta %s component: %s",
2182 tag, Py_TYPE(num)->tp_name);
2183 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002184}
2185
2186static PyObject *
2187delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 /* Argument objects. */
2192 PyObject *day = NULL;
2193 PyObject *second = NULL;
2194 PyObject *us = NULL;
2195 PyObject *ms = NULL;
2196 PyObject *minute = NULL;
2197 PyObject *hour = NULL;
2198 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002200 PyObject *x = NULL; /* running sum of microseconds */
2201 PyObject *y = NULL; /* temp sum of microseconds */
2202 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 static char *keywords[] = {
2205 "days", "seconds", "microseconds", "milliseconds",
2206 "minutes", "hours", "weeks", NULL
2207 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2210 keywords,
2211 &day, &second, &us,
2212 &ms, &minute, &hour, &week) == 0)
2213 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002215 x = PyLong_FromLong(0);
2216 if (x == NULL)
2217 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219#define CLEANUP \
2220 Py_DECREF(x); \
2221 x = y; \
2222 if (x == NULL) \
2223 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002226 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 CLEANUP;
2228 }
2229 if (ms) {
2230 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2231 CLEANUP;
2232 }
2233 if (second) {
2234 y = accum("seconds", x, second, us_per_second, &leftover_us);
2235 CLEANUP;
2236 }
2237 if (minute) {
2238 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2239 CLEANUP;
2240 }
2241 if (hour) {
2242 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2243 CLEANUP;
2244 }
2245 if (day) {
2246 y = accum("days", x, day, us_per_day, &leftover_us);
2247 CLEANUP;
2248 }
2249 if (week) {
2250 y = accum("weeks", x, week, us_per_week, &leftover_us);
2251 CLEANUP;
2252 }
2253 if (leftover_us) {
2254 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002255 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002256 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002257 PyObject *temp;
2258
Victor Stinner69cc4872015-09-08 23:58:54 +02002259 whole_us = round(leftover_us);
2260 if (fabs(whole_us - leftover_us) == 0.5) {
2261 /* We're exactly halfway between two integers. In order
2262 * to do round-half-to-even, we must determine whether x
2263 * is odd. Note that x is odd when it's last bit is 1. The
2264 * code below uses bitwise and operation to check the last
2265 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002266 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002267 if (temp == NULL) {
2268 Py_DECREF(x);
2269 goto Done;
2270 }
2271 x_is_odd = PyObject_IsTrue(temp);
2272 Py_DECREF(temp);
2273 if (x_is_odd == -1) {
2274 Py_DECREF(x);
2275 goto Done;
2276 }
2277 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2278 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002279
Victor Stinner36a5a062013-08-28 01:53:39 +02002280 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 if (temp == NULL) {
2283 Py_DECREF(x);
2284 goto Done;
2285 }
2286 y = PyNumber_Add(x, temp);
2287 Py_DECREF(temp);
2288 CLEANUP;
2289 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 self = microseconds_to_delta_ex(x, type);
2292 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002293Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002295
2296#undef CLEANUP
2297}
2298
2299static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002300delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 return (GET_TD_DAYS(self) != 0
2303 || GET_TD_SECONDS(self) != 0
2304 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002305}
2306
2307static PyObject *
2308delta_repr(PyDateTime_Delta *self)
2309{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002310 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002311
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002312 if (args == NULL) {
2313 return NULL;
2314 }
2315
2316 const char *sep = "";
2317
2318 if (GET_TD_DAYS(self) != 0) {
2319 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2320 if (args == NULL) {
2321 return NULL;
2322 }
2323 sep = ", ";
2324 }
2325
2326 if (GET_TD_SECONDS(self) != 0) {
2327 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2328 GET_TD_SECONDS(self)));
2329 if (args == NULL) {
2330 return NULL;
2331 }
2332 sep = ", ";
2333 }
2334
2335 if (GET_TD_MICROSECONDS(self) != 0) {
2336 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2337 GET_TD_MICROSECONDS(self)));
2338 if (args == NULL) {
2339 return NULL;
2340 }
2341 }
2342
2343 if (PyUnicode_GET_LENGTH(args) == 0) {
2344 Py_SETREF(args, PyUnicode_FromString("0"));
2345 if (args == NULL) {
2346 return NULL;
2347 }
2348 }
2349
2350 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2351 args);
2352 Py_DECREF(args);
2353 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002354}
2355
2356static PyObject *
2357delta_str(PyDateTime_Delta *self)
2358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002359 int us = GET_TD_MICROSECONDS(self);
2360 int seconds = GET_TD_SECONDS(self);
2361 int minutes = divmod(seconds, 60, &seconds);
2362 int hours = divmod(minutes, 60, &minutes);
2363 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002365 if (days) {
2366 if (us)
2367 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2368 days, (days == 1 || days == -1) ? "" : "s",
2369 hours, minutes, seconds, us);
2370 else
2371 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2372 days, (days == 1 || days == -1) ? "" : "s",
2373 hours, minutes, seconds);
2374 } else {
2375 if (us)
2376 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2377 hours, minutes, seconds, us);
2378 else
2379 return PyUnicode_FromFormat("%d:%02d:%02d",
2380 hours, minutes, seconds);
2381 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002382
Tim Peters2a799bf2002-12-16 20:18:38 +00002383}
2384
Tim Peters371935f2003-02-01 01:52:50 +00002385/* Pickle support, a simple use of __reduce__. */
2386
Tim Petersb57f8f02003-02-01 02:54:15 +00002387/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002388static PyObject *
2389delta_getstate(PyDateTime_Delta *self)
2390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 return Py_BuildValue("iii", GET_TD_DAYS(self),
2392 GET_TD_SECONDS(self),
2393 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002394}
2395
Tim Peters2a799bf2002-12-16 20:18:38 +00002396static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002397delta_total_seconds(PyObject *self)
2398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 PyObject *total_seconds;
2400 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2403 if (total_microseconds == NULL)
2404 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002405
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002406 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002410}
2411
2412static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002413delta_reduce(PyDateTime_Delta* self)
2414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002416}
2417
2418#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2419
2420static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 {"days", T_INT, OFFSET(days), READONLY,
2423 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002425 {"seconds", T_INT, OFFSET(seconds), READONLY,
2426 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2429 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2430 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002431};
2432
2433static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2435 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2438 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002440 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002441};
2442
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002443static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002444PyDoc_STR("Difference between two datetime values.");
2445
2446static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002447 delta_add, /* nb_add */
2448 delta_subtract, /* nb_subtract */
2449 delta_multiply, /* nb_multiply */
2450 delta_remainder, /* nb_remainder */
2451 delta_divmod, /* nb_divmod */
2452 0, /* nb_power */
2453 (unaryfunc)delta_negative, /* nb_negative */
2454 (unaryfunc)delta_positive, /* nb_positive */
2455 (unaryfunc)delta_abs, /* nb_absolute */
2456 (inquiry)delta_bool, /* nb_bool */
2457 0, /*nb_invert*/
2458 0, /*nb_lshift*/
2459 0, /*nb_rshift*/
2460 0, /*nb_and*/
2461 0, /*nb_xor*/
2462 0, /*nb_or*/
2463 0, /*nb_int*/
2464 0, /*nb_reserved*/
2465 0, /*nb_float*/
2466 0, /*nb_inplace_add*/
2467 0, /*nb_inplace_subtract*/
2468 0, /*nb_inplace_multiply*/
2469 0, /*nb_inplace_remainder*/
2470 0, /*nb_inplace_power*/
2471 0, /*nb_inplace_lshift*/
2472 0, /*nb_inplace_rshift*/
2473 0, /*nb_inplace_and*/
2474 0, /*nb_inplace_xor*/
2475 0, /*nb_inplace_or*/
2476 delta_divide, /* nb_floor_divide */
2477 delta_truedivide, /* nb_true_divide */
2478 0, /* nb_inplace_floor_divide */
2479 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002480};
2481
2482static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 PyVarObject_HEAD_INIT(NULL, 0)
2484 "datetime.timedelta", /* tp_name */
2485 sizeof(PyDateTime_Delta), /* tp_basicsize */
2486 0, /* tp_itemsize */
2487 0, /* tp_dealloc */
2488 0, /* tp_print */
2489 0, /* tp_getattr */
2490 0, /* tp_setattr */
2491 0, /* tp_reserved */
2492 (reprfunc)delta_repr, /* tp_repr */
2493 &delta_as_number, /* tp_as_number */
2494 0, /* tp_as_sequence */
2495 0, /* tp_as_mapping */
2496 (hashfunc)delta_hash, /* tp_hash */
2497 0, /* tp_call */
2498 (reprfunc)delta_str, /* tp_str */
2499 PyObject_GenericGetAttr, /* tp_getattro */
2500 0, /* tp_setattro */
2501 0, /* tp_as_buffer */
2502 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2503 delta_doc, /* tp_doc */
2504 0, /* tp_traverse */
2505 0, /* tp_clear */
2506 delta_richcompare, /* tp_richcompare */
2507 0, /* tp_weaklistoffset */
2508 0, /* tp_iter */
2509 0, /* tp_iternext */
2510 delta_methods, /* tp_methods */
2511 delta_members, /* tp_members */
2512 0, /* tp_getset */
2513 0, /* tp_base */
2514 0, /* tp_dict */
2515 0, /* tp_descr_get */
2516 0, /* tp_descr_set */
2517 0, /* tp_dictoffset */
2518 0, /* tp_init */
2519 0, /* tp_alloc */
2520 delta_new, /* tp_new */
2521 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002522};
2523
2524/*
2525 * PyDateTime_Date implementation.
2526 */
2527
2528/* Accessor properties. */
2529
2530static PyObject *
2531date_year(PyDateTime_Date *self, void *unused)
2532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002533 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002534}
2535
2536static PyObject *
2537date_month(PyDateTime_Date *self, void *unused)
2538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002540}
2541
2542static PyObject *
2543date_day(PyDateTime_Date *self, void *unused)
2544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002545 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002546}
2547
2548static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002549 {"year", (getter)date_year},
2550 {"month", (getter)date_month},
2551 {"day", (getter)date_day},
2552 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002553};
2554
2555/* Constructors. */
2556
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002557static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002558
Tim Peters2a799bf2002-12-16 20:18:38 +00002559static PyObject *
2560date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2561{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002562 PyObject *self = NULL;
2563 PyObject *state;
2564 int year;
2565 int month;
2566 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002568 /* Check for invocation from pickle with __getstate__ state */
2569 if (PyTuple_GET_SIZE(args) == 1 &&
2570 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2571 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2572 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2573 {
2574 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002576 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2577 if (me != NULL) {
2578 char *pdata = PyBytes_AS_STRING(state);
2579 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2580 me->hashcode = -1;
2581 }
2582 return (PyObject *)me;
2583 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002585 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2586 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 self = new_date_ex(year, month, day, type);
2588 }
2589 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002590}
2591
2592/* Return new date from localtime(t). */
2593static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002594date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002595{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002596 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002598
Victor Stinnere4a994d2015-03-30 01:10:14 +02002599 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002601
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002602 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002603 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002604
2605 return PyObject_CallFunction(cls, "iii",
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002606 tm.tm_year + 1900,
2607 tm.tm_mon + 1,
2608 tm.tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002609}
2610
2611/* Return new date from current time.
2612 * We say this is equivalent to fromtimestamp(time.time()), and the
2613 * only way to be sure of that is to *call* time.time(). That's not
2614 * generally the same as calling C's time.
2615 */
2616static PyObject *
2617date_today(PyObject *cls, PyObject *dummy)
2618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002619 PyObject *time;
2620 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002621 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002623 time = time_time();
2624 if (time == NULL)
2625 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002627 /* Note well: today() is a class method, so this may not call
2628 * date.fromtimestamp. For example, it may call
2629 * datetime.fromtimestamp. That's why we need all the accuracy
2630 * time.time() delivers; if someone were gonzo about optimization,
2631 * date.today() could get away with plain C time().
2632 */
Victor Stinner20401de2016-12-09 15:24:31 +01002633 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2634 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002635 Py_DECREF(time);
2636 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002637}
2638
2639/* Return new date from given timestamp (Python timestamp -- a double). */
2640static PyObject *
2641date_fromtimestamp(PyObject *cls, PyObject *args)
2642{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002643 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002644 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002645
Victor Stinner5d272cc2012-03-13 13:35:55 +01002646 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2647 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002648 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002649}
2650
2651/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2652 * the ordinal is out of range.
2653 */
2654static PyObject *
2655date_fromordinal(PyObject *cls, PyObject *args)
2656{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002657 PyObject *result = NULL;
2658 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002660 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2661 int year;
2662 int month;
2663 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002665 if (ordinal < 1)
2666 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2667 ">= 1");
2668 else {
2669 ord_to_ymd(ordinal, &year, &month, &day);
2670 result = PyObject_CallFunction(cls, "iii",
2671 year, month, day);
2672 }
2673 }
2674 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002675}
2676
2677/*
2678 * Date arithmetic.
2679 */
2680
2681/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2682 * instead.
2683 */
2684static PyObject *
2685add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002687 PyObject *result = NULL;
2688 int year = GET_YEAR(date);
2689 int month = GET_MONTH(date);
2690 int deltadays = GET_TD_DAYS(delta);
2691 /* C-level overflow is impossible because |deltadays| < 1e9. */
2692 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002694 if (normalize_date(&year, &month, &day) >= 0)
2695 result = new_date(year, month, day);
2696 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002697}
2698
2699static PyObject *
2700date_add(PyObject *left, PyObject *right)
2701{
Brian Curtindfc80e32011-08-10 20:28:54 -05002702 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2703 Py_RETURN_NOTIMPLEMENTED;
2704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002705 if (PyDate_Check(left)) {
2706 /* date + ??? */
2707 if (PyDelta_Check(right))
2708 /* date + delta */
2709 return add_date_timedelta((PyDateTime_Date *) left,
2710 (PyDateTime_Delta *) right,
2711 0);
2712 }
2713 else {
2714 /* ??? + date
2715 * 'right' must be one of us, or we wouldn't have been called
2716 */
2717 if (PyDelta_Check(left))
2718 /* delta + date */
2719 return add_date_timedelta((PyDateTime_Date *) right,
2720 (PyDateTime_Delta *) left,
2721 0);
2722 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002723 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002724}
2725
2726static PyObject *
2727date_subtract(PyObject *left, PyObject *right)
2728{
Brian Curtindfc80e32011-08-10 20:28:54 -05002729 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2730 Py_RETURN_NOTIMPLEMENTED;
2731
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002732 if (PyDate_Check(left)) {
2733 if (PyDate_Check(right)) {
2734 /* date - date */
2735 int left_ord = ymd_to_ord(GET_YEAR(left),
2736 GET_MONTH(left),
2737 GET_DAY(left));
2738 int right_ord = ymd_to_ord(GET_YEAR(right),
2739 GET_MONTH(right),
2740 GET_DAY(right));
2741 return new_delta(left_ord - right_ord, 0, 0, 0);
2742 }
2743 if (PyDelta_Check(right)) {
2744 /* date - delta */
2745 return add_date_timedelta((PyDateTime_Date *) left,
2746 (PyDateTime_Delta *) right,
2747 1);
2748 }
2749 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002750 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002751}
2752
2753
2754/* Various ways to turn a date into a string. */
2755
2756static PyObject *
2757date_repr(PyDateTime_Date *self)
2758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002759 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2760 Py_TYPE(self)->tp_name,
2761 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002762}
2763
2764static PyObject *
2765date_isoformat(PyDateTime_Date *self)
2766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002767 return PyUnicode_FromFormat("%04d-%02d-%02d",
2768 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002769}
2770
Tim Peterse2df5ff2003-05-02 18:39:55 +00002771/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002772static PyObject *
2773date_str(PyDateTime_Date *self)
2774{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002775 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002776}
2777
2778
2779static PyObject *
2780date_ctime(PyDateTime_Date *self)
2781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002782 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002783}
2784
2785static PyObject *
2786date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002788 /* This method can be inherited, and needs to call the
2789 * timetuple() method appropriate to self's class.
2790 */
2791 PyObject *result;
2792 PyObject *tuple;
2793 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002794 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002795 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002796
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002797 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2798 &format))
2799 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002800
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002801 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002802 if (tuple == NULL)
2803 return NULL;
2804 result = wrap_strftime((PyObject *)self, format, tuple,
2805 (PyObject *)self);
2806 Py_DECREF(tuple);
2807 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002808}
2809
Eric Smith1ba31142007-09-11 18:06:02 +00002810static PyObject *
2811date_format(PyDateTime_Date *self, PyObject *args)
2812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002813 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2816 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002817
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002818 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002819 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002820 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002821
Victor Stinner20401de2016-12-09 15:24:31 +01002822 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
2823 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00002824}
2825
Tim Peters2a799bf2002-12-16 20:18:38 +00002826/* ISO methods. */
2827
2828static PyObject *
2829date_isoweekday(PyDateTime_Date *self)
2830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002833 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002834}
2835
2836static PyObject *
2837date_isocalendar(PyDateTime_Date *self)
2838{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002839 int year = GET_YEAR(self);
2840 int week1_monday = iso_week1_monday(year);
2841 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2842 int week;
2843 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 week = divmod(today - week1_monday, 7, &day);
2846 if (week < 0) {
2847 --year;
2848 week1_monday = iso_week1_monday(year);
2849 week = divmod(today - week1_monday, 7, &day);
2850 }
2851 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2852 ++year;
2853 week = 0;
2854 }
2855 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002856}
2857
2858/* Miscellaneous methods. */
2859
Tim Peters2a799bf2002-12-16 20:18:38 +00002860static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002861date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002863 if (PyDate_Check(other)) {
2864 int diff = memcmp(((PyDateTime_Date *)self)->data,
2865 ((PyDateTime_Date *)other)->data,
2866 _PyDateTime_DATE_DATASIZE);
2867 return diff_to_bool(diff, op);
2868 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002869 else
2870 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002871}
2872
2873static PyObject *
2874date_timetuple(PyDateTime_Date *self)
2875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002876 return build_struct_time(GET_YEAR(self),
2877 GET_MONTH(self),
2878 GET_DAY(self),
2879 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002880}
2881
Tim Peters12bf3392002-12-24 05:41:27 +00002882static PyObject *
2883date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002885 PyObject *clone;
2886 PyObject *tuple;
2887 int year = GET_YEAR(self);
2888 int month = GET_MONTH(self);
2889 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002891 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2892 &year, &month, &day))
2893 return NULL;
2894 tuple = Py_BuildValue("iii", year, month, day);
2895 if (tuple == NULL)
2896 return NULL;
2897 clone = date_new(Py_TYPE(self), tuple, NULL);
2898 Py_DECREF(tuple);
2899 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002900}
2901
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002902static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002903generic_hash(unsigned char *data, int len)
2904{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002905 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002906}
2907
2908
2909static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002910
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002911static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002912date_hash(PyDateTime_Date *self)
2913{
Benjamin Petersondec2df32016-09-09 17:46:24 -07002914 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002915 self->hashcode = generic_hash(
2916 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07002917 }
Guido van Rossum254348e2007-11-21 19:29:53 +00002918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002919 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002920}
2921
2922static PyObject *
2923date_toordinal(PyDateTime_Date *self)
2924{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002925 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2926 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002927}
2928
2929static PyObject *
2930date_weekday(PyDateTime_Date *self)
2931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002932 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002934 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002935}
2936
Tim Peters371935f2003-02-01 01:52:50 +00002937/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002938
Tim Petersb57f8f02003-02-01 02:54:15 +00002939/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002940static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002941date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002942{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002943 PyObject* field;
2944 field = PyBytes_FromStringAndSize((char*)self->data,
2945 _PyDateTime_DATE_DATASIZE);
2946 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002947}
2948
2949static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002950date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002952 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002953}
2954
2955static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002957 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002959 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2960 METH_CLASS,
2961 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2962 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002964 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2965 METH_CLASS,
2966 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2967 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002969 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2970 PyDoc_STR("Current date or datetime: same as "
2971 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002973 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002975 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2976 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002978 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2979 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002981 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2982 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002984 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2985 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002987 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2988 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2989 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002991 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2992 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002994 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2995 PyDoc_STR("Return the day of the week represented by the date.\n"
2996 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002998 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2999 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3000 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003002 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3003 PyDoc_STR("Return the day of the week represented by the date.\n"
3004 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003006 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3007 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003009 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3010 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003012 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003013};
3014
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003015static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003016PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003017
3018static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003019 date_add, /* nb_add */
3020 date_subtract, /* nb_subtract */
3021 0, /* nb_multiply */
3022 0, /* nb_remainder */
3023 0, /* nb_divmod */
3024 0, /* nb_power */
3025 0, /* nb_negative */
3026 0, /* nb_positive */
3027 0, /* nb_absolute */
3028 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003029};
3030
3031static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003032 PyVarObject_HEAD_INIT(NULL, 0)
3033 "datetime.date", /* tp_name */
3034 sizeof(PyDateTime_Date), /* tp_basicsize */
3035 0, /* tp_itemsize */
3036 0, /* tp_dealloc */
3037 0, /* tp_print */
3038 0, /* tp_getattr */
3039 0, /* tp_setattr */
3040 0, /* tp_reserved */
3041 (reprfunc)date_repr, /* tp_repr */
3042 &date_as_number, /* tp_as_number */
3043 0, /* tp_as_sequence */
3044 0, /* tp_as_mapping */
3045 (hashfunc)date_hash, /* tp_hash */
3046 0, /* tp_call */
3047 (reprfunc)date_str, /* tp_str */
3048 PyObject_GenericGetAttr, /* tp_getattro */
3049 0, /* tp_setattro */
3050 0, /* tp_as_buffer */
3051 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3052 date_doc, /* tp_doc */
3053 0, /* tp_traverse */
3054 0, /* tp_clear */
3055 date_richcompare, /* tp_richcompare */
3056 0, /* tp_weaklistoffset */
3057 0, /* tp_iter */
3058 0, /* tp_iternext */
3059 date_methods, /* tp_methods */
3060 0, /* tp_members */
3061 date_getset, /* tp_getset */
3062 0, /* tp_base */
3063 0, /* tp_dict */
3064 0, /* tp_descr_get */
3065 0, /* tp_descr_set */
3066 0, /* tp_dictoffset */
3067 0, /* tp_init */
3068 0, /* tp_alloc */
3069 date_new, /* tp_new */
3070 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003071};
3072
3073/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003074 * PyDateTime_TZInfo implementation.
3075 */
3076
3077/* This is a pure abstract base class, so doesn't do anything beyond
3078 * raising NotImplemented exceptions. Real tzinfo classes need
3079 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003080 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003081 * be subclasses of this tzinfo class, which is easy and quick to check).
3082 *
3083 * Note: For reasons having to do with pickling of subclasses, we have
3084 * to allow tzinfo objects to be instantiated. This wasn't an issue
3085 * in the Python implementation (__init__() could raise NotImplementedError
3086 * there without ill effect), but doing so in the C implementation hit a
3087 * brick wall.
3088 */
3089
3090static PyObject *
3091tzinfo_nogo(const char* methodname)
3092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003093 PyErr_Format(PyExc_NotImplementedError,
3094 "a tzinfo subclass must implement %s()",
3095 methodname);
3096 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003097}
3098
3099/* Methods. A subclass must implement these. */
3100
Tim Peters52dcce22003-01-23 16:36:11 +00003101static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003102tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003104 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003105}
3106
Tim Peters52dcce22003-01-23 16:36:11 +00003107static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003108tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3109{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003111}
3112
Tim Peters52dcce22003-01-23 16:36:11 +00003113static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003114tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003116 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003117}
3118
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003119
3120static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3121 PyDateTime_Delta *delta,
3122 int factor);
3123static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3124static PyObject *datetime_dst(PyObject *self, PyObject *);
3125
Tim Peters52dcce22003-01-23 16:36:11 +00003126static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003127tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003128{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003129 PyObject *result = NULL;
3130 PyObject *off = NULL, *dst = NULL;
3131 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003132
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003133 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003134 PyErr_SetString(PyExc_TypeError,
3135 "fromutc: argument must be a datetime");
3136 return NULL;
3137 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003138 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3140 "is not self");
3141 return NULL;
3142 }
Tim Peters52dcce22003-01-23 16:36:11 +00003143
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003144 off = datetime_utcoffset(dt, NULL);
3145 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003146 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003147 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003148 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3149 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003150 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003151 }
Tim Peters52dcce22003-01-23 16:36:11 +00003152
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003153 dst = datetime_dst(dt, NULL);
3154 if (dst == NULL)
3155 goto Fail;
3156 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003157 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3158 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003159 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003160 }
Tim Peters52dcce22003-01-23 16:36:11 +00003161
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003162 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3163 if (delta == NULL)
3164 goto Fail;
3165 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003166 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003167 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003168
3169 Py_DECREF(dst);
3170 dst = call_dst(GET_DT_TZINFO(dt), result);
3171 if (dst == NULL)
3172 goto Fail;
3173 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003174 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003175 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003176 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003177 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003178 if (result == NULL)
3179 goto Fail;
3180 }
3181 Py_DECREF(delta);
3182 Py_DECREF(dst);
3183 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003184 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003185
3186Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003187 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3188 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003190 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003191Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003192 Py_XDECREF(off);
3193 Py_XDECREF(dst);
3194 Py_XDECREF(delta);
3195 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003196 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003197}
3198
Tim Peters2a799bf2002-12-16 20:18:38 +00003199/*
3200 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003201 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003202 */
3203
Guido van Rossum177e41a2003-01-30 22:06:23 +00003204static PyObject *
3205tzinfo_reduce(PyObject *self)
3206{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003207 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003209 _Py_IDENTIFIER(__getinitargs__);
3210 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003211
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003212 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003213 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003214 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 Py_DECREF(getinitargs);
3216 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 return NULL;
3218 }
3219 }
3220 else {
3221 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003222
3223 args = PyTuple_New(0);
3224 if (args == NULL) {
3225 return NULL;
3226 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003227 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003228
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003229 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003230 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003231 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003232 Py_DECREF(getstate);
3233 if (state == NULL) {
3234 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003235 return NULL;
3236 }
3237 }
3238 else {
3239 PyObject **dictptr;
3240 PyErr_Clear();
3241 state = Py_None;
3242 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003243 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003244 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003245 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003246 Py_INCREF(state);
3247 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003249 if (state == Py_None) {
3250 Py_DECREF(state);
3251 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3252 }
3253 else
3254 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003255}
Tim Peters2a799bf2002-12-16 20:18:38 +00003256
3257static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003259 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3260 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003262 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003263 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3264 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003266 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003267 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003269 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003270 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003272 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3273 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003275 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003276};
3277
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003278static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003279PyDoc_STR("Abstract base class for time zone info objects.");
3280
Neal Norwitz227b5332006-03-22 09:28:35 +00003281static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003282 PyVarObject_HEAD_INIT(NULL, 0)
3283 "datetime.tzinfo", /* tp_name */
3284 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3285 0, /* tp_itemsize */
3286 0, /* tp_dealloc */
3287 0, /* tp_print */
3288 0, /* tp_getattr */
3289 0, /* tp_setattr */
3290 0, /* tp_reserved */
3291 0, /* tp_repr */
3292 0, /* tp_as_number */
3293 0, /* tp_as_sequence */
3294 0, /* tp_as_mapping */
3295 0, /* tp_hash */
3296 0, /* tp_call */
3297 0, /* tp_str */
3298 PyObject_GenericGetAttr, /* tp_getattro */
3299 0, /* tp_setattro */
3300 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003301 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003302 tzinfo_doc, /* tp_doc */
3303 0, /* tp_traverse */
3304 0, /* tp_clear */
3305 0, /* tp_richcompare */
3306 0, /* tp_weaklistoffset */
3307 0, /* tp_iter */
3308 0, /* tp_iternext */
3309 tzinfo_methods, /* tp_methods */
3310 0, /* tp_members */
3311 0, /* tp_getset */
3312 0, /* tp_base */
3313 0, /* tp_dict */
3314 0, /* tp_descr_get */
3315 0, /* tp_descr_set */
3316 0, /* tp_dictoffset */
3317 0, /* tp_init */
3318 0, /* tp_alloc */
3319 PyType_GenericNew, /* tp_new */
3320 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003321};
3322
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003323static char *timezone_kws[] = {"offset", "name", NULL};
3324
3325static PyObject *
3326timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3327{
3328 PyObject *offset;
3329 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003330 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3331 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003332 return new_timezone(offset, name);
3333
3334 return NULL;
3335}
3336
3337static void
3338timezone_dealloc(PyDateTime_TimeZone *self)
3339{
3340 Py_CLEAR(self->offset);
3341 Py_CLEAR(self->name);
3342 Py_TYPE(self)->tp_free((PyObject *)self);
3343}
3344
3345static PyObject *
3346timezone_richcompare(PyDateTime_TimeZone *self,
3347 PyDateTime_TimeZone *other, int op)
3348{
Brian Curtindfc80e32011-08-10 20:28:54 -05003349 if (op != Py_EQ && op != Py_NE)
3350 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003351 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003352 if (op == Py_EQ)
3353 Py_RETURN_FALSE;
3354 else
3355 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003356 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003357 return delta_richcompare(self->offset, other->offset, op);
3358}
3359
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003360static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003361timezone_hash(PyDateTime_TimeZone *self)
3362{
3363 return delta_hash((PyDateTime_Delta *)self->offset);
3364}
3365
3366/* Check argument type passed to tzname, utcoffset, or dst methods.
3367 Returns 0 for good argument. Returns -1 and sets exception info
3368 otherwise.
3369 */
3370static int
3371_timezone_check_argument(PyObject *dt, const char *meth)
3372{
3373 if (dt == Py_None || PyDateTime_Check(dt))
3374 return 0;
3375 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3376 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3377 return -1;
3378}
3379
3380static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003381timezone_repr(PyDateTime_TimeZone *self)
3382{
3383 /* Note that although timezone is not subclassable, it is convenient
3384 to use Py_TYPE(self)->tp_name here. */
3385 const char *type_name = Py_TYPE(self)->tp_name;
3386
3387 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3388 return PyUnicode_FromFormat("%s.utc", type_name);
3389
3390 if (self->name == NULL)
3391 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3392
3393 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3394 self->name);
3395}
3396
3397
3398static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003399timezone_str(PyDateTime_TimeZone *self)
3400{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003401 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003402 PyObject *offset;
3403 char sign;
3404
3405 if (self->name != NULL) {
3406 Py_INCREF(self->name);
3407 return self->name;
3408 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003409 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003410 (GET_TD_DAYS(self->offset) == 0 &&
3411 GET_TD_SECONDS(self->offset) == 0 &&
3412 GET_TD_MICROSECONDS(self->offset) == 0))
3413 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003414 /* Offset is normalized, so it is negative if days < 0 */
3415 if (GET_TD_DAYS(self->offset) < 0) {
3416 sign = '-';
3417 offset = delta_negative((PyDateTime_Delta *)self->offset);
3418 if (offset == NULL)
3419 return NULL;
3420 }
3421 else {
3422 sign = '+';
3423 offset = self->offset;
3424 Py_INCREF(offset);
3425 }
3426 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003427 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003428 seconds = GET_TD_SECONDS(offset);
3429 Py_DECREF(offset);
3430 minutes = divmod(seconds, 60, &seconds);
3431 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003432 if (microseconds != 0) {
3433 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3434 sign, hours, minutes,
3435 seconds, microseconds);
3436 }
3437 if (seconds != 0) {
3438 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3439 sign, hours, minutes, seconds);
3440 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003441 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003442}
3443
3444static PyObject *
3445timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3446{
3447 if (_timezone_check_argument(dt, "tzname") == -1)
3448 return NULL;
3449
3450 return timezone_str(self);
3451}
3452
3453static PyObject *
3454timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3455{
3456 if (_timezone_check_argument(dt, "utcoffset") == -1)
3457 return NULL;
3458
3459 Py_INCREF(self->offset);
3460 return self->offset;
3461}
3462
3463static PyObject *
3464timezone_dst(PyObject *self, PyObject *dt)
3465{
3466 if (_timezone_check_argument(dt, "dst") == -1)
3467 return NULL;
3468
3469 Py_RETURN_NONE;
3470}
3471
3472static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003473timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3474{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003475 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003476 PyErr_SetString(PyExc_TypeError,
3477 "fromutc: argument must be a datetime");
3478 return NULL;
3479 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003480 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003481 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3482 "is not self");
3483 return NULL;
3484 }
3485
3486 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3487}
3488
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003489static PyObject *
3490timezone_getinitargs(PyDateTime_TimeZone *self)
3491{
3492 if (self->name == NULL)
3493 return Py_BuildValue("(O)", self->offset);
3494 return Py_BuildValue("(OO)", self->offset, self->name);
3495}
3496
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003497static PyMethodDef timezone_methods[] = {
3498 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3499 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003500 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003501
3502 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003503 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003504
3505 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003506 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003507
3508 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3509 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3510
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003511 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3512 PyDoc_STR("pickle support")},
3513
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003514 {NULL, NULL}
3515};
3516
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003517static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003518PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3519
3520static PyTypeObject PyDateTime_TimeZoneType = {
3521 PyVarObject_HEAD_INIT(NULL, 0)
3522 "datetime.timezone", /* tp_name */
3523 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3524 0, /* tp_itemsize */
3525 (destructor)timezone_dealloc, /* tp_dealloc */
3526 0, /* tp_print */
3527 0, /* tp_getattr */
3528 0, /* tp_setattr */
3529 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003530 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003531 0, /* tp_as_number */
3532 0, /* tp_as_sequence */
3533 0, /* tp_as_mapping */
3534 (hashfunc)timezone_hash, /* tp_hash */
3535 0, /* tp_call */
3536 (reprfunc)timezone_str, /* tp_str */
3537 0, /* tp_getattro */
3538 0, /* tp_setattro */
3539 0, /* tp_as_buffer */
3540 Py_TPFLAGS_DEFAULT, /* tp_flags */
3541 timezone_doc, /* tp_doc */
3542 0, /* tp_traverse */
3543 0, /* tp_clear */
3544 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3545 0, /* tp_weaklistoffset */
3546 0, /* tp_iter */
3547 0, /* tp_iternext */
3548 timezone_methods, /* tp_methods */
3549 0, /* tp_members */
3550 0, /* tp_getset */
3551 &PyDateTime_TZInfoType, /* tp_base */
3552 0, /* tp_dict */
3553 0, /* tp_descr_get */
3554 0, /* tp_descr_set */
3555 0, /* tp_dictoffset */
3556 0, /* tp_init */
3557 0, /* tp_alloc */
3558 timezone_new, /* tp_new */
3559};
3560
Tim Peters2a799bf2002-12-16 20:18:38 +00003561/*
Tim Peters37f39822003-01-10 03:49:02 +00003562 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003563 */
3564
Tim Peters37f39822003-01-10 03:49:02 +00003565/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003566 */
3567
3568static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003569time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003570{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003571 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003572}
3573
Tim Peters37f39822003-01-10 03:49:02 +00003574static PyObject *
3575time_minute(PyDateTime_Time *self, void *unused)
3576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003577 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003578}
3579
3580/* The name time_second conflicted with some platform header file. */
3581static PyObject *
3582py_time_second(PyDateTime_Time *self, void *unused)
3583{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003584 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003585}
3586
3587static PyObject *
3588time_microsecond(PyDateTime_Time *self, void *unused)
3589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003590 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003591}
3592
3593static PyObject *
3594time_tzinfo(PyDateTime_Time *self, void *unused)
3595{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003596 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3597 Py_INCREF(result);
3598 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003599}
3600
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003601static PyObject *
3602time_fold(PyDateTime_Time *self, void *unused)
3603{
3604 return PyLong_FromLong(TIME_GET_FOLD(self));
3605}
3606
Tim Peters37f39822003-01-10 03:49:02 +00003607static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003608 {"hour", (getter)time_hour},
3609 {"minute", (getter)time_minute},
3610 {"second", (getter)py_time_second},
3611 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003612 {"tzinfo", (getter)time_tzinfo},
3613 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003614 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003615};
3616
3617/*
3618 * Constructors.
3619 */
3620
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003621static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003622 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003623
Tim Peters2a799bf2002-12-16 20:18:38 +00003624static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003625time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003627 PyObject *self = NULL;
3628 PyObject *state;
3629 int hour = 0;
3630 int minute = 0;
3631 int second = 0;
3632 int usecond = 0;
3633 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003634 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003636 /* Check for invocation from pickle with __getstate__ state */
3637 if (PyTuple_GET_SIZE(args) >= 1 &&
3638 PyTuple_GET_SIZE(args) <= 2 &&
3639 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3640 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003641 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003642 {
3643 PyDateTime_Time *me;
3644 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003646 if (PyTuple_GET_SIZE(args) == 2) {
3647 tzinfo = PyTuple_GET_ITEM(args, 1);
3648 if (check_tzinfo_subclass(tzinfo) < 0) {
3649 PyErr_SetString(PyExc_TypeError, "bad "
3650 "tzinfo state arg");
3651 return NULL;
3652 }
3653 }
3654 aware = (char)(tzinfo != Py_None);
3655 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3656 if (me != NULL) {
3657 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003659 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3660 me->hashcode = -1;
3661 me->hastzinfo = aware;
3662 if (aware) {
3663 Py_INCREF(tzinfo);
3664 me->tzinfo = tzinfo;
3665 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003666 if (pdata[0] & (1 << 7)) {
3667 me->data[0] -= 128;
3668 me->fold = 1;
3669 }
3670 else {
3671 me->fold = 0;
3672 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003673 }
3674 return (PyObject *)me;
3675 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003676
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003677 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003678 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003679 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003680 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3681 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003682 }
3683 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003684}
3685
3686/*
3687 * Destructor.
3688 */
3689
3690static void
Tim Peters37f39822003-01-10 03:49:02 +00003691time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003692{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003693 if (HASTZINFO(self)) {
3694 Py_XDECREF(self->tzinfo);
3695 }
3696 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003697}
3698
3699/*
Tim Peters855fe882002-12-22 03:43:39 +00003700 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003701 */
3702
Tim Peters2a799bf2002-12-16 20:18:38 +00003703/* These are all METH_NOARGS, so don't need to check the arglist. */
3704static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003705time_utcoffset(PyObject *self, PyObject *unused) {
3706 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003707}
3708
3709static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003710time_dst(PyObject *self, PyObject *unused) {
3711 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003712}
3713
3714static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003715time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003716 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003717}
3718
3719/*
Tim Peters37f39822003-01-10 03:49:02 +00003720 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003721 */
3722
3723static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003724time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003726 const char *type_name = Py_TYPE(self)->tp_name;
3727 int h = TIME_GET_HOUR(self);
3728 int m = TIME_GET_MINUTE(self);
3729 int s = TIME_GET_SECOND(self);
3730 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003731 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003732 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003734 if (us)
3735 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3736 type_name, h, m, s, us);
3737 else if (s)
3738 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3739 type_name, h, m, s);
3740 else
3741 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3742 if (result != NULL && HASTZINFO(self))
3743 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003744 if (result != NULL && fold)
3745 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003746 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003747}
3748
Tim Peters37f39822003-01-10 03:49:02 +00003749static PyObject *
3750time_str(PyDateTime_Time *self)
3751{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003752 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003753}
Tim Peters2a799bf2002-12-16 20:18:38 +00003754
3755static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003756time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003758 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003759 char *timespec = NULL;
3760 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003761 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003762 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003763 static char *specs[][2] = {
3764 {"hours", "%02d"},
3765 {"minutes", "%02d:%02d"},
3766 {"seconds", "%02d:%02d:%02d"},
3767 {"milliseconds", "%02d:%02d:%02d.%03d"},
3768 {"microseconds", "%02d:%02d:%02d.%06d"},
3769 };
3770 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003771
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003772 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3773 return NULL;
3774
3775 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3776 if (us == 0) {
3777 /* seconds */
3778 given_spec = 2;
3779 }
3780 else {
3781 /* microseconds */
3782 given_spec = 4;
3783 }
3784 }
3785 else {
3786 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3787 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3788 if (given_spec == 3) {
3789 /* milliseconds */
3790 us = us / 1000;
3791 }
3792 break;
3793 }
3794 }
3795 }
3796
3797 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3798 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3799 return NULL;
3800 }
3801 else {
3802 result = PyUnicode_FromFormat(specs[given_spec][1],
3803 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3804 TIME_GET_SECOND(self), us);
3805 }
Tim Peters37f39822003-01-10 03:49:02 +00003806
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003807 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003808 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003810 /* We need to append the UTC offset. */
3811 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3812 Py_None) < 0) {
3813 Py_DECREF(result);
3814 return NULL;
3815 }
3816 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3817 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003818}
3819
Tim Peters37f39822003-01-10 03:49:02 +00003820static PyObject *
3821time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003823 PyObject *result;
3824 PyObject *tuple;
3825 PyObject *format;
3826 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003828 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3829 &format))
3830 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003832 /* Python's strftime does insane things with the year part of the
3833 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003834 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 */
3836 tuple = Py_BuildValue("iiiiiiiii",
3837 1900, 1, 1, /* year, month, day */
3838 TIME_GET_HOUR(self),
3839 TIME_GET_MINUTE(self),
3840 TIME_GET_SECOND(self),
3841 0, 1, -1); /* weekday, daynum, dst */
3842 if (tuple == NULL)
3843 return NULL;
3844 assert(PyTuple_Size(tuple) == 9);
3845 result = wrap_strftime((PyObject *)self, format, tuple,
3846 Py_None);
3847 Py_DECREF(tuple);
3848 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003849}
Tim Peters2a799bf2002-12-16 20:18:38 +00003850
3851/*
3852 * Miscellaneous methods.
3853 */
3854
Tim Peters37f39822003-01-10 03:49:02 +00003855static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003856time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003857{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003858 PyObject *result = NULL;
3859 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003860 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003861
Brian Curtindfc80e32011-08-10 20:28:54 -05003862 if (! PyTime_Check(other))
3863 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003864
3865 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003866 diff = memcmp(((PyDateTime_Time *)self)->data,
3867 ((PyDateTime_Time *)other)->data,
3868 _PyDateTime_TIME_DATASIZE);
3869 return diff_to_bool(diff, op);
3870 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003871 offset1 = time_utcoffset(self, NULL);
3872 if (offset1 == NULL)
3873 return NULL;
3874 offset2 = time_utcoffset(other, NULL);
3875 if (offset2 == NULL)
3876 goto done;
3877 /* If they're both naive, or both aware and have the same offsets,
3878 * we get off cheap. Note that if they're both naive, offset1 ==
3879 * offset2 == Py_None at this point.
3880 */
3881 if ((offset1 == offset2) ||
3882 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3883 delta_cmp(offset1, offset2) == 0)) {
3884 diff = memcmp(((PyDateTime_Time *)self)->data,
3885 ((PyDateTime_Time *)other)->data,
3886 _PyDateTime_TIME_DATASIZE);
3887 result = diff_to_bool(diff, op);
3888 }
3889 /* The hard case: both aware with different UTC offsets */
3890 else if (offset1 != Py_None && offset2 != Py_None) {
3891 int offsecs1, offsecs2;
3892 assert(offset1 != offset2); /* else last "if" handled it */
3893 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3894 TIME_GET_MINUTE(self) * 60 +
3895 TIME_GET_SECOND(self) -
3896 GET_TD_DAYS(offset1) * 86400 -
3897 GET_TD_SECONDS(offset1);
3898 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3899 TIME_GET_MINUTE(other) * 60 +
3900 TIME_GET_SECOND(other) -
3901 GET_TD_DAYS(offset2) * 86400 -
3902 GET_TD_SECONDS(offset2);
3903 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003904 if (diff == 0)
3905 diff = TIME_GET_MICROSECOND(self) -
3906 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003907 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003908 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003909 else if (op == Py_EQ) {
3910 result = Py_False;
3911 Py_INCREF(result);
3912 }
3913 else if (op == Py_NE) {
3914 result = Py_True;
3915 Py_INCREF(result);
3916 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003917 else {
3918 PyErr_SetString(PyExc_TypeError,
3919 "can't compare offset-naive and "
3920 "offset-aware times");
3921 }
3922 done:
3923 Py_DECREF(offset1);
3924 Py_XDECREF(offset2);
3925 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003926}
3927
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003928static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003929time_hash(PyDateTime_Time *self)
3930{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003931 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003932 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01003933 if (TIME_GET_FOLD(self)) {
3934 self0 = new_time_ex2(TIME_GET_HOUR(self),
3935 TIME_GET_MINUTE(self),
3936 TIME_GET_SECOND(self),
3937 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003938 HASTZINFO(self) ? self->tzinfo : Py_None,
3939 0, Py_TYPE(self));
3940 if (self0 == NULL)
3941 return -1;
3942 }
3943 else {
3944 self0 = (PyObject *)self;
3945 Py_INCREF(self0);
3946 }
3947 offset = time_utcoffset(self0, NULL);
3948 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003949
3950 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003951 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003953 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003954 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003955 self->hashcode = generic_hash(
3956 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003957 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003958 PyObject *temp1, *temp2;
3959 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003960 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003961 seconds = TIME_GET_HOUR(self) * 3600 +
3962 TIME_GET_MINUTE(self) * 60 +
3963 TIME_GET_SECOND(self);
3964 microseconds = TIME_GET_MICROSECOND(self);
3965 temp1 = new_delta(0, seconds, microseconds, 1);
3966 if (temp1 == NULL) {
3967 Py_DECREF(offset);
3968 return -1;
3969 }
3970 temp2 = delta_subtract(temp1, offset);
3971 Py_DECREF(temp1);
3972 if (temp2 == NULL) {
3973 Py_DECREF(offset);
3974 return -1;
3975 }
3976 self->hashcode = PyObject_Hash(temp2);
3977 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003979 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 }
3981 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003982}
Tim Peters2a799bf2002-12-16 20:18:38 +00003983
Tim Peters12bf3392002-12-24 05:41:27 +00003984static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003985time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003987 PyObject *clone;
3988 PyObject *tuple;
3989 int hh = TIME_GET_HOUR(self);
3990 int mm = TIME_GET_MINUTE(self);
3991 int ss = TIME_GET_SECOND(self);
3992 int us = TIME_GET_MICROSECOND(self);
3993 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003994 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003995
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003996 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003997 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003998 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003999 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03004000 if (fold != 0 && fold != 1) {
4001 PyErr_SetString(PyExc_ValueError,
4002 "fold must be either 0 or 1");
4003 return NULL;
4004 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004005 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
4006 if (tuple == NULL)
4007 return NULL;
4008 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004009 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004010 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004011 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004012 Py_DECREF(tuple);
4013 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004014}
4015
Tim Peters371935f2003-02-01 01:52:50 +00004016/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00004017
Tim Peters33e0f382003-01-10 02:05:14 +00004018/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004019 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4020 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004021 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004022 */
4023static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004024time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00004025{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004026 PyObject *basestate;
4027 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004029 basestate = PyBytes_FromStringAndSize((char *)self->data,
4030 _PyDateTime_TIME_DATASIZE);
4031 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004032 if (proto > 3 && TIME_GET_FOLD(self))
4033 /* Set the first bit of the first byte */
4034 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004035 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4036 result = PyTuple_Pack(1, basestate);
4037 else
4038 result = PyTuple_Pack(2, basestate, self->tzinfo);
4039 Py_DECREF(basestate);
4040 }
4041 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004042}
4043
4044static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004045time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004046{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004047 int proto;
4048 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004049 return NULL;
4050
4051 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004052}
4053
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004054static PyObject *
4055time_reduce(PyDateTime_Time *self, PyObject *arg)
4056{
4057 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4058}
4059
Tim Peters37f39822003-01-10 03:49:02 +00004060static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004061
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004062 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4063 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4064 "[+HH:MM].\n\n"
4065 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004067 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4068 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004070 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4071 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004073 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4074 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004076 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4077 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004079 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4080 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004082 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4083 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004084
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004085 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004086 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004087
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004088 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4089 PyDoc_STR("__reduce__() -> (cls, state)")},
4090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004091 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004092};
4093
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004094static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004095PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4096\n\
4097All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004098a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004099
Neal Norwitz227b5332006-03-22 09:28:35 +00004100static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004101 PyVarObject_HEAD_INIT(NULL, 0)
4102 "datetime.time", /* tp_name */
4103 sizeof(PyDateTime_Time), /* tp_basicsize */
4104 0, /* tp_itemsize */
4105 (destructor)time_dealloc, /* tp_dealloc */
4106 0, /* tp_print */
4107 0, /* tp_getattr */
4108 0, /* tp_setattr */
4109 0, /* tp_reserved */
4110 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004111 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004112 0, /* tp_as_sequence */
4113 0, /* tp_as_mapping */
4114 (hashfunc)time_hash, /* tp_hash */
4115 0, /* tp_call */
4116 (reprfunc)time_str, /* tp_str */
4117 PyObject_GenericGetAttr, /* tp_getattro */
4118 0, /* tp_setattro */
4119 0, /* tp_as_buffer */
4120 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4121 time_doc, /* tp_doc */
4122 0, /* tp_traverse */
4123 0, /* tp_clear */
4124 time_richcompare, /* tp_richcompare */
4125 0, /* tp_weaklistoffset */
4126 0, /* tp_iter */
4127 0, /* tp_iternext */
4128 time_methods, /* tp_methods */
4129 0, /* tp_members */
4130 time_getset, /* tp_getset */
4131 0, /* tp_base */
4132 0, /* tp_dict */
4133 0, /* tp_descr_get */
4134 0, /* tp_descr_set */
4135 0, /* tp_dictoffset */
4136 0, /* tp_init */
4137 time_alloc, /* tp_alloc */
4138 time_new, /* tp_new */
4139 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004140};
4141
4142/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004143 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004144 */
4145
Tim Petersa9bc1682003-01-11 03:39:11 +00004146/* Accessor properties. Properties for day, month, and year are inherited
4147 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004148 */
4149
4150static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004151datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004153 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004154}
4155
Tim Petersa9bc1682003-01-11 03:39:11 +00004156static PyObject *
4157datetime_minute(PyDateTime_DateTime *self, void *unused)
4158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004159 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004160}
4161
4162static PyObject *
4163datetime_second(PyDateTime_DateTime *self, void *unused)
4164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004165 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004166}
4167
4168static PyObject *
4169datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004171 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004172}
4173
4174static PyObject *
4175datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4178 Py_INCREF(result);
4179 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004180}
4181
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004182static PyObject *
4183datetime_fold(PyDateTime_DateTime *self, void *unused)
4184{
4185 return PyLong_FromLong(DATE_GET_FOLD(self));
4186}
4187
Tim Petersa9bc1682003-01-11 03:39:11 +00004188static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004189 {"hour", (getter)datetime_hour},
4190 {"minute", (getter)datetime_minute},
4191 {"second", (getter)datetime_second},
4192 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004193 {"tzinfo", (getter)datetime_tzinfo},
4194 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004195 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004196};
4197
4198/*
4199 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004200 */
4201
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004202static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004203 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004204 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004205};
4206
Tim Peters2a799bf2002-12-16 20:18:38 +00004207static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004208datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004210 PyObject *self = NULL;
4211 PyObject *state;
4212 int year;
4213 int month;
4214 int day;
4215 int hour = 0;
4216 int minute = 0;
4217 int second = 0;
4218 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004219 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004220 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004222 /* Check for invocation from pickle with __getstate__ state */
4223 if (PyTuple_GET_SIZE(args) >= 1 &&
4224 PyTuple_GET_SIZE(args) <= 2 &&
4225 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4226 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004227 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004228 {
4229 PyDateTime_DateTime *me;
4230 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 if (PyTuple_GET_SIZE(args) == 2) {
4233 tzinfo = PyTuple_GET_ITEM(args, 1);
4234 if (check_tzinfo_subclass(tzinfo) < 0) {
4235 PyErr_SetString(PyExc_TypeError, "bad "
4236 "tzinfo state arg");
4237 return NULL;
4238 }
4239 }
4240 aware = (char)(tzinfo != Py_None);
4241 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4242 if (me != NULL) {
4243 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004245 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4246 me->hashcode = -1;
4247 me->hastzinfo = aware;
4248 if (aware) {
4249 Py_INCREF(tzinfo);
4250 me->tzinfo = tzinfo;
4251 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004252 if (pdata[2] & (1 << 7)) {
4253 me->data[2] -= 128;
4254 me->fold = 1;
4255 }
4256 else {
4257 me->fold = 0;
4258 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004259 }
4260 return (PyObject *)me;
4261 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004262
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004263 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004264 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004265 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004266 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004267 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004268 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004269 }
4270 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004271}
4272
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004273/* TM_FUNC is the shared type of _PyTime_localtime() and
4274 * _PyTime_gmtime(). */
4275typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004276
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004277/* As of version 2015f max fold in IANA database is
4278 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004279static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004280/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004281static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004282
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004283static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004284utc_to_seconds(int year, int month, int day,
4285 int hour, int minute, int second)
4286{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004287 long long ordinal;
4288
4289 /* ymd_to_ord() doesn't support year <= 0 */
4290 if (year < MINYEAR || year > MAXYEAR) {
4291 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4292 return -1;
4293 }
4294
4295 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004296 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4297}
4298
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004299static long long
4300local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004301{
4302 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004303 time_t t;
4304 u -= epoch;
4305 t = u;
4306 if (t != u) {
4307 PyErr_SetString(PyExc_OverflowError,
4308 "timestamp out of range for platform time_t");
4309 return -1;
4310 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004311 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004312 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004313 return utc_to_seconds(local_time.tm_year + 1900,
4314 local_time.tm_mon + 1,
4315 local_time.tm_mday,
4316 local_time.tm_hour,
4317 local_time.tm_min,
4318 local_time.tm_sec);
4319}
4320
Tim Petersa9bc1682003-01-11 03:39:11 +00004321/* Internal helper.
4322 * Build datetime from a time_t and a distinct count of microseconds.
4323 * Pass localtime or gmtime for f, to control the interpretation of timet.
4324 */
4325static PyObject *
4326datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004327 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004328{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004329 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004330 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004331
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004332 if (f(timet, &tm) != 0)
4333 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004334
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004335 year = tm.tm_year + 1900;
4336 month = tm.tm_mon + 1;
4337 day = tm.tm_mday;
4338 hour = tm.tm_hour;
4339 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004340 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004341 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004342 * except to the extent that passing them on to the datetime
4343 * constructor would raise ValueError for a reason that
4344 * made no sense to the user.
4345 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004346 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004347
Victor Stinnerb67f0962017-02-10 10:34:02 +01004348 /* local timezone requires to compute fold */
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004349 if (tzinfo == Py_None && f == _PyTime_localtime) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004350 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004351
4352 result_seconds = utc_to_seconds(year, month, day,
4353 hour, minute, second);
4354 /* Probe max_fold_seconds to detect a fold. */
4355 probe_seconds = local(epoch + timet - max_fold_seconds);
4356 if (probe_seconds == -1)
4357 return NULL;
4358 transition = result_seconds - probe_seconds - max_fold_seconds;
4359 if (transition < 0) {
4360 probe_seconds = local(epoch + timet + transition);
4361 if (probe_seconds == -1)
4362 return NULL;
4363 if (probe_seconds == result_seconds)
4364 fold = 1;
4365 }
4366 }
4367 return new_datetime_ex2(year, month, day, hour,
4368 minute, second, us, tzinfo, fold,
4369 (PyTypeObject *)cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004370}
4371
4372/* Internal helper.
4373 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4374 * to control the interpretation of the timestamp. Since a double doesn't
4375 * have enough bits to cover a datetime's full range of precision, it's
4376 * better to call datetime_from_timet_and_us provided you have a way
4377 * to get that much precision (e.g., C time() isn't good enough).
4378 */
4379static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004380datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004381 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004383 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004384 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004385
Victor Stinnere4a994d2015-03-30 01:10:14 +02004386 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004387 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004388 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004389
Victor Stinner21f58932012-03-14 00:15:40 +01004390 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004391}
4392
4393/* Internal helper.
4394 * Build most accurate possible datetime for current time. Pass localtime or
4395 * gmtime for f as appropriate.
4396 */
4397static PyObject *
4398datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4399{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004400 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004401 time_t secs;
4402 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004403
Victor Stinner1e2b6882015-09-18 13:23:02 +02004404 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004405 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004406 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004407
Victor Stinner1e2b6882015-09-18 13:23:02 +02004408 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004409}
4410
Larry Hastings61272b72014-01-07 12:41:53 -08004411/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004412
4413@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004414datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004415
4416 tz: object = None
4417 Timezone object.
4418
4419Returns new datetime object representing current time local to tz.
4420
4421If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004422[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004423
Larry Hastings31826802013-10-19 00:09:25 -07004424static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004425datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004426/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004428 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004429
Larry Hastings31826802013-10-19 00:09:25 -07004430 /* Return best possible local time -- this isn't constrained by the
4431 * precision of a timestamp.
4432 */
4433 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004434 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004435
Larry Hastings5c661892014-01-24 06:17:25 -08004436 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004437 tz == Py_None ? _PyTime_localtime :
4438 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004439 tz);
4440 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004441 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004442 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004443 }
4444 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004445}
4446
Tim Petersa9bc1682003-01-11 03:39:11 +00004447/* Return best possible UTC time -- this isn't constrained by the
4448 * precision of a timestamp.
4449 */
4450static PyObject *
4451datetime_utcnow(PyObject *cls, PyObject *dummy)
4452{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004453 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004454}
4455
Tim Peters2a799bf2002-12-16 20:18:38 +00004456/* Return new local datetime from timestamp (Python timestamp -- a double). */
4457static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004458datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004460 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004461 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004462 PyObject *tzinfo = Py_None;
4463 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004464
Victor Stinner5d272cc2012-03-13 13:35:55 +01004465 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004466 keywords, &timestamp, &tzinfo))
4467 return NULL;
4468 if (check_tzinfo_subclass(tzinfo) < 0)
4469 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004471 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004472 tzinfo == Py_None ? _PyTime_localtime :
4473 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004474 timestamp,
4475 tzinfo);
4476 if (self != NULL && tzinfo != Py_None) {
4477 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004478 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004479 }
4480 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004481}
4482
Tim Petersa9bc1682003-01-11 03:39:11 +00004483/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4484static PyObject *
4485datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4486{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004487 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004488 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004489
Victor Stinner5d272cc2012-03-13 13:35:55 +01004490 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004491 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004492 Py_None);
4493 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004494}
4495
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004496/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004497static PyObject *
4498datetime_strptime(PyObject *cls, PyObject *args)
4499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004500 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004501 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004502 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004503
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004504 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004505 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004506
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004507 if (module == NULL) {
4508 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004509 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004510 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004511 }
Victor Stinner20401de2016-12-09 15:24:31 +01004512 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4513 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004514}
4515
Tim Petersa9bc1682003-01-11 03:39:11 +00004516/* Return new datetime from date/datetime and time arguments. */
4517static PyObject *
4518datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4519{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004520 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004521 PyObject *date;
4522 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004523 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004524 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004525
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004526 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004527 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004528 &PyDateTime_TimeType, &time, &tzinfo)) {
4529 if (tzinfo == NULL) {
4530 if (HASTZINFO(time))
4531 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4532 else
4533 tzinfo = Py_None;
4534 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004535 result = PyObject_CallFunction(cls, "iiiiiiiO",
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004536 GET_YEAR(date),
4537 GET_MONTH(date),
4538 GET_DAY(date),
4539 TIME_GET_HOUR(time),
4540 TIME_GET_MINUTE(time),
4541 TIME_GET_SECOND(time),
4542 TIME_GET_MICROSECOND(time),
4543 tzinfo);
4544 if (result)
4545 DATE_SET_FOLD(result, TIME_GET_FOLD(time));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004546 }
4547 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004548}
Tim Peters2a799bf2002-12-16 20:18:38 +00004549
4550/*
4551 * Destructor.
4552 */
4553
4554static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004555datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004557 if (HASTZINFO(self)) {
4558 Py_XDECREF(self->tzinfo);
4559 }
4560 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004561}
4562
4563/*
4564 * Indirect access to tzinfo methods.
4565 */
4566
Tim Peters2a799bf2002-12-16 20:18:38 +00004567/* These are all METH_NOARGS, so don't need to check the arglist. */
4568static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004569datetime_utcoffset(PyObject *self, PyObject *unused) {
4570 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004571}
4572
4573static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004574datetime_dst(PyObject *self, PyObject *unused) {
4575 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004576}
4577
4578static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004579datetime_tzname(PyObject *self, PyObject *unused) {
4580 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004581}
4582
4583/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004584 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004585 */
4586
Tim Petersa9bc1682003-01-11 03:39:11 +00004587/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4588 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004589 */
4590static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004591add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004592 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004594 /* Note that the C-level additions can't overflow, because of
4595 * invariant bounds on the member values.
4596 */
4597 int year = GET_YEAR(date);
4598 int month = GET_MONTH(date);
4599 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4600 int hour = DATE_GET_HOUR(date);
4601 int minute = DATE_GET_MINUTE(date);
4602 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4603 int microsecond = DATE_GET_MICROSECOND(date) +
4604 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004606 assert(factor == 1 || factor == -1);
4607 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01004608 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004609 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01004610 }
4611
4612 return new_datetime(year, month, day,
4613 hour, minute, second, microsecond,
4614 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004615}
4616
4617static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004618datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004620 if (PyDateTime_Check(left)) {
4621 /* datetime + ??? */
4622 if (PyDelta_Check(right))
4623 /* datetime + delta */
4624 return add_datetime_timedelta(
4625 (PyDateTime_DateTime *)left,
4626 (PyDateTime_Delta *)right,
4627 1);
4628 }
4629 else if (PyDelta_Check(left)) {
4630 /* delta + datetime */
4631 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4632 (PyDateTime_Delta *) left,
4633 1);
4634 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004635 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004636}
4637
4638static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004639datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004641 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004643 if (PyDateTime_Check(left)) {
4644 /* datetime - ??? */
4645 if (PyDateTime_Check(right)) {
4646 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004647 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004648 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004649
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004650 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4651 offset2 = offset1 = Py_None;
4652 Py_INCREF(offset1);
4653 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004654 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004655 else {
4656 offset1 = datetime_utcoffset(left, NULL);
4657 if (offset1 == NULL)
4658 return NULL;
4659 offset2 = datetime_utcoffset(right, NULL);
4660 if (offset2 == NULL) {
4661 Py_DECREF(offset1);
4662 return NULL;
4663 }
4664 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4665 PyErr_SetString(PyExc_TypeError,
4666 "can't subtract offset-naive and "
4667 "offset-aware datetimes");
4668 Py_DECREF(offset1);
4669 Py_DECREF(offset2);
4670 return NULL;
4671 }
4672 }
4673 if ((offset1 != offset2) &&
4674 delta_cmp(offset1, offset2) != 0) {
4675 offdiff = delta_subtract(offset1, offset2);
4676 if (offdiff == NULL) {
4677 Py_DECREF(offset1);
4678 Py_DECREF(offset2);
4679 return NULL;
4680 }
4681 }
4682 Py_DECREF(offset1);
4683 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004684 delta_d = ymd_to_ord(GET_YEAR(left),
4685 GET_MONTH(left),
4686 GET_DAY(left)) -
4687 ymd_to_ord(GET_YEAR(right),
4688 GET_MONTH(right),
4689 GET_DAY(right));
4690 /* These can't overflow, since the values are
4691 * normalized. At most this gives the number of
4692 * seconds in one day.
4693 */
4694 delta_s = (DATE_GET_HOUR(left) -
4695 DATE_GET_HOUR(right)) * 3600 +
4696 (DATE_GET_MINUTE(left) -
4697 DATE_GET_MINUTE(right)) * 60 +
4698 (DATE_GET_SECOND(left) -
4699 DATE_GET_SECOND(right));
4700 delta_us = DATE_GET_MICROSECOND(left) -
4701 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004702 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004703 if (result == NULL)
4704 return NULL;
4705
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004706 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004707 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004708 Py_DECREF(offdiff);
4709 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004710 }
4711 else if (PyDelta_Check(right)) {
4712 /* datetime - delta */
4713 result = add_datetime_timedelta(
4714 (PyDateTime_DateTime *)left,
4715 (PyDateTime_Delta *)right,
4716 -1);
4717 }
4718 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004720 if (result == Py_NotImplemented)
4721 Py_INCREF(result);
4722 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004723}
4724
4725/* Various ways to turn a datetime into a string. */
4726
4727static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004728datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004730 const char *type_name = Py_TYPE(self)->tp_name;
4731 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004733 if (DATE_GET_MICROSECOND(self)) {
4734 baserepr = PyUnicode_FromFormat(
4735 "%s(%d, %d, %d, %d, %d, %d, %d)",
4736 type_name,
4737 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4738 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4739 DATE_GET_SECOND(self),
4740 DATE_GET_MICROSECOND(self));
4741 }
4742 else if (DATE_GET_SECOND(self)) {
4743 baserepr = PyUnicode_FromFormat(
4744 "%s(%d, %d, %d, %d, %d, %d)",
4745 type_name,
4746 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4747 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4748 DATE_GET_SECOND(self));
4749 }
4750 else {
4751 baserepr = PyUnicode_FromFormat(
4752 "%s(%d, %d, %d, %d, %d)",
4753 type_name,
4754 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4755 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4756 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004757 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4758 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004759 if (baserepr == NULL || ! HASTZINFO(self))
4760 return baserepr;
4761 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004762}
4763
Tim Petersa9bc1682003-01-11 03:39:11 +00004764static PyObject *
4765datetime_str(PyDateTime_DateTime *self)
4766{
Victor Stinner4c381542016-12-09 00:33:39 +01004767 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004768}
Tim Peters2a799bf2002-12-16 20:18:38 +00004769
4770static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004771datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004773 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004774 char *timespec = NULL;
4775 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004776 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004777 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004778 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004779 static char *specs[][2] = {
4780 {"hours", "%04d-%02d-%02d%c%02d"},
4781 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4782 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4783 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4784 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4785 };
4786 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004787
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004788 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004789 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004790
4791 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4792 if (us == 0) {
4793 /* seconds */
4794 given_spec = 2;
4795 }
4796 else {
4797 /* microseconds */
4798 given_spec = 4;
4799 }
4800 }
4801 else {
4802 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4803 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4804 if (given_spec == 3) {
4805 us = us / 1000;
4806 }
4807 break;
4808 }
4809 }
4810 }
4811
4812 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4813 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4814 return NULL;
4815 }
4816 else {
4817 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004818 GET_YEAR(self), GET_MONTH(self),
4819 GET_DAY(self), (int)sep,
4820 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4821 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004822 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004824 if (!result || !HASTZINFO(self))
4825 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004827 /* We need to append the UTC offset. */
4828 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4829 (PyObject *)self) < 0) {
4830 Py_DECREF(result);
4831 return NULL;
4832 }
4833 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4834 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004835}
4836
Tim Petersa9bc1682003-01-11 03:39:11 +00004837static PyObject *
4838datetime_ctime(PyDateTime_DateTime *self)
4839{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004840 return format_ctime((PyDateTime_Date *)self,
4841 DATE_GET_HOUR(self),
4842 DATE_GET_MINUTE(self),
4843 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004844}
4845
Tim Peters2a799bf2002-12-16 20:18:38 +00004846/* Miscellaneous methods. */
4847
Tim Petersa9bc1682003-01-11 03:39:11 +00004848static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004849flip_fold(PyObject *dt)
4850{
4851 return new_datetime_ex2(GET_YEAR(dt),
4852 GET_MONTH(dt),
4853 GET_DAY(dt),
4854 DATE_GET_HOUR(dt),
4855 DATE_GET_MINUTE(dt),
4856 DATE_GET_SECOND(dt),
4857 DATE_GET_MICROSECOND(dt),
4858 HASTZINFO(dt) ?
4859 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4860 !DATE_GET_FOLD(dt),
4861 Py_TYPE(dt));
4862}
4863
4864static PyObject *
4865get_flip_fold_offset(PyObject *dt)
4866{
4867 PyObject *result, *flip_dt;
4868
4869 flip_dt = flip_fold(dt);
4870 if (flip_dt == NULL)
4871 return NULL;
4872 result = datetime_utcoffset(flip_dt, NULL);
4873 Py_DECREF(flip_dt);
4874 return result;
4875}
4876
4877/* PEP 495 exception: Whenever one or both of the operands in
4878 * inter-zone comparison is such that its utcoffset() depends
4879 * on the value of its fold fold attribute, the result is False.
4880 *
4881 * Return 1 if exception applies, 0 if not, and -1 on error.
4882 */
4883static int
4884pep495_eq_exception(PyObject *self, PyObject *other,
4885 PyObject *offset_self, PyObject *offset_other)
4886{
4887 int result = 0;
4888 PyObject *flip_offset;
4889
4890 flip_offset = get_flip_fold_offset(self);
4891 if (flip_offset == NULL)
4892 return -1;
4893 if (flip_offset != offset_self &&
4894 delta_cmp(flip_offset, offset_self))
4895 {
4896 result = 1;
4897 goto done;
4898 }
4899 Py_DECREF(flip_offset);
4900
4901 flip_offset = get_flip_fold_offset(other);
4902 if (flip_offset == NULL)
4903 return -1;
4904 if (flip_offset != offset_other &&
4905 delta_cmp(flip_offset, offset_other))
4906 result = 1;
4907 done:
4908 Py_DECREF(flip_offset);
4909 return result;
4910}
4911
4912static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004913datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004914{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004915 PyObject *result = NULL;
4916 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004917 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004919 if (! PyDateTime_Check(other)) {
4920 if (PyDate_Check(other)) {
4921 /* Prevent invocation of date_richcompare. We want to
4922 return NotImplemented here to give the other object
4923 a chance. But since DateTime is a subclass of
4924 Date, if the other object is a Date, it would
4925 compute an ordering based on the date part alone,
4926 and we don't want that. So force unequal or
4927 uncomparable here in that case. */
4928 if (op == Py_EQ)
4929 Py_RETURN_FALSE;
4930 if (op == Py_NE)
4931 Py_RETURN_TRUE;
4932 return cmperror(self, other);
4933 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004934 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004935 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004936
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004937 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004938 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4939 ((PyDateTime_DateTime *)other)->data,
4940 _PyDateTime_DATETIME_DATASIZE);
4941 return diff_to_bool(diff, op);
4942 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004943 offset1 = datetime_utcoffset(self, NULL);
4944 if (offset1 == NULL)
4945 return NULL;
4946 offset2 = datetime_utcoffset(other, NULL);
4947 if (offset2 == NULL)
4948 goto done;
4949 /* If they're both naive, or both aware and have the same offsets,
4950 * we get off cheap. Note that if they're both naive, offset1 ==
4951 * offset2 == Py_None at this point.
4952 */
4953 if ((offset1 == offset2) ||
4954 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4955 delta_cmp(offset1, offset2) == 0)) {
4956 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4957 ((PyDateTime_DateTime *)other)->data,
4958 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004959 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4960 int ex = pep495_eq_exception(self, other, offset1, offset2);
4961 if (ex == -1)
4962 goto done;
4963 if (ex)
4964 diff = 1;
4965 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004966 result = diff_to_bool(diff, op);
4967 }
4968 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004969 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004970
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004971 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004972 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4973 other);
4974 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004975 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004976 diff = GET_TD_DAYS(delta);
4977 if (diff == 0)
4978 diff = GET_TD_SECONDS(delta) |
4979 GET_TD_MICROSECONDS(delta);
4980 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004981 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4982 int ex = pep495_eq_exception(self, other, offset1, offset2);
4983 if (ex == -1)
4984 goto done;
4985 if (ex)
4986 diff = 1;
4987 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004988 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004989 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004990 else if (op == Py_EQ) {
4991 result = Py_False;
4992 Py_INCREF(result);
4993 }
4994 else if (op == Py_NE) {
4995 result = Py_True;
4996 Py_INCREF(result);
4997 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004998 else {
4999 PyErr_SetString(PyExc_TypeError,
5000 "can't compare offset-naive and "
5001 "offset-aware datetimes");
5002 }
5003 done:
5004 Py_DECREF(offset1);
5005 Py_XDECREF(offset2);
5006 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00005007}
5008
Benjamin Peterson8f67d082010-10-17 20:54:53 +00005009static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00005010datetime_hash(PyDateTime_DateTime *self)
5011{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005012 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005013 PyObject *offset, *self0;
5014 if (DATE_GET_FOLD(self)) {
5015 self0 = new_datetime_ex2(GET_YEAR(self),
5016 GET_MONTH(self),
5017 GET_DAY(self),
5018 DATE_GET_HOUR(self),
5019 DATE_GET_MINUTE(self),
5020 DATE_GET_SECOND(self),
5021 DATE_GET_MICROSECOND(self),
5022 HASTZINFO(self) ? self->tzinfo : Py_None,
5023 0, Py_TYPE(self));
5024 if (self0 == NULL)
5025 return -1;
5026 }
5027 else {
5028 self0 = (PyObject *)self;
5029 Py_INCREF(self0);
5030 }
5031 offset = datetime_utcoffset(self0, NULL);
5032 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005033
5034 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00005036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005037 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005038 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005039 self->hashcode = generic_hash(
5040 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005041 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005042 PyObject *temp1, *temp2;
5043 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005045 assert(HASTZINFO(self));
5046 days = ymd_to_ord(GET_YEAR(self),
5047 GET_MONTH(self),
5048 GET_DAY(self));
5049 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005050 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005051 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005052 temp1 = new_delta(days, seconds,
5053 DATE_GET_MICROSECOND(self),
5054 1);
5055 if (temp1 == NULL) {
5056 Py_DECREF(offset);
5057 return -1;
5058 }
5059 temp2 = delta_subtract(temp1, offset);
5060 Py_DECREF(temp1);
5061 if (temp2 == NULL) {
5062 Py_DECREF(offset);
5063 return -1;
5064 }
5065 self->hashcode = PyObject_Hash(temp2);
5066 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005067 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005068 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005069 }
5070 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005071}
Tim Peters2a799bf2002-12-16 20:18:38 +00005072
5073static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005074datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005076 PyObject *clone;
5077 PyObject *tuple;
5078 int y = GET_YEAR(self);
5079 int m = GET_MONTH(self);
5080 int d = GET_DAY(self);
5081 int hh = DATE_GET_HOUR(self);
5082 int mm = DATE_GET_MINUTE(self);
5083 int ss = DATE_GET_SECOND(self);
5084 int us = DATE_GET_MICROSECOND(self);
5085 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005086 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005087
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005088 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005089 datetime_kws,
5090 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005091 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005092 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005093 if (fold != 0 && fold != 1) {
5094 PyErr_SetString(PyExc_ValueError,
5095 "fold must be either 0 or 1");
5096 return NULL;
5097 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005098 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5099 if (tuple == NULL)
5100 return NULL;
5101 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005102 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005103 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005104 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005105 Py_DECREF(tuple);
5106 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005107}
5108
5109static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005110local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005111{
5112 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005113 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005114 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005115 PyObject *nameo = NULL;
5116 const char *zone = NULL;
5117
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005118 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005119 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005120#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005121 zone = local_time_tm.tm_zone;
5122 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005123#else /* HAVE_STRUCT_TM_TM_ZONE */
5124 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005125 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005126 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005127 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005128 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005129 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005130 local_time = new_datetime(local_time_tm.tm_year + 1900,
5131 local_time_tm.tm_mon + 1,
5132 local_time_tm.tm_mday,
5133 local_time_tm.tm_hour,
5134 local_time_tm.tm_min,
5135 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005136 if (local_time == NULL) {
5137 return NULL;
5138 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005139 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005140 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005141 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5142 utc_time_tm.tm_mon + 1,
5143 utc_time_tm.tm_mday,
5144 utc_time_tm.tm_hour,
5145 utc_time_tm.tm_min,
5146 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005147 if (utc_time == NULL) {
5148 Py_DECREF(local_time);
5149 return NULL;
5150 }
5151 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005152 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005153 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005154 }
5155#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005156 if (delta == NULL) {
5157 return NULL;
5158 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005159 if (zone != NULL) {
5160 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5161 if (nameo == NULL)
5162 goto error;
5163 }
5164 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005165 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005166 error:
5167 Py_DECREF(delta);
5168 return result;
5169}
5170
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005171static PyObject *
5172local_timezone(PyDateTime_DateTime *utc_time)
5173{
5174 time_t timestamp;
5175 PyObject *delta;
5176 PyObject *one_second;
5177 PyObject *seconds;
5178
5179 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5180 if (delta == NULL)
5181 return NULL;
5182 one_second = new_delta(0, 1, 0, 0);
5183 if (one_second == NULL) {
5184 Py_DECREF(delta);
5185 return NULL;
5186 }
5187 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5188 (PyDateTime_Delta *)one_second);
5189 Py_DECREF(one_second);
5190 Py_DECREF(delta);
5191 if (seconds == NULL)
5192 return NULL;
5193 timestamp = _PyLong_AsTime_t(seconds);
5194 Py_DECREF(seconds);
5195 if (timestamp == -1 && PyErr_Occurred())
5196 return NULL;
5197 return local_timezone_from_timestamp(timestamp);
5198}
5199
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005200static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005201local_to_seconds(int year, int month, int day,
5202 int hour, int minute, int second, int fold);
5203
5204static PyObject *
5205local_timezone_from_local(PyDateTime_DateTime *local_dt)
5206{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005207 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005208 time_t timestamp;
5209 seconds = local_to_seconds(GET_YEAR(local_dt),
5210 GET_MONTH(local_dt),
5211 GET_DAY(local_dt),
5212 DATE_GET_HOUR(local_dt),
5213 DATE_GET_MINUTE(local_dt),
5214 DATE_GET_SECOND(local_dt),
5215 DATE_GET_FOLD(local_dt));
5216 if (seconds == -1)
5217 return NULL;
5218 /* XXX: add bounds check */
5219 timestamp = seconds - epoch;
5220 return local_timezone_from_timestamp(timestamp);
5221}
5222
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005223static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005224datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005225{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005226 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005227 PyObject *offset;
5228 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005229 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005230 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005231 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005232
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005233 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005234 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005235 return NULL;
5236
5237 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005238 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005239
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005240 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5241 self_tzinfo = local_timezone_from_local(self);
5242 if (self_tzinfo == NULL)
5243 return NULL;
5244 } else {
5245 self_tzinfo = self->tzinfo;
5246 Py_INCREF(self_tzinfo);
5247 }
Tim Peters521fc152002-12-31 17:36:56 +00005248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005249 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005250 if (self_tzinfo == tzinfo) {
5251 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005252 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005253 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005254 }
Tim Peters521fc152002-12-31 17:36:56 +00005255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005256 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005257 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5258 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005259 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005260 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005261 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005262 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5263 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005264 Py_DECREF(offset);
5265 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005266 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005267
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005268 /* Make sure result is aware and UTC. */
5269 if (!HASTZINFO(result)) {
5270 temp = (PyObject *)result;
5271 result = (PyDateTime_DateTime *)
5272 new_datetime_ex2(GET_YEAR(result),
5273 GET_MONTH(result),
5274 GET_DAY(result),
5275 DATE_GET_HOUR(result),
5276 DATE_GET_MINUTE(result),
5277 DATE_GET_SECOND(result),
5278 DATE_GET_MICROSECOND(result),
5279 PyDateTime_TimeZone_UTC,
5280 DATE_GET_FOLD(result),
5281 Py_TYPE(result));
5282 Py_DECREF(temp);
5283 if (result == NULL)
5284 return NULL;
5285 }
5286 else {
5287 /* Result is already aware - just replace tzinfo. */
5288 temp = result->tzinfo;
5289 result->tzinfo = PyDateTime_TimeZone_UTC;
5290 Py_INCREF(result->tzinfo);
5291 Py_DECREF(temp);
5292 }
5293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005294 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005295 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005296 if (tzinfo == Py_None) {
5297 tzinfo = local_timezone(result);
5298 if (tzinfo == NULL) {
5299 Py_DECREF(result);
5300 return NULL;
5301 }
5302 }
5303 else
5304 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005305 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005306 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005307
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005308 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005309 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005310 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005311 Py_DECREF(temp);
5312
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005313 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005314}
5315
5316static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005317datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005319 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005321 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005322 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005323
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005324 dst = call_dst(self->tzinfo, (PyObject *)self);
5325 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005326 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005327
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005328 if (dst != Py_None)
5329 dstflag = delta_bool((PyDateTime_Delta *)dst);
5330 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005331 }
5332 return build_struct_time(GET_YEAR(self),
5333 GET_MONTH(self),
5334 GET_DAY(self),
5335 DATE_GET_HOUR(self),
5336 DATE_GET_MINUTE(self),
5337 DATE_GET_SECOND(self),
5338 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005339}
5340
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005341static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005342local_to_seconds(int year, int month, int day,
5343 int hour, int minute, int second, int fold)
5344{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005345 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005346 t = utc_to_seconds(year, month, day, hour, minute, second);
5347 /* Our goal is to solve t = local(u) for u. */
5348 lt = local(t);
5349 if (lt == -1)
5350 return -1;
5351 a = lt - t;
5352 u1 = t - a;
5353 t1 = local(u1);
5354 if (t1 == -1)
5355 return -1;
5356 if (t1 == t) {
5357 /* We found one solution, but it may not be the one we need.
5358 * Look for an earlier solution (if `fold` is 0), or a
5359 * later one (if `fold` is 1). */
5360 if (fold)
5361 u2 = u1 + max_fold_seconds;
5362 else
5363 u2 = u1 - max_fold_seconds;
5364 lt = local(u2);
5365 if (lt == -1)
5366 return -1;
5367 b = lt - u2;
5368 if (a == b)
5369 return u1;
5370 }
5371 else {
5372 b = t1 - u1;
5373 assert(a != b);
5374 }
5375 u2 = t - b;
5376 t2 = local(u2);
5377 if (t2 == -1)
5378 return -1;
5379 if (t2 == t)
5380 return u2;
5381 if (t1 == t)
5382 return u1;
5383 /* We have found both offsets a and b, but neither t - a nor t - b is
5384 * a solution. This means t is in the gap. */
5385 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5386}
5387
5388/* date(1970,1,1).toordinal() == 719163 */
5389#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5390
Tim Peters2a799bf2002-12-16 20:18:38 +00005391static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005392datetime_timestamp(PyDateTime_DateTime *self)
5393{
5394 PyObject *result;
5395
5396 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5397 PyObject *delta;
5398 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5399 if (delta == NULL)
5400 return NULL;
5401 result = delta_total_seconds(delta);
5402 Py_DECREF(delta);
5403 }
5404 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005405 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005406 seconds = local_to_seconds(GET_YEAR(self),
5407 GET_MONTH(self),
5408 GET_DAY(self),
5409 DATE_GET_HOUR(self),
5410 DATE_GET_MINUTE(self),
5411 DATE_GET_SECOND(self),
5412 DATE_GET_FOLD(self));
5413 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005414 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005415 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5416 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005417 }
5418 return result;
5419}
5420
5421static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005422datetime_getdate(PyDateTime_DateTime *self)
5423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005424 return new_date(GET_YEAR(self),
5425 GET_MONTH(self),
5426 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005427}
5428
5429static PyObject *
5430datetime_gettime(PyDateTime_DateTime *self)
5431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005432 return new_time(DATE_GET_HOUR(self),
5433 DATE_GET_MINUTE(self),
5434 DATE_GET_SECOND(self),
5435 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005436 Py_None,
5437 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005438}
5439
5440static PyObject *
5441datetime_gettimetz(PyDateTime_DateTime *self)
5442{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005443 return new_time(DATE_GET_HOUR(self),
5444 DATE_GET_MINUTE(self),
5445 DATE_GET_SECOND(self),
5446 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005447 GET_DT_TZINFO(self),
5448 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005449}
5450
5451static PyObject *
5452datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005453{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005454 int y, m, d, hh, mm, ss;
5455 PyObject *tzinfo;
5456 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005457
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005458 tzinfo = GET_DT_TZINFO(self);
5459 if (tzinfo == Py_None) {
5460 utcself = self;
5461 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005462 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005463 else {
5464 PyObject *offset;
5465 offset = call_utcoffset(tzinfo, (PyObject *)self);
5466 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005467 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005468 if (offset == Py_None) {
5469 Py_DECREF(offset);
5470 utcself = self;
5471 Py_INCREF(utcself);
5472 }
5473 else {
5474 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5475 (PyDateTime_Delta *)offset, -1);
5476 Py_DECREF(offset);
5477 if (utcself == NULL)
5478 return NULL;
5479 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005480 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005481 y = GET_YEAR(utcself);
5482 m = GET_MONTH(utcself);
5483 d = GET_DAY(utcself);
5484 hh = DATE_GET_HOUR(utcself);
5485 mm = DATE_GET_MINUTE(utcself);
5486 ss = DATE_GET_SECOND(utcself);
5487
5488 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005489 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005490}
5491
Tim Peters371935f2003-02-01 01:52:50 +00005492/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005493
Tim Petersa9bc1682003-01-11 03:39:11 +00005494/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005495 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5496 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005497 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005498 */
5499static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005500datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005502 PyObject *basestate;
5503 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005505 basestate = PyBytes_FromStringAndSize((char *)self->data,
5506 _PyDateTime_DATETIME_DATASIZE);
5507 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005508 if (proto > 3 && DATE_GET_FOLD(self))
5509 /* Set the first bit of the third byte */
5510 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005511 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5512 result = PyTuple_Pack(1, basestate);
5513 else
5514 result = PyTuple_Pack(2, basestate, self->tzinfo);
5515 Py_DECREF(basestate);
5516 }
5517 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005518}
5519
5520static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005521datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005522{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005523 int proto;
5524 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005525 return NULL;
5526
5527 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005528}
5529
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005530static PyObject *
5531datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5532{
5533 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5534}
5535
Tim Petersa9bc1682003-01-11 03:39:11 +00005536static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005538 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005539
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005540 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005542 {"utcnow", (PyCFunction)datetime_utcnow,
5543 METH_NOARGS | METH_CLASS,
5544 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005546 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5547 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5548 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005550 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5551 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005552 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005554 {"strptime", (PyCFunction)datetime_strptime,
5555 METH_VARARGS | METH_CLASS,
5556 PyDoc_STR("string, format -> new datetime parsed from a string "
5557 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005559 {"combine", (PyCFunction)datetime_combine,
5560 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5561 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005563 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005565 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5566 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005568 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5569 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005571 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5572 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005574 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5575 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005577 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5578 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005579
Alexander Belopolskya4415142012-06-08 12:33:09 -04005580 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5581 PyDoc_STR("Return POSIX timestamp as float.")},
5582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005583 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5584 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005586 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5587 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005588 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005589 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005590 "defaults to 'T'.\n"
5591 "timespec specifies what components of the time to include"
5592 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5593 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005595 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5596 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005598 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5599 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005601 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5602 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005604 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5605 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005607 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5608 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005609
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005610 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005611 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005612
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005613 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5614 PyDoc_STR("__reduce__() -> (cls, state)")},
5615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005616 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005617};
5618
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005619static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005620PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5621\n\
5622The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005623instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005624
Tim Petersa9bc1682003-01-11 03:39:11 +00005625static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005626 datetime_add, /* nb_add */
5627 datetime_subtract, /* nb_subtract */
5628 0, /* nb_multiply */
5629 0, /* nb_remainder */
5630 0, /* nb_divmod */
5631 0, /* nb_power */
5632 0, /* nb_negative */
5633 0, /* nb_positive */
5634 0, /* nb_absolute */
5635 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005636};
5637
Neal Norwitz227b5332006-03-22 09:28:35 +00005638static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005639 PyVarObject_HEAD_INIT(NULL, 0)
5640 "datetime.datetime", /* tp_name */
5641 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5642 0, /* tp_itemsize */
5643 (destructor)datetime_dealloc, /* tp_dealloc */
5644 0, /* tp_print */
5645 0, /* tp_getattr */
5646 0, /* tp_setattr */
5647 0, /* tp_reserved */
5648 (reprfunc)datetime_repr, /* tp_repr */
5649 &datetime_as_number, /* tp_as_number */
5650 0, /* tp_as_sequence */
5651 0, /* tp_as_mapping */
5652 (hashfunc)datetime_hash, /* tp_hash */
5653 0, /* tp_call */
5654 (reprfunc)datetime_str, /* tp_str */
5655 PyObject_GenericGetAttr, /* tp_getattro */
5656 0, /* tp_setattro */
5657 0, /* tp_as_buffer */
5658 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5659 datetime_doc, /* tp_doc */
5660 0, /* tp_traverse */
5661 0, /* tp_clear */
5662 datetime_richcompare, /* tp_richcompare */
5663 0, /* tp_weaklistoffset */
5664 0, /* tp_iter */
5665 0, /* tp_iternext */
5666 datetime_methods, /* tp_methods */
5667 0, /* tp_members */
5668 datetime_getset, /* tp_getset */
5669 &PyDateTime_DateType, /* tp_base */
5670 0, /* tp_dict */
5671 0, /* tp_descr_get */
5672 0, /* tp_descr_set */
5673 0, /* tp_dictoffset */
5674 0, /* tp_init */
5675 datetime_alloc, /* tp_alloc */
5676 datetime_new, /* tp_new */
5677 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005678};
5679
5680/* ---------------------------------------------------------------------------
5681 * Module methods and initialization.
5682 */
5683
5684static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005685 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005686};
5687
Tim Peters9ddf40b2004-06-20 22:41:32 +00005688/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5689 * datetime.h.
5690 */
5691static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005692 &PyDateTime_DateType,
5693 &PyDateTime_DateTimeType,
5694 &PyDateTime_TimeType,
5695 &PyDateTime_DeltaType,
5696 &PyDateTime_TZInfoType,
5697 new_date_ex,
5698 new_datetime_ex,
5699 new_time_ex,
5700 new_delta_ex,
5701 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005702 date_fromtimestamp,
5703 new_datetime_ex2,
5704 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00005705};
5706
5707
Martin v. Löwis1a214512008-06-11 05:26:20 +00005708
5709static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005710 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005711 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005712 "Fast implementation of the datetime type.",
5713 -1,
5714 module_methods,
5715 NULL,
5716 NULL,
5717 NULL,
5718 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005719};
5720
Tim Peters2a799bf2002-12-16 20:18:38 +00005721PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005722PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005723{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005724 PyObject *m; /* a module object */
5725 PyObject *d; /* its dict */
5726 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005727 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005729 m = PyModule_Create(&datetimemodule);
5730 if (m == NULL)
5731 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005733 if (PyType_Ready(&PyDateTime_DateType) < 0)
5734 return NULL;
5735 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5736 return NULL;
5737 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5738 return NULL;
5739 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5740 return NULL;
5741 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5742 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005743 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5744 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005746 /* timedelta values */
5747 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005749 x = new_delta(0, 0, 1, 0);
5750 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5751 return NULL;
5752 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005754 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5755 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5756 return NULL;
5757 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005759 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5760 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5761 return NULL;
5762 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005764 /* date values */
5765 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005767 x = new_date(1, 1, 1);
5768 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5769 return NULL;
5770 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005772 x = new_date(MAXYEAR, 12, 31);
5773 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5774 return NULL;
5775 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005777 x = new_delta(1, 0, 0, 0);
5778 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5779 return NULL;
5780 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005782 /* time values */
5783 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005784
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005785 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005786 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5787 return NULL;
5788 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005789
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005790 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005791 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5792 return NULL;
5793 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005795 x = new_delta(0, 0, 1, 0);
5796 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5797 return NULL;
5798 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005800 /* datetime values */
5801 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005802
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005803 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005804 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5805 return NULL;
5806 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005807
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005808 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005809 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5810 return NULL;
5811 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005813 x = new_delta(0, 0, 1, 0);
5814 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5815 return NULL;
5816 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005817
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005818 /* timezone values */
5819 d = PyDateTime_TimeZoneType.tp_dict;
5820
5821 delta = new_delta(0, 0, 0, 0);
5822 if (delta == NULL)
5823 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005824 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005825 Py_DECREF(delta);
5826 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5827 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005828 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005829
5830 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5831 if (delta == NULL)
5832 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005833 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005834 Py_DECREF(delta);
5835 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5836 return NULL;
5837 Py_DECREF(x);
5838
5839 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5840 if (delta == NULL)
5841 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005842 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005843 Py_DECREF(delta);
5844 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5845 return NULL;
5846 Py_DECREF(x);
5847
Alexander Belopolskya4415142012-06-08 12:33:09 -04005848 /* Epoch */
5849 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005850 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005851 if (PyDateTime_Epoch == NULL)
5852 return NULL;
5853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005854 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005855 PyModule_AddIntMacro(m, MINYEAR);
5856 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005858 Py_INCREF(&PyDateTime_DateType);
5859 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005861 Py_INCREF(&PyDateTime_DateTimeType);
5862 PyModule_AddObject(m, "datetime",
5863 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005865 Py_INCREF(&PyDateTime_TimeType);
5866 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005868 Py_INCREF(&PyDateTime_DeltaType);
5869 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005871 Py_INCREF(&PyDateTime_TZInfoType);
5872 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005873
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005874 Py_INCREF(&PyDateTime_TimeZoneType);
5875 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005877 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5878 if (x == NULL)
5879 return NULL;
5880 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005882 /* A 4-year cycle has an extra leap day over what we'd get from
5883 * pasting together 4 single years.
5884 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005885 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005886 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005888 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5889 * get from pasting together 4 100-year cycles.
5890 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005891 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005892 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005894 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5895 * pasting together 25 4-year cycles.
5896 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005897 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005898 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005900 us_per_ms = PyLong_FromLong(1000);
5901 us_per_second = PyLong_FromLong(1000000);
5902 us_per_minute = PyLong_FromLong(60000000);
5903 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03005904 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005905 us_per_minute == NULL || seconds_per_day == NULL)
5906 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005908 /* The rest are too big for 32-bit ints, but even
5909 * us_per_week fits in 40 bits, so doubles should be exact.
5910 */
5911 us_per_hour = PyLong_FromDouble(3600000000.0);
5912 us_per_day = PyLong_FromDouble(86400000000.0);
5913 us_per_week = PyLong_FromDouble(604800000000.0);
5914 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5915 return NULL;
5916 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005917}
Tim Petersf3615152003-01-01 21:51:37 +00005918
5919/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005920Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005921 x.n = x stripped of its timezone -- its naive time.
5922 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005923 return None
Tim Petersf3615152003-01-01 21:51:37 +00005924 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005925 return None
Tim Petersf3615152003-01-01 21:51:37 +00005926 x.s = x's standard offset, x.o - x.d
5927
5928Now some derived rules, where k is a duration (timedelta).
5929
59301. x.o = x.s + x.d
5931 This follows from the definition of x.s.
5932
Tim Petersc5dc4da2003-01-02 17:55:03 +000059332. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005934 This is actually a requirement, an assumption we need to make about
5935 sane tzinfo classes.
5936
59373. The naive UTC time corresponding to x is x.n - x.o.
5938 This is again a requirement for a sane tzinfo class.
5939
59404. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005941 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005942
Tim Petersc5dc4da2003-01-02 17:55:03 +000059435. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005944 Again follows from how arithmetic is defined.
5945
Tim Peters8bb5ad22003-01-24 02:44:45 +00005946Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005947(meaning that the various tzinfo methods exist, and don't blow up or return
5948None when called).
5949
Tim Petersa9bc1682003-01-11 03:39:11 +00005950The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005951x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005952
5953By #3, we want
5954
Tim Peters8bb5ad22003-01-24 02:44:45 +00005955 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005956
5957The algorithm starts by attaching tz to x.n, and calling that y. So
5958x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5959becomes true; in effect, we want to solve [2] for k:
5960
Tim Peters8bb5ad22003-01-24 02:44:45 +00005961 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005962
5963By #1, this is the same as
5964
Tim Peters8bb5ad22003-01-24 02:44:45 +00005965 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005966
5967By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5968Substituting that into [3],
5969
Tim Peters8bb5ad22003-01-24 02:44:45 +00005970 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5971 k - (y+k).s - (y+k).d = 0; rearranging,
5972 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5973 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005974
Tim Peters8bb5ad22003-01-24 02:44:45 +00005975On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5976approximate k by ignoring the (y+k).d term at first. Note that k can't be
5977very large, since all offset-returning methods return a duration of magnitude
5978less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5979be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005980
5981In any case, the new value is
5982
Tim Peters8bb5ad22003-01-24 02:44:45 +00005983 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005984
Tim Peters8bb5ad22003-01-24 02:44:45 +00005985It's helpful to step back at look at [4] from a higher level: it's simply
5986mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005987
5988At this point, if
5989
Tim Peters8bb5ad22003-01-24 02:44:45 +00005990 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005991
5992we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005993at the start of daylight time. Picture US Eastern for concreteness. The wall
5994time 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 +00005995sense then. The docs ask that an Eastern tzinfo class consider such a time to
5996be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5997on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005998the only spelling that makes sense on the local wall clock.
5999
Tim Petersc5dc4da2003-01-02 17:55:03 +00006000In fact, if [5] holds at this point, we do have the standard-time spelling,
6001but that takes a bit of proof. We first prove a stronger result. What's the
6002difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00006003
Tim Peters8bb5ad22003-01-24 02:44:45 +00006004 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00006005
Tim Petersc5dc4da2003-01-02 17:55:03 +00006006Now
6007 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00006008 (y + y.s).n = by #5
6009 y.n + y.s = since y.n = x.n
6010 x.n + y.s = since z and y are have the same tzinfo member,
6011 y.s = z.s by #2
6012 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00006013
Tim Petersc5dc4da2003-01-02 17:55:03 +00006014Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00006015
Tim Petersc5dc4da2003-01-02 17:55:03 +00006016 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00006017 x.n - ((x.n + z.s) - z.o) = expanding
6018 x.n - x.n - z.s + z.o = cancelling
6019 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00006020 z.d
Tim Petersf3615152003-01-01 21:51:37 +00006021
Tim Petersc5dc4da2003-01-02 17:55:03 +00006022So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00006023
Tim Petersc5dc4da2003-01-02 17:55:03 +00006024If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00006025spelling we wanted in the endcase described above. We're done. Contrarily,
6026if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00006027
Tim Petersc5dc4da2003-01-02 17:55:03 +00006028If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
6029add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00006030local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00006031
Tim Petersc5dc4da2003-01-02 17:55:03 +00006032Let
Tim Petersf3615152003-01-01 21:51:37 +00006033
Tim Peters4fede1a2003-01-04 00:26:59 +00006034 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006035
Tim Peters4fede1a2003-01-04 00:26:59 +00006036and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00006037
Tim Peters8bb5ad22003-01-24 02:44:45 +00006038 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00006039
Tim Peters8bb5ad22003-01-24 02:44:45 +00006040If so, we're done. If not, the tzinfo class is insane, according to the
6041assumptions we've made. This also requires a bit of proof. As before, let's
6042compute the difference between the LHS and RHS of [8] (and skipping some of
6043the justifications for the kinds of substitutions we've done several times
6044already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006045
Tim Peters8bb5ad22003-01-24 02:44:45 +00006046 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006047 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6048 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6049 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6050 - z.n + z.n - z.o + z'.o = cancel z.n
6051 - z.o + z'.o = #1 twice
6052 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6053 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006054
6055So 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 +00006056we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6057return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006058
Tim Peters8bb5ad22003-01-24 02:44:45 +00006059How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6060a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6061would have to change the result dst() returns: we start in DST, and moving
6062a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006063
Tim Peters8bb5ad22003-01-24 02:44:45 +00006064There isn't a sane case where this can happen. The closest it gets is at
6065the end of DST, where there's an hour in UTC with no spelling in a hybrid
6066tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6067that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6068UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6069time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6070clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6071standard time. Since that's what the local clock *does*, we want to map both
6072UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006073in local time, but so it goes -- it's the way the local clock works.
6074
Tim Peters8bb5ad22003-01-24 02:44:45 +00006075When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6076so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6077z' = 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 +00006078(correctly) concludes that z' is not UTC-equivalent to x.
6079
6080Because we know z.d said z was in daylight time (else [5] would have held and
6081we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006082and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006083return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6084but the reasoning doesn't depend on the example -- it depends on there being
6085two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006086z' must be in standard time, and is the spelling we want in this case.
6087
6088Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6089concerned (because it takes z' as being in standard time rather than the
6090daylight time we intend here), but returning it gives the real-life "local
6091clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6092tz.
6093
6094When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6095the 1:MM standard time spelling we want.
6096
6097So how can this break? One of the assumptions must be violated. Two
6098possibilities:
6099
61001) [2] effectively says that y.s is invariant across all y belong to a given
6101 time zone. This isn't true if, for political reasons or continental drift,
6102 a region decides to change its base offset from UTC.
6103
61042) There may be versions of "double daylight" time where the tail end of
6105 the analysis gives up a step too early. I haven't thought about that
6106 enough to say.
6107
6108In any case, it's clear that the default fromutc() is strong enough to handle
6109"almost all" time zones: so long as the standard offset is invariant, it
6110doesn't matter if daylight time transition points change from year to year, or
6111if daylight time is skipped in some years; it doesn't matter how large or
6112small dst() may get within its bounds; and it doesn't even matter if some
6113perverse time zone returns a negative dst()). So a breaking case must be
6114pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006115--------------------------------------------------------------------------- */