blob: b50cddad5dd2fd6e1c692ed31d98671e8f151f29 [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{
stratakise8b19652017-11-02 11:32:54 +01001445 Py_RETURN_RICHCOMPARE(diff, 0, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001446}
1447
Tim Peters07534a62003-02-07 22:50:28 +00001448/* Raises a "can't compare" TypeError and returns NULL. */
1449static PyObject *
1450cmperror(PyObject *a, PyObject *b)
1451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 PyErr_Format(PyExc_TypeError,
1453 "can't compare %s to %s",
1454 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1455 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001456}
1457
Tim Peters2a799bf2002-12-16 20:18:38 +00001458/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001459 * Cached Python objects; these are set by the module init function.
1460 */
1461
1462/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463static PyObject *us_per_ms = NULL; /* 1000 */
1464static PyObject *us_per_second = NULL; /* 1000000 */
1465static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001466static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1467static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1468static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001469static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1470
Tim Peters2a799bf2002-12-16 20:18:38 +00001471/* ---------------------------------------------------------------------------
1472 * Class implementations.
1473 */
1474
1475/*
1476 * PyDateTime_Delta implementation.
1477 */
1478
1479/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001481 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001482 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1483 * due to ubiquitous overflow possibilities.
1484 */
1485static PyObject *
1486delta_to_microseconds(PyDateTime_Delta *self)
1487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 PyObject *x1 = NULL;
1489 PyObject *x2 = NULL;
1490 PyObject *x3 = NULL;
1491 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1494 if (x1 == NULL)
1495 goto Done;
1496 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1497 if (x2 == NULL)
1498 goto Done;
1499 Py_DECREF(x1);
1500 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 /* x2 has days in seconds */
1503 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1504 if (x1 == NULL)
1505 goto Done;
1506 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1507 if (x3 == NULL)
1508 goto Done;
1509 Py_DECREF(x1);
1510 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001511 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 /* x3 has days+seconds in seconds */
1514 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1515 if (x1 == NULL)
1516 goto Done;
1517 Py_DECREF(x3);
1518 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 /* x1 has days+seconds in us */
1521 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1522 if (x2 == NULL)
1523 goto Done;
1524 result = PyNumber_Add(x1, x2);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001525 assert(result == NULL || PyLong_CheckExact(result));
Tim Peters2a799bf2002-12-16 20:18:38 +00001526
1527Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 Py_XDECREF(x1);
1529 Py_XDECREF(x2);
1530 Py_XDECREF(x3);
1531 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001532}
1533
Serhiy Storchaka95949422013-08-27 19:40:23 +03001534/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001535 */
1536static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001537microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 int us;
1540 int s;
1541 int d;
1542 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 PyObject *tuple = NULL;
1545 PyObject *num = NULL;
1546 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001547
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03001548 assert(PyLong_CheckExact(pyus));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 tuple = PyNumber_Divmod(pyus, us_per_second);
1550 if (tuple == NULL)
1551 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 num = PyTuple_GetItem(tuple, 1); /* us */
1554 if (num == NULL)
1555 goto Done;
1556 temp = PyLong_AsLong(num);
1557 num = NULL;
1558 if (temp == -1 && PyErr_Occurred())
1559 goto Done;
1560 assert(0 <= temp && temp < 1000000);
1561 us = (int)temp;
1562 if (us < 0) {
1563 /* The divisor was positive, so this must be an error. */
1564 assert(PyErr_Occurred());
1565 goto Done;
1566 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1569 if (num == NULL)
1570 goto Done;
1571 Py_INCREF(num);
1572 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 tuple = PyNumber_Divmod(num, seconds_per_day);
1575 if (tuple == NULL)
1576 goto Done;
1577 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 num = PyTuple_GetItem(tuple, 1); /* seconds */
1580 if (num == NULL)
1581 goto Done;
1582 temp = PyLong_AsLong(num);
1583 num = NULL;
1584 if (temp == -1 && PyErr_Occurred())
1585 goto Done;
1586 assert(0 <= temp && temp < 24*3600);
1587 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 if (s < 0) {
1590 /* The divisor was positive, so this must be an error. */
1591 assert(PyErr_Occurred());
1592 goto Done;
1593 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1596 if (num == NULL)
1597 goto Done;
1598 Py_INCREF(num);
1599 temp = PyLong_AsLong(num);
1600 if (temp == -1 && PyErr_Occurred())
1601 goto Done;
1602 d = (int)temp;
1603 if ((long)d != temp) {
1604 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1605 "large to fit in a C int");
1606 goto Done;
1607 }
1608 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001609
1610Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 Py_XDECREF(tuple);
1612 Py_XDECREF(num);
1613 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001614}
1615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616#define microseconds_to_delta(pymicros) \
1617 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001618
Tim Peters2a799bf2002-12-16 20:18:38 +00001619static PyObject *
1620multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 PyObject *pyus_in;
1623 PyObject *pyus_out;
1624 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 pyus_in = delta_to_microseconds(delta);
1627 if (pyus_in == NULL)
1628 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1631 Py_DECREF(pyus_in);
1632 if (pyus_out == NULL)
1633 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 result = microseconds_to_delta(pyus_out);
1636 Py_DECREF(pyus_out);
1637 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001638}
1639
1640static PyObject *
Oren Milman865e4b42017-09-19 15:58:11 +03001641get_float_as_integer_ratio(PyObject *floatobj)
1642{
1643 PyObject *ratio;
1644
1645 assert(floatobj && PyFloat_Check(floatobj));
1646 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1647 if (ratio == NULL) {
1648 return NULL;
1649 }
1650 if (!PyTuple_Check(ratio)) {
1651 PyErr_Format(PyExc_TypeError,
1652 "unexpected return type from as_integer_ratio(): "
1653 "expected tuple, got '%.200s'",
1654 Py_TYPE(ratio)->tp_name);
1655 Py_DECREF(ratio);
1656 return NULL;
1657 }
1658 if (PyTuple_Size(ratio) != 2) {
1659 PyErr_SetString(PyExc_ValueError,
1660 "as_integer_ratio() must return a 2-tuple");
1661 Py_DECREF(ratio);
1662 return NULL;
1663 }
1664 return ratio;
1665}
1666
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001667/* op is 0 for multiplication, 1 for division */
Oren Milman865e4b42017-09-19 15:58:11 +03001668static PyObject *
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001669multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op)
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001670{
1671 PyObject *result = NULL;
1672 PyObject *pyus_in = NULL, *temp, *pyus_out;
1673 PyObject *ratio = NULL;
1674
1675 pyus_in = delta_to_microseconds(delta);
1676 if (pyus_in == NULL)
1677 return NULL;
Oren Milman865e4b42017-09-19 15:58:11 +03001678 ratio = get_float_as_integer_ratio(floatobj);
1679 if (ratio == NULL) {
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001680 goto error;
Oren Milman865e4b42017-09-19 15:58:11 +03001681 }
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001682 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001683 Py_DECREF(pyus_in);
1684 pyus_in = NULL;
1685 if (temp == NULL)
1686 goto error;
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001687 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op));
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001688 Py_DECREF(temp);
1689 if (pyus_out == NULL)
1690 goto error;
1691 result = microseconds_to_delta(pyus_out);
1692 Py_DECREF(pyus_out);
1693 error:
1694 Py_XDECREF(pyus_in);
1695 Py_XDECREF(ratio);
1696
1697 return result;
1698}
1699
1700static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001701divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1702{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703 PyObject *pyus_in;
1704 PyObject *pyus_out;
1705 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 pyus_in = delta_to_microseconds(delta);
1708 if (pyus_in == NULL)
1709 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1712 Py_DECREF(pyus_in);
1713 if (pyus_out == NULL)
1714 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001715
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 result = microseconds_to_delta(pyus_out);
1717 Py_DECREF(pyus_out);
1718 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001719}
1720
1721static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001722divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1723{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 PyObject *pyus_left;
1725 PyObject *pyus_right;
1726 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 pyus_left = delta_to_microseconds(left);
1729 if (pyus_left == NULL)
1730 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001731
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 pyus_right = delta_to_microseconds(right);
1733 if (pyus_right == NULL) {
1734 Py_DECREF(pyus_left);
1735 return NULL;
1736 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1739 Py_DECREF(pyus_left);
1740 Py_DECREF(pyus_right);
1741 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001742}
1743
1744static PyObject *
1745truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 PyObject *pyus_left;
1748 PyObject *pyus_right;
1749 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 pyus_left = delta_to_microseconds(left);
1752 if (pyus_left == NULL)
1753 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 pyus_right = delta_to_microseconds(right);
1756 if (pyus_right == NULL) {
1757 Py_DECREF(pyus_left);
1758 return NULL;
1759 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1762 Py_DECREF(pyus_left);
1763 Py_DECREF(pyus_right);
1764 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001765}
1766
1767static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001768truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1769{
1770 PyObject *result;
1771 PyObject *pyus_in, *pyus_out;
1772 pyus_in = delta_to_microseconds(delta);
1773 if (pyus_in == NULL)
1774 return NULL;
1775 pyus_out = divide_nearest(pyus_in, i);
1776 Py_DECREF(pyus_in);
1777 if (pyus_out == NULL)
1778 return NULL;
1779 result = microseconds_to_delta(pyus_out);
1780 Py_DECREF(pyus_out);
1781
1782 return result;
1783}
1784
1785static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001786delta_add(PyObject *left, PyObject *right)
1787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1791 /* delta + delta */
1792 /* The C-level additions can't overflow because of the
1793 * invariant bounds.
1794 */
1795 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1796 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1797 int microseconds = GET_TD_MICROSECONDS(left) +
1798 GET_TD_MICROSECONDS(right);
1799 result = new_delta(days, seconds, microseconds, 1);
1800 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 if (result == Py_NotImplemented)
1803 Py_INCREF(result);
1804 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001805}
1806
1807static PyObject *
1808delta_negative(PyDateTime_Delta *self)
1809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 return new_delta(-GET_TD_DAYS(self),
1811 -GET_TD_SECONDS(self),
1812 -GET_TD_MICROSECONDS(self),
1813 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001814}
1815
1816static PyObject *
1817delta_positive(PyDateTime_Delta *self)
1818{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 /* Could optimize this (by returning self) if this isn't a
1820 * subclass -- but who uses unary + ? Approximately nobody.
1821 */
1822 return new_delta(GET_TD_DAYS(self),
1823 GET_TD_SECONDS(self),
1824 GET_TD_MICROSECONDS(self),
1825 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001826}
1827
1828static PyObject *
1829delta_abs(PyDateTime_Delta *self)
1830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 assert(GET_TD_MICROSECONDS(self) >= 0);
1834 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 if (GET_TD_DAYS(self) < 0)
1837 result = delta_negative(self);
1838 else
1839 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001842}
1843
1844static PyObject *
1845delta_subtract(PyObject *left, PyObject *right)
1846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1850 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001851 /* The C-level additions can't overflow because of the
1852 * invariant bounds.
1853 */
1854 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1855 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1856 int microseconds = GET_TD_MICROSECONDS(left) -
1857 GET_TD_MICROSECONDS(right);
1858 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 if (result == Py_NotImplemented)
1862 Py_INCREF(result);
1863 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001864}
1865
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001866static int
1867delta_cmp(PyObject *self, PyObject *other)
1868{
1869 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1870 if (diff == 0) {
1871 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1872 if (diff == 0)
1873 diff = GET_TD_MICROSECONDS(self) -
1874 GET_TD_MICROSECONDS(other);
1875 }
1876 return diff;
1877}
1878
Tim Peters2a799bf2002-12-16 20:18:38 +00001879static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001880delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001881{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001883 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 return diff_to_bool(diff, op);
1885 }
1886 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001887 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001889}
1890
1891static PyObject *delta_getstate(PyDateTime_Delta *self);
1892
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001893static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001894delta_hash(PyDateTime_Delta *self)
1895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 if (self->hashcode == -1) {
1897 PyObject *temp = delta_getstate(self);
1898 if (temp != NULL) {
1899 self->hashcode = PyObject_Hash(temp);
1900 Py_DECREF(temp);
1901 }
1902 }
1903 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001904}
1905
1906static PyObject *
1907delta_multiply(PyObject *left, PyObject *right)
1908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (PyDelta_Check(left)) {
1912 /* delta * ??? */
1913 if (PyLong_Check(right))
1914 result = multiply_int_timedelta(right,
1915 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001916 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001917 result = multiply_truedivide_timedelta_float(
1918 (PyDateTime_Delta *) left, right, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 }
1920 else if (PyLong_Check(left))
1921 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001922 (PyDateTime_Delta *) right);
1923 else if (PyFloat_Check(left))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001924 result = multiply_truedivide_timedelta_float(
1925 (PyDateTime_Delta *) right, left, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 if (result == Py_NotImplemented)
1928 Py_INCREF(result);
1929 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001930}
1931
1932static PyObject *
1933delta_divide(PyObject *left, PyObject *right)
1934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 if (PyDelta_Check(left)) {
1938 /* delta * ??? */
1939 if (PyLong_Check(right))
1940 result = divide_timedelta_int(
1941 (PyDateTime_Delta *)left,
1942 right);
1943 else if (PyDelta_Check(right))
1944 result = divide_timedelta_timedelta(
1945 (PyDateTime_Delta *)left,
1946 (PyDateTime_Delta *)right);
1947 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 if (result == Py_NotImplemented)
1950 Py_INCREF(result);
1951 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001952}
1953
Mark Dickinson7c186e22010-04-20 22:32:49 +00001954static PyObject *
1955delta_truedivide(PyObject *left, PyObject *right)
1956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 if (PyDelta_Check(left)) {
1960 if (PyDelta_Check(right))
1961 result = truedivide_timedelta_timedelta(
1962 (PyDateTime_Delta *)left,
1963 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001964 else if (PyFloat_Check(right))
Serhiy Storchakadb12ef72017-10-04 20:30:09 +03001965 result = multiply_truedivide_timedelta_float(
1966 (PyDateTime_Delta *)left, right, 1);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001967 else if (PyLong_Check(right))
1968 result = truedivide_timedelta_int(
1969 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 if (result == Py_NotImplemented)
1973 Py_INCREF(result);
1974 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001975}
1976
1977static PyObject *
1978delta_remainder(PyObject *left, PyObject *right)
1979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 PyObject *pyus_left;
1981 PyObject *pyus_right;
1982 PyObject *pyus_remainder;
1983 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001984
Brian Curtindfc80e32011-08-10 20:28:54 -05001985 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1986 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1989 if (pyus_left == NULL)
1990 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1993 if (pyus_right == NULL) {
1994 Py_DECREF(pyus_left);
1995 return NULL;
1996 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1999 Py_DECREF(pyus_left);
2000 Py_DECREF(pyus_right);
2001 if (pyus_remainder == NULL)
2002 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 remainder = microseconds_to_delta(pyus_remainder);
2005 Py_DECREF(pyus_remainder);
2006 if (remainder == NULL)
2007 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002010}
2011
2012static PyObject *
2013delta_divmod(PyObject *left, PyObject *right)
2014{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 PyObject *pyus_left;
2016 PyObject *pyus_right;
2017 PyObject *divmod;
2018 PyObject *delta;
2019 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002020
Brian Curtindfc80e32011-08-10 20:28:54 -05002021 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2022 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2025 if (pyus_left == NULL)
2026 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2029 if (pyus_right == NULL) {
2030 Py_DECREF(pyus_left);
2031 return NULL;
2032 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2035 Py_DECREF(pyus_left);
2036 Py_DECREF(pyus_right);
2037 if (divmod == NULL)
2038 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 assert(PyTuple_Size(divmod) == 2);
2041 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2042 if (delta == NULL) {
2043 Py_DECREF(divmod);
2044 return NULL;
2045 }
2046 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2047 Py_DECREF(delta);
2048 Py_DECREF(divmod);
2049 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002050}
2051
Tim Peters2a799bf2002-12-16 20:18:38 +00002052/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2053 * timedelta constructor. sofar is the # of microseconds accounted for
2054 * so far, and there are factor microseconds per current unit, the number
2055 * of which is given by num. num * factor is added to sofar in a
2056 * numerically careful way, and that's the result. Any fractional
2057 * microseconds left over (this can happen if num is a float type) are
2058 * added into *leftover.
2059 * Note that there are many ways this can give an error (NULL) return.
2060 */
2061static PyObject *
2062accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2063 double *leftover)
2064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 PyObject *prod;
2066 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 if (PyLong_Check(num)) {
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002071 prod = PyNumber_Multiply(factor, num);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002072 if (prod == NULL)
2073 return NULL;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002074 assert(PyLong_CheckExact(prod));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 sum = PyNumber_Add(sofar, prod);
2076 Py_DECREF(prod);
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002077 assert(sum == NULL || PyLong_CheckExact(sum));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 return sum;
2079 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 if (PyFloat_Check(num)) {
2082 double dnum;
2083 double fracpart;
2084 double intpart;
2085 PyObject *x;
2086 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 /* The Plan: decompose num into an integer part and a
2089 * fractional part, num = intpart + fracpart.
2090 * Then num * factor ==
2091 * intpart * factor + fracpart * factor
2092 * and the LHS can be computed exactly in long arithmetic.
2093 * The RHS is again broken into an int part and frac part.
2094 * and the frac part is added into *leftover.
2095 */
2096 dnum = PyFloat_AsDouble(num);
2097 if (dnum == -1.0 && PyErr_Occurred())
2098 return NULL;
2099 fracpart = modf(dnum, &intpart);
2100 x = PyLong_FromDouble(intpart);
2101 if (x == NULL)
2102 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 prod = PyNumber_Multiply(x, factor);
2105 Py_DECREF(x);
2106 if (prod == NULL)
2107 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 sum = PyNumber_Add(sofar, prod);
2110 Py_DECREF(prod);
2111 if (sum == NULL)
2112 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 if (fracpart == 0.0)
2115 return sum;
2116 /* So far we've lost no information. Dealing with the
2117 * fractional part requires float arithmetic, and may
2118 * lose a little info.
2119 */
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002120 assert(PyLong_CheckExact(factor));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 dnum *= fracpart;
2124 fracpart = modf(dnum, &intpart);
2125 x = PyLong_FromDouble(intpart);
2126 if (x == NULL) {
2127 Py_DECREF(sum);
2128 return NULL;
2129 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 y = PyNumber_Add(sum, x);
2132 Py_DECREF(sum);
2133 Py_DECREF(x);
2134 *leftover += fracpart;
Serhiy Storchaka4ffd4652017-10-23 17:12:28 +03002135 assert(y == NULL || PyLong_CheckExact(y));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 return y;
2137 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 PyErr_Format(PyExc_TypeError,
2140 "unsupported type for timedelta %s component: %s",
2141 tag, Py_TYPE(num)->tp_name);
2142 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002143}
2144
2145static PyObject *
2146delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002150 /* Argument objects. */
2151 PyObject *day = NULL;
2152 PyObject *second = NULL;
2153 PyObject *us = NULL;
2154 PyObject *ms = NULL;
2155 PyObject *minute = NULL;
2156 PyObject *hour = NULL;
2157 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 PyObject *x = NULL; /* running sum of microseconds */
2160 PyObject *y = NULL; /* temp sum of microseconds */
2161 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 static char *keywords[] = {
2164 "days", "seconds", "microseconds", "milliseconds",
2165 "minutes", "hours", "weeks", NULL
2166 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2169 keywords,
2170 &day, &second, &us,
2171 &ms, &minute, &hour, &week) == 0)
2172 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 x = PyLong_FromLong(0);
2175 if (x == NULL)
2176 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178#define CLEANUP \
2179 Py_DECREF(x); \
2180 x = y; \
2181 if (x == NULL) \
2182 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 if (us) {
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002185 y = accum("microseconds", x, us, _PyLong_One, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 CLEANUP;
2187 }
2188 if (ms) {
2189 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2190 CLEANUP;
2191 }
2192 if (second) {
2193 y = accum("seconds", x, second, us_per_second, &leftover_us);
2194 CLEANUP;
2195 }
2196 if (minute) {
2197 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2198 CLEANUP;
2199 }
2200 if (hour) {
2201 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2202 CLEANUP;
2203 }
2204 if (day) {
2205 y = accum("days", x, day, us_per_day, &leftover_us);
2206 CLEANUP;
2207 }
2208 if (week) {
2209 y = accum("weeks", x, week, us_per_week, &leftover_us);
2210 CLEANUP;
2211 }
2212 if (leftover_us) {
2213 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002214 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002215 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002216 PyObject *temp;
2217
Victor Stinner69cc4872015-09-08 23:58:54 +02002218 whole_us = round(leftover_us);
2219 if (fabs(whole_us - leftover_us) == 0.5) {
2220 /* We're exactly halfway between two integers. In order
2221 * to do round-half-to-even, we must determine whether x
2222 * is odd. Note that x is odd when it's last bit is 1. The
2223 * code below uses bitwise and operation to check the last
2224 * bit. */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002225 temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */
Victor Stinner69cc4872015-09-08 23:58:54 +02002226 if (temp == NULL) {
2227 Py_DECREF(x);
2228 goto Done;
2229 }
2230 x_is_odd = PyObject_IsTrue(temp);
2231 Py_DECREF(temp);
2232 if (x_is_odd == -1) {
2233 Py_DECREF(x);
2234 goto Done;
2235 }
2236 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2237 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002238
Victor Stinner36a5a062013-08-28 01:53:39 +02002239 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 if (temp == NULL) {
2242 Py_DECREF(x);
2243 goto Done;
2244 }
2245 y = PyNumber_Add(x, temp);
2246 Py_DECREF(temp);
2247 CLEANUP;
2248 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250 self = microseconds_to_delta_ex(x, type);
2251 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002252Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002254
2255#undef CLEANUP
2256}
2257
2258static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002259delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 return (GET_TD_DAYS(self) != 0
2262 || GET_TD_SECONDS(self) != 0
2263 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002264}
2265
2266static PyObject *
2267delta_repr(PyDateTime_Delta *self)
2268{
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002269 PyObject *args = PyUnicode_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00002270
Utkarsh Upadhyaycc5a65c2017-07-25 23:51:33 +02002271 if (args == NULL) {
2272 return NULL;
2273 }
2274
2275 const char *sep = "";
2276
2277 if (GET_TD_DAYS(self) != 0) {
2278 Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self)));
2279 if (args == NULL) {
2280 return NULL;
2281 }
2282 sep = ", ";
2283 }
2284
2285 if (GET_TD_SECONDS(self) != 0) {
2286 Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep,
2287 GET_TD_SECONDS(self)));
2288 if (args == NULL) {
2289 return NULL;
2290 }
2291 sep = ", ";
2292 }
2293
2294 if (GET_TD_MICROSECONDS(self) != 0) {
2295 Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep,
2296 GET_TD_MICROSECONDS(self)));
2297 if (args == NULL) {
2298 return NULL;
2299 }
2300 }
2301
2302 if (PyUnicode_GET_LENGTH(args) == 0) {
2303 Py_SETREF(args, PyUnicode_FromString("0"));
2304 if (args == NULL) {
2305 return NULL;
2306 }
2307 }
2308
2309 PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name,
2310 args);
2311 Py_DECREF(args);
2312 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00002313}
2314
2315static PyObject *
2316delta_str(PyDateTime_Delta *self)
2317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 int us = GET_TD_MICROSECONDS(self);
2319 int seconds = GET_TD_SECONDS(self);
2320 int minutes = divmod(seconds, 60, &seconds);
2321 int hours = divmod(minutes, 60, &minutes);
2322 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002324 if (days) {
2325 if (us)
2326 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2327 days, (days == 1 || days == -1) ? "" : "s",
2328 hours, minutes, seconds, us);
2329 else
2330 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2331 days, (days == 1 || days == -1) ? "" : "s",
2332 hours, minutes, seconds);
2333 } else {
2334 if (us)
2335 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2336 hours, minutes, seconds, us);
2337 else
2338 return PyUnicode_FromFormat("%d:%02d:%02d",
2339 hours, minutes, seconds);
2340 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002341
Tim Peters2a799bf2002-12-16 20:18:38 +00002342}
2343
Tim Peters371935f2003-02-01 01:52:50 +00002344/* Pickle support, a simple use of __reduce__. */
2345
Tim Petersb57f8f02003-02-01 02:54:15 +00002346/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002347static PyObject *
2348delta_getstate(PyDateTime_Delta *self)
2349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350 return Py_BuildValue("iii", GET_TD_DAYS(self),
2351 GET_TD_SECONDS(self),
2352 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002353}
2354
Tim Peters2a799bf2002-12-16 20:18:38 +00002355static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002356delta_total_seconds(PyObject *self)
2357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002358 PyObject *total_seconds;
2359 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2362 if (total_microseconds == NULL)
2363 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002364
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002365 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002367 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002369}
2370
2371static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002372delta_reduce(PyDateTime_Delta* self)
2373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002375}
2376
2377#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2378
2379static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 {"days", T_INT, OFFSET(days), READONLY,
2382 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 {"seconds", T_INT, OFFSET(seconds), READONLY,
2385 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2388 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2389 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002390};
2391
2392static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2394 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2397 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002400};
2401
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002402static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002403PyDoc_STR("Difference between two datetime values.");
2404
2405static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 delta_add, /* nb_add */
2407 delta_subtract, /* nb_subtract */
2408 delta_multiply, /* nb_multiply */
2409 delta_remainder, /* nb_remainder */
2410 delta_divmod, /* nb_divmod */
2411 0, /* nb_power */
2412 (unaryfunc)delta_negative, /* nb_negative */
2413 (unaryfunc)delta_positive, /* nb_positive */
2414 (unaryfunc)delta_abs, /* nb_absolute */
2415 (inquiry)delta_bool, /* nb_bool */
2416 0, /*nb_invert*/
2417 0, /*nb_lshift*/
2418 0, /*nb_rshift*/
2419 0, /*nb_and*/
2420 0, /*nb_xor*/
2421 0, /*nb_or*/
2422 0, /*nb_int*/
2423 0, /*nb_reserved*/
2424 0, /*nb_float*/
2425 0, /*nb_inplace_add*/
2426 0, /*nb_inplace_subtract*/
2427 0, /*nb_inplace_multiply*/
2428 0, /*nb_inplace_remainder*/
2429 0, /*nb_inplace_power*/
2430 0, /*nb_inplace_lshift*/
2431 0, /*nb_inplace_rshift*/
2432 0, /*nb_inplace_and*/
2433 0, /*nb_inplace_xor*/
2434 0, /*nb_inplace_or*/
2435 delta_divide, /* nb_floor_divide */
2436 delta_truedivide, /* nb_true_divide */
2437 0, /* nb_inplace_floor_divide */
2438 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002439};
2440
2441static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 PyVarObject_HEAD_INIT(NULL, 0)
2443 "datetime.timedelta", /* tp_name */
2444 sizeof(PyDateTime_Delta), /* tp_basicsize */
2445 0, /* tp_itemsize */
2446 0, /* tp_dealloc */
2447 0, /* tp_print */
2448 0, /* tp_getattr */
2449 0, /* tp_setattr */
2450 0, /* tp_reserved */
2451 (reprfunc)delta_repr, /* tp_repr */
2452 &delta_as_number, /* tp_as_number */
2453 0, /* tp_as_sequence */
2454 0, /* tp_as_mapping */
2455 (hashfunc)delta_hash, /* tp_hash */
2456 0, /* tp_call */
2457 (reprfunc)delta_str, /* tp_str */
2458 PyObject_GenericGetAttr, /* tp_getattro */
2459 0, /* tp_setattro */
2460 0, /* tp_as_buffer */
2461 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2462 delta_doc, /* tp_doc */
2463 0, /* tp_traverse */
2464 0, /* tp_clear */
2465 delta_richcompare, /* tp_richcompare */
2466 0, /* tp_weaklistoffset */
2467 0, /* tp_iter */
2468 0, /* tp_iternext */
2469 delta_methods, /* tp_methods */
2470 delta_members, /* tp_members */
2471 0, /* tp_getset */
2472 0, /* tp_base */
2473 0, /* tp_dict */
2474 0, /* tp_descr_get */
2475 0, /* tp_descr_set */
2476 0, /* tp_dictoffset */
2477 0, /* tp_init */
2478 0, /* tp_alloc */
2479 delta_new, /* tp_new */
2480 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002481};
2482
2483/*
2484 * PyDateTime_Date implementation.
2485 */
2486
2487/* Accessor properties. */
2488
2489static PyObject *
2490date_year(PyDateTime_Date *self, void *unused)
2491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002493}
2494
2495static PyObject *
2496date_month(PyDateTime_Date *self, void *unused)
2497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002499}
2500
2501static PyObject *
2502date_day(PyDateTime_Date *self, void *unused)
2503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002505}
2506
2507static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002508 {"year", (getter)date_year},
2509 {"month", (getter)date_month},
2510 {"day", (getter)date_day},
2511 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002512};
2513
2514/* Constructors. */
2515
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002516static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002517
Tim Peters2a799bf2002-12-16 20:18:38 +00002518static PyObject *
2519date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002521 PyObject *self = NULL;
2522 PyObject *state;
2523 int year;
2524 int month;
2525 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002527 /* Check for invocation from pickle with __getstate__ state */
2528 if (PyTuple_GET_SIZE(args) == 1 &&
2529 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2530 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2531 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2532 {
2533 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002535 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2536 if (me != NULL) {
2537 char *pdata = PyBytes_AS_STRING(state);
2538 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2539 me->hashcode = -1;
2540 }
2541 return (PyObject *)me;
2542 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002544 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2545 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002546 self = new_date_ex(year, month, day, type);
2547 }
2548 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002549}
2550
2551/* Return new date from localtime(t). */
2552static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002553date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002554{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002555 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002557
Victor Stinnere4a994d2015-03-30 01:10:14 +02002558 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002559 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002560
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002561 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002562 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002563
2564 return PyObject_CallFunction(cls, "iii",
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002565 tm.tm_year + 1900,
2566 tm.tm_mon + 1,
2567 tm.tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002568}
2569
2570/* Return new date from current time.
2571 * We say this is equivalent to fromtimestamp(time.time()), and the
2572 * only way to be sure of that is to *call* time.time(). That's not
2573 * generally the same as calling C's time.
2574 */
2575static PyObject *
2576date_today(PyObject *cls, PyObject *dummy)
2577{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 PyObject *time;
2579 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002580 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002582 time = time_time();
2583 if (time == NULL)
2584 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 /* Note well: today() is a class method, so this may not call
2587 * date.fromtimestamp. For example, it may call
2588 * datetime.fromtimestamp. That's why we need all the accuracy
2589 * time.time() delivers; if someone were gonzo about optimization,
2590 * date.today() could get away with plain C time().
2591 */
Victor Stinner20401de2016-12-09 15:24:31 +01002592 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2593 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 Py_DECREF(time);
2595 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002596}
2597
2598/* Return new date from given timestamp (Python timestamp -- a double). */
2599static PyObject *
2600date_fromtimestamp(PyObject *cls, PyObject *args)
2601{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002602 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002603 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002604
Victor Stinner5d272cc2012-03-13 13:35:55 +01002605 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2606 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002608}
2609
2610/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2611 * the ordinal is out of range.
2612 */
2613static PyObject *
2614date_fromordinal(PyObject *cls, PyObject *args)
2615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 PyObject *result = NULL;
2617 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002619 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2620 int year;
2621 int month;
2622 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 if (ordinal < 1)
2625 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2626 ">= 1");
2627 else {
2628 ord_to_ymd(ordinal, &year, &month, &day);
2629 result = PyObject_CallFunction(cls, "iii",
2630 year, month, day);
2631 }
2632 }
2633 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002634}
2635
2636/*
2637 * Date arithmetic.
2638 */
2639
2640/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2641 * instead.
2642 */
2643static PyObject *
2644add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 PyObject *result = NULL;
2647 int year = GET_YEAR(date);
2648 int month = GET_MONTH(date);
2649 int deltadays = GET_TD_DAYS(delta);
2650 /* C-level overflow is impossible because |deltadays| < 1e9. */
2651 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 if (normalize_date(&year, &month, &day) >= 0)
2654 result = new_date(year, month, day);
2655 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002656}
2657
2658static PyObject *
2659date_add(PyObject *left, PyObject *right)
2660{
Brian Curtindfc80e32011-08-10 20:28:54 -05002661 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2662 Py_RETURN_NOTIMPLEMENTED;
2663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002664 if (PyDate_Check(left)) {
2665 /* date + ??? */
2666 if (PyDelta_Check(right))
2667 /* date + delta */
2668 return add_date_timedelta((PyDateTime_Date *) left,
2669 (PyDateTime_Delta *) right,
2670 0);
2671 }
2672 else {
2673 /* ??? + date
2674 * 'right' must be one of us, or we wouldn't have been called
2675 */
2676 if (PyDelta_Check(left))
2677 /* delta + date */
2678 return add_date_timedelta((PyDateTime_Date *) right,
2679 (PyDateTime_Delta *) left,
2680 0);
2681 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002682 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002683}
2684
2685static PyObject *
2686date_subtract(PyObject *left, PyObject *right)
2687{
Brian Curtindfc80e32011-08-10 20:28:54 -05002688 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2689 Py_RETURN_NOTIMPLEMENTED;
2690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002691 if (PyDate_Check(left)) {
2692 if (PyDate_Check(right)) {
2693 /* date - date */
2694 int left_ord = ymd_to_ord(GET_YEAR(left),
2695 GET_MONTH(left),
2696 GET_DAY(left));
2697 int right_ord = ymd_to_ord(GET_YEAR(right),
2698 GET_MONTH(right),
2699 GET_DAY(right));
2700 return new_delta(left_ord - right_ord, 0, 0, 0);
2701 }
2702 if (PyDelta_Check(right)) {
2703 /* date - delta */
2704 return add_date_timedelta((PyDateTime_Date *) left,
2705 (PyDateTime_Delta *) right,
2706 1);
2707 }
2708 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002709 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002710}
2711
2712
2713/* Various ways to turn a date into a string. */
2714
2715static PyObject *
2716date_repr(PyDateTime_Date *self)
2717{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2719 Py_TYPE(self)->tp_name,
2720 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002721}
2722
2723static PyObject *
2724date_isoformat(PyDateTime_Date *self)
2725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002726 return PyUnicode_FromFormat("%04d-%02d-%02d",
2727 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002728}
2729
Tim Peterse2df5ff2003-05-02 18:39:55 +00002730/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002731static PyObject *
2732date_str(PyDateTime_Date *self)
2733{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002734 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002735}
2736
2737
2738static PyObject *
2739date_ctime(PyDateTime_Date *self)
2740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002741 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002742}
2743
2744static PyObject *
2745date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002747 /* This method can be inherited, and needs to call the
2748 * timetuple() method appropriate to self's class.
2749 */
2750 PyObject *result;
2751 PyObject *tuple;
2752 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002753 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002754 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002756 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2757 &format))
2758 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002759
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002760 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002761 if (tuple == NULL)
2762 return NULL;
2763 result = wrap_strftime((PyObject *)self, format, tuple,
2764 (PyObject *)self);
2765 Py_DECREF(tuple);
2766 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002767}
2768
Eric Smith1ba31142007-09-11 18:06:02 +00002769static PyObject *
2770date_format(PyDateTime_Date *self, PyObject *args)
2771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002774 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2775 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002777 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002778 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002779 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002780
Victor Stinner20401de2016-12-09 15:24:31 +01002781 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
2782 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00002783}
2784
Tim Peters2a799bf2002-12-16 20:18:38 +00002785/* ISO methods. */
2786
2787static PyObject *
2788date_isoweekday(PyDateTime_Date *self)
2789{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002790 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002792 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002793}
2794
2795static PyObject *
2796date_isocalendar(PyDateTime_Date *self)
2797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002798 int year = GET_YEAR(self);
2799 int week1_monday = iso_week1_monday(year);
2800 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2801 int week;
2802 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002804 week = divmod(today - week1_monday, 7, &day);
2805 if (week < 0) {
2806 --year;
2807 week1_monday = iso_week1_monday(year);
2808 week = divmod(today - week1_monday, 7, &day);
2809 }
2810 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2811 ++year;
2812 week = 0;
2813 }
2814 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002815}
2816
2817/* Miscellaneous methods. */
2818
Tim Peters2a799bf2002-12-16 20:18:38 +00002819static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002820date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 if (PyDate_Check(other)) {
2823 int diff = memcmp(((PyDateTime_Date *)self)->data,
2824 ((PyDateTime_Date *)other)->data,
2825 _PyDateTime_DATE_DATASIZE);
2826 return diff_to_bool(diff, op);
2827 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002828 else
2829 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002830}
2831
2832static PyObject *
2833date_timetuple(PyDateTime_Date *self)
2834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002835 return build_struct_time(GET_YEAR(self),
2836 GET_MONTH(self),
2837 GET_DAY(self),
2838 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002839}
2840
Tim Peters12bf3392002-12-24 05:41:27 +00002841static PyObject *
2842date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2843{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 PyObject *clone;
2845 PyObject *tuple;
2846 int year = GET_YEAR(self);
2847 int month = GET_MONTH(self);
2848 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2851 &year, &month, &day))
2852 return NULL;
2853 tuple = Py_BuildValue("iii", year, month, day);
2854 if (tuple == NULL)
2855 return NULL;
2856 clone = date_new(Py_TYPE(self), tuple, NULL);
2857 Py_DECREF(tuple);
2858 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002859}
2860
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002861static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002862generic_hash(unsigned char *data, int len)
2863{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002864 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002865}
2866
2867
2868static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002869
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002870static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002871date_hash(PyDateTime_Date *self)
2872{
Benjamin Petersondec2df32016-09-09 17:46:24 -07002873 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002874 self->hashcode = generic_hash(
2875 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07002876 }
Guido van Rossum254348e2007-11-21 19:29:53 +00002877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002879}
2880
2881static PyObject *
2882date_toordinal(PyDateTime_Date *self)
2883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2885 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002886}
2887
2888static PyObject *
2889date_weekday(PyDateTime_Date *self)
2890{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002891 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002894}
2895
Tim Peters371935f2003-02-01 01:52:50 +00002896/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002897
Tim Petersb57f8f02003-02-01 02:54:15 +00002898/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002899static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002900date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002902 PyObject* field;
2903 field = PyBytes_FromStringAndSize((char*)self->data,
2904 _PyDateTime_DATE_DATASIZE);
2905 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002906}
2907
2908static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002909date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002911 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002912}
2913
2914static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002916 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002918 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2919 METH_CLASS,
2920 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2921 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002923 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2924 METH_CLASS,
2925 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2926 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002928 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2929 PyDoc_STR("Current date or datetime: same as "
2930 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002932 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002934 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2935 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002937 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2938 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002940 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2941 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002943 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2944 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002946 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2947 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2948 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002950 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2951 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002953 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2954 PyDoc_STR("Return the day of the week represented by the date.\n"
2955 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002957 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2958 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2959 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002961 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2962 PyDoc_STR("Return the day of the week represented by the date.\n"
2963 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002965 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2966 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002968 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2969 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002971 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002972};
2973
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002974static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002975PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002976
2977static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002978 date_add, /* nb_add */
2979 date_subtract, /* nb_subtract */
2980 0, /* nb_multiply */
2981 0, /* nb_remainder */
2982 0, /* nb_divmod */
2983 0, /* nb_power */
2984 0, /* nb_negative */
2985 0, /* nb_positive */
2986 0, /* nb_absolute */
2987 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002988};
2989
2990static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002991 PyVarObject_HEAD_INIT(NULL, 0)
2992 "datetime.date", /* tp_name */
2993 sizeof(PyDateTime_Date), /* tp_basicsize */
2994 0, /* tp_itemsize */
2995 0, /* tp_dealloc */
2996 0, /* tp_print */
2997 0, /* tp_getattr */
2998 0, /* tp_setattr */
2999 0, /* tp_reserved */
3000 (reprfunc)date_repr, /* tp_repr */
3001 &date_as_number, /* tp_as_number */
3002 0, /* tp_as_sequence */
3003 0, /* tp_as_mapping */
3004 (hashfunc)date_hash, /* tp_hash */
3005 0, /* tp_call */
3006 (reprfunc)date_str, /* tp_str */
3007 PyObject_GenericGetAttr, /* tp_getattro */
3008 0, /* tp_setattro */
3009 0, /* tp_as_buffer */
3010 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3011 date_doc, /* tp_doc */
3012 0, /* tp_traverse */
3013 0, /* tp_clear */
3014 date_richcompare, /* tp_richcompare */
3015 0, /* tp_weaklistoffset */
3016 0, /* tp_iter */
3017 0, /* tp_iternext */
3018 date_methods, /* tp_methods */
3019 0, /* tp_members */
3020 date_getset, /* tp_getset */
3021 0, /* tp_base */
3022 0, /* tp_dict */
3023 0, /* tp_descr_get */
3024 0, /* tp_descr_set */
3025 0, /* tp_dictoffset */
3026 0, /* tp_init */
3027 0, /* tp_alloc */
3028 date_new, /* tp_new */
3029 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003030};
3031
3032/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003033 * PyDateTime_TZInfo implementation.
3034 */
3035
3036/* This is a pure abstract base class, so doesn't do anything beyond
3037 * raising NotImplemented exceptions. Real tzinfo classes need
3038 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003039 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003040 * be subclasses of this tzinfo class, which is easy and quick to check).
3041 *
3042 * Note: For reasons having to do with pickling of subclasses, we have
3043 * to allow tzinfo objects to be instantiated. This wasn't an issue
3044 * in the Python implementation (__init__() could raise NotImplementedError
3045 * there without ill effect), but doing so in the C implementation hit a
3046 * brick wall.
3047 */
3048
3049static PyObject *
3050tzinfo_nogo(const char* methodname)
3051{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003052 PyErr_Format(PyExc_NotImplementedError,
3053 "a tzinfo subclass must implement %s()",
3054 methodname);
3055 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003056}
3057
3058/* Methods. A subclass must implement these. */
3059
Tim Peters52dcce22003-01-23 16:36:11 +00003060static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003061tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3062{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003063 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003064}
3065
Tim Peters52dcce22003-01-23 16:36:11 +00003066static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003067tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003069 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003070}
3071
Tim Peters52dcce22003-01-23 16:36:11 +00003072static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003073tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003075 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003076}
3077
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003078
3079static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3080 PyDateTime_Delta *delta,
3081 int factor);
3082static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3083static PyObject *datetime_dst(PyObject *self, PyObject *);
3084
Tim Peters52dcce22003-01-23 16:36:11 +00003085static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003086tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003087{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003088 PyObject *result = NULL;
3089 PyObject *off = NULL, *dst = NULL;
3090 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003091
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003092 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003093 PyErr_SetString(PyExc_TypeError,
3094 "fromutc: argument must be a datetime");
3095 return NULL;
3096 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003097 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003098 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3099 "is not self");
3100 return NULL;
3101 }
Tim Peters52dcce22003-01-23 16:36:11 +00003102
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003103 off = datetime_utcoffset(dt, NULL);
3104 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003105 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003106 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003107 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3108 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003109 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 }
Tim Peters52dcce22003-01-23 16:36:11 +00003111
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003112 dst = datetime_dst(dt, NULL);
3113 if (dst == NULL)
3114 goto Fail;
3115 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003116 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3117 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003118 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003119 }
Tim Peters52dcce22003-01-23 16:36:11 +00003120
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003121 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3122 if (delta == NULL)
3123 goto Fail;
3124 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003126 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003127
3128 Py_DECREF(dst);
3129 dst = call_dst(GET_DT_TZINFO(dt), result);
3130 if (dst == NULL)
3131 goto Fail;
3132 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003133 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003134 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003135 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003136 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003137 if (result == NULL)
3138 goto Fail;
3139 }
3140 Py_DECREF(delta);
3141 Py_DECREF(dst);
3142 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003144
3145Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003146 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3147 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003149 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003150Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003151 Py_XDECREF(off);
3152 Py_XDECREF(dst);
3153 Py_XDECREF(delta);
3154 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003155 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003156}
3157
Tim Peters2a799bf2002-12-16 20:18:38 +00003158/*
3159 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003160 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003161 */
3162
Guido van Rossum177e41a2003-01-30 22:06:23 +00003163static PyObject *
3164tzinfo_reduce(PyObject *self)
3165{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003166 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003167 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003168 _Py_IDENTIFIER(__getinitargs__);
3169 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003170
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003171 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003173 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003174 Py_DECREF(getinitargs);
3175 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003176 return NULL;
3177 }
3178 }
3179 else {
3180 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003181
3182 args = PyTuple_New(0);
3183 if (args == NULL) {
3184 return NULL;
3185 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003186 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003187
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003188 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003189 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003190 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003191 Py_DECREF(getstate);
3192 if (state == NULL) {
3193 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003194 return NULL;
3195 }
3196 }
3197 else {
3198 PyObject **dictptr;
3199 PyErr_Clear();
3200 state = Py_None;
3201 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003202 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003203 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003204 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003205 Py_INCREF(state);
3206 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 if (state == Py_None) {
3209 Py_DECREF(state);
3210 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3211 }
3212 else
3213 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003214}
Tim Peters2a799bf2002-12-16 20:18:38 +00003215
3216static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003218 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3219 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003221 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003222 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3223 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003225 {"dst", (PyCFunction)tzinfo_dst, METH_O,
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003226 PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003228 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003229 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003231 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3232 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003234 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003235};
3236
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003237static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003238PyDoc_STR("Abstract base class for time zone info objects.");
3239
Neal Norwitz227b5332006-03-22 09:28:35 +00003240static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003241 PyVarObject_HEAD_INIT(NULL, 0)
3242 "datetime.tzinfo", /* tp_name */
3243 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3244 0, /* tp_itemsize */
3245 0, /* tp_dealloc */
3246 0, /* tp_print */
3247 0, /* tp_getattr */
3248 0, /* tp_setattr */
3249 0, /* tp_reserved */
3250 0, /* tp_repr */
3251 0, /* tp_as_number */
3252 0, /* tp_as_sequence */
3253 0, /* tp_as_mapping */
3254 0, /* tp_hash */
3255 0, /* tp_call */
3256 0, /* tp_str */
3257 PyObject_GenericGetAttr, /* tp_getattro */
3258 0, /* tp_setattro */
3259 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003260 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003261 tzinfo_doc, /* tp_doc */
3262 0, /* tp_traverse */
3263 0, /* tp_clear */
3264 0, /* tp_richcompare */
3265 0, /* tp_weaklistoffset */
3266 0, /* tp_iter */
3267 0, /* tp_iternext */
3268 tzinfo_methods, /* tp_methods */
3269 0, /* tp_members */
3270 0, /* tp_getset */
3271 0, /* tp_base */
3272 0, /* tp_dict */
3273 0, /* tp_descr_get */
3274 0, /* tp_descr_set */
3275 0, /* tp_dictoffset */
3276 0, /* tp_init */
3277 0, /* tp_alloc */
3278 PyType_GenericNew, /* tp_new */
3279 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003280};
3281
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003282static char *timezone_kws[] = {"offset", "name", NULL};
3283
3284static PyObject *
3285timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3286{
3287 PyObject *offset;
3288 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003289 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3290 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003291 return new_timezone(offset, name);
3292
3293 return NULL;
3294}
3295
3296static void
3297timezone_dealloc(PyDateTime_TimeZone *self)
3298{
3299 Py_CLEAR(self->offset);
3300 Py_CLEAR(self->name);
3301 Py_TYPE(self)->tp_free((PyObject *)self);
3302}
3303
3304static PyObject *
3305timezone_richcompare(PyDateTime_TimeZone *self,
3306 PyDateTime_TimeZone *other, int op)
3307{
Brian Curtindfc80e32011-08-10 20:28:54 -05003308 if (op != Py_EQ && op != Py_NE)
3309 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003310 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003311 if (op == Py_EQ)
3312 Py_RETURN_FALSE;
3313 else
3314 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003315 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003316 return delta_richcompare(self->offset, other->offset, op);
3317}
3318
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003319static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003320timezone_hash(PyDateTime_TimeZone *self)
3321{
3322 return delta_hash((PyDateTime_Delta *)self->offset);
3323}
3324
3325/* Check argument type passed to tzname, utcoffset, or dst methods.
3326 Returns 0 for good argument. Returns -1 and sets exception info
3327 otherwise.
3328 */
3329static int
3330_timezone_check_argument(PyObject *dt, const char *meth)
3331{
3332 if (dt == Py_None || PyDateTime_Check(dt))
3333 return 0;
3334 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3335 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3336 return -1;
3337}
3338
3339static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003340timezone_repr(PyDateTime_TimeZone *self)
3341{
3342 /* Note that although timezone is not subclassable, it is convenient
3343 to use Py_TYPE(self)->tp_name here. */
3344 const char *type_name = Py_TYPE(self)->tp_name;
3345
3346 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3347 return PyUnicode_FromFormat("%s.utc", type_name);
3348
3349 if (self->name == NULL)
3350 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3351
3352 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3353 self->name);
3354}
3355
3356
3357static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003358timezone_str(PyDateTime_TimeZone *self)
3359{
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003360 int hours, minutes, seconds, microseconds;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003361 PyObject *offset;
3362 char sign;
3363
3364 if (self->name != NULL) {
3365 Py_INCREF(self->name);
3366 return self->name;
3367 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003368 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003369 (GET_TD_DAYS(self->offset) == 0 &&
3370 GET_TD_SECONDS(self->offset) == 0 &&
3371 GET_TD_MICROSECONDS(self->offset) == 0))
3372 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003373 /* Offset is normalized, so it is negative if days < 0 */
3374 if (GET_TD_DAYS(self->offset) < 0) {
3375 sign = '-';
3376 offset = delta_negative((PyDateTime_Delta *)self->offset);
3377 if (offset == NULL)
3378 return NULL;
3379 }
3380 else {
3381 sign = '+';
3382 offset = self->offset;
3383 Py_INCREF(offset);
3384 }
3385 /* Offset is not negative here. */
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003386 microseconds = GET_TD_MICROSECONDS(offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003387 seconds = GET_TD_SECONDS(offset);
3388 Py_DECREF(offset);
3389 minutes = divmod(seconds, 60, &seconds);
3390 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky018d3532017-07-31 10:26:50 -04003391 if (microseconds != 0) {
3392 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d",
3393 sign, hours, minutes,
3394 seconds, microseconds);
3395 }
3396 if (seconds != 0) {
3397 return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d",
3398 sign, hours, minutes, seconds);
3399 }
Victor Stinner6ced7c42011-03-21 18:15:42 +01003400 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003401}
3402
3403static PyObject *
3404timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3405{
3406 if (_timezone_check_argument(dt, "tzname") == -1)
3407 return NULL;
3408
3409 return timezone_str(self);
3410}
3411
3412static PyObject *
3413timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3414{
3415 if (_timezone_check_argument(dt, "utcoffset") == -1)
3416 return NULL;
3417
3418 Py_INCREF(self->offset);
3419 return self->offset;
3420}
3421
3422static PyObject *
3423timezone_dst(PyObject *self, PyObject *dt)
3424{
3425 if (_timezone_check_argument(dt, "dst") == -1)
3426 return NULL;
3427
3428 Py_RETURN_NONE;
3429}
3430
3431static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003432timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3433{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003434 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003435 PyErr_SetString(PyExc_TypeError,
3436 "fromutc: argument must be a datetime");
3437 return NULL;
3438 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003439 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003440 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3441 "is not self");
3442 return NULL;
3443 }
3444
3445 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3446}
3447
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003448static PyObject *
3449timezone_getinitargs(PyDateTime_TimeZone *self)
3450{
3451 if (self->name == NULL)
3452 return Py_BuildValue("(O)", self->offset);
3453 return Py_BuildValue("(OO)", self->offset, self->name);
3454}
3455
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003456static PyMethodDef timezone_methods[] = {
3457 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3458 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003459 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003460
3461 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003462 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003463
3464 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003465 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003466
3467 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3468 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3469
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003470 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3471 PyDoc_STR("pickle support")},
3472
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003473 {NULL, NULL}
3474};
3475
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003476static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003477PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3478
3479static PyTypeObject PyDateTime_TimeZoneType = {
3480 PyVarObject_HEAD_INIT(NULL, 0)
3481 "datetime.timezone", /* tp_name */
3482 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3483 0, /* tp_itemsize */
3484 (destructor)timezone_dealloc, /* tp_dealloc */
3485 0, /* tp_print */
3486 0, /* tp_getattr */
3487 0, /* tp_setattr */
3488 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003489 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003490 0, /* tp_as_number */
3491 0, /* tp_as_sequence */
3492 0, /* tp_as_mapping */
3493 (hashfunc)timezone_hash, /* tp_hash */
3494 0, /* tp_call */
3495 (reprfunc)timezone_str, /* tp_str */
3496 0, /* tp_getattro */
3497 0, /* tp_setattro */
3498 0, /* tp_as_buffer */
3499 Py_TPFLAGS_DEFAULT, /* tp_flags */
3500 timezone_doc, /* tp_doc */
3501 0, /* tp_traverse */
3502 0, /* tp_clear */
3503 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3504 0, /* tp_weaklistoffset */
3505 0, /* tp_iter */
3506 0, /* tp_iternext */
3507 timezone_methods, /* tp_methods */
3508 0, /* tp_members */
3509 0, /* tp_getset */
3510 &PyDateTime_TZInfoType, /* tp_base */
3511 0, /* tp_dict */
3512 0, /* tp_descr_get */
3513 0, /* tp_descr_set */
3514 0, /* tp_dictoffset */
3515 0, /* tp_init */
3516 0, /* tp_alloc */
3517 timezone_new, /* tp_new */
3518};
3519
Tim Peters2a799bf2002-12-16 20:18:38 +00003520/*
Tim Peters37f39822003-01-10 03:49:02 +00003521 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003522 */
3523
Tim Peters37f39822003-01-10 03:49:02 +00003524/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003525 */
3526
3527static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003528time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003530 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003531}
3532
Tim Peters37f39822003-01-10 03:49:02 +00003533static PyObject *
3534time_minute(PyDateTime_Time *self, void *unused)
3535{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003536 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003537}
3538
3539/* The name time_second conflicted with some platform header file. */
3540static PyObject *
3541py_time_second(PyDateTime_Time *self, void *unused)
3542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003543 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003544}
3545
3546static PyObject *
3547time_microsecond(PyDateTime_Time *self, void *unused)
3548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003549 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003550}
3551
3552static PyObject *
3553time_tzinfo(PyDateTime_Time *self, void *unused)
3554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3556 Py_INCREF(result);
3557 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003558}
3559
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003560static PyObject *
3561time_fold(PyDateTime_Time *self, void *unused)
3562{
3563 return PyLong_FromLong(TIME_GET_FOLD(self));
3564}
3565
Tim Peters37f39822003-01-10 03:49:02 +00003566static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003567 {"hour", (getter)time_hour},
3568 {"minute", (getter)time_minute},
3569 {"second", (getter)py_time_second},
3570 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003571 {"tzinfo", (getter)time_tzinfo},
3572 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003573 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003574};
3575
3576/*
3577 * Constructors.
3578 */
3579
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003580static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003581 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003582
Tim Peters2a799bf2002-12-16 20:18:38 +00003583static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003584time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003585{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003586 PyObject *self = NULL;
3587 PyObject *state;
3588 int hour = 0;
3589 int minute = 0;
3590 int second = 0;
3591 int usecond = 0;
3592 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003593 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003595 /* Check for invocation from pickle with __getstate__ state */
3596 if (PyTuple_GET_SIZE(args) >= 1 &&
3597 PyTuple_GET_SIZE(args) <= 2 &&
3598 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3599 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003600 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003601 {
3602 PyDateTime_Time *me;
3603 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003605 if (PyTuple_GET_SIZE(args) == 2) {
3606 tzinfo = PyTuple_GET_ITEM(args, 1);
3607 if (check_tzinfo_subclass(tzinfo) < 0) {
3608 PyErr_SetString(PyExc_TypeError, "bad "
3609 "tzinfo state arg");
3610 return NULL;
3611 }
3612 }
3613 aware = (char)(tzinfo != Py_None);
3614 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3615 if (me != NULL) {
3616 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003618 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3619 me->hashcode = -1;
3620 me->hastzinfo = aware;
3621 if (aware) {
3622 Py_INCREF(tzinfo);
3623 me->tzinfo = tzinfo;
3624 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003625 if (pdata[0] & (1 << 7)) {
3626 me->data[0] -= 128;
3627 me->fold = 1;
3628 }
3629 else {
3630 me->fold = 0;
3631 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003632 }
3633 return (PyObject *)me;
3634 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003635
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003636 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003637 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003638 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003639 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3640 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003641 }
3642 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003643}
3644
3645/*
3646 * Destructor.
3647 */
3648
3649static void
Tim Peters37f39822003-01-10 03:49:02 +00003650time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003652 if (HASTZINFO(self)) {
3653 Py_XDECREF(self->tzinfo);
3654 }
3655 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003656}
3657
3658/*
Tim Peters855fe882002-12-22 03:43:39 +00003659 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003660 */
3661
Tim Peters2a799bf2002-12-16 20:18:38 +00003662/* These are all METH_NOARGS, so don't need to check the arglist. */
3663static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003664time_utcoffset(PyObject *self, PyObject *unused) {
3665 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003666}
3667
3668static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003669time_dst(PyObject *self, PyObject *unused) {
3670 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003671}
3672
3673static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003674time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003675 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003676}
3677
3678/*
Tim Peters37f39822003-01-10 03:49:02 +00003679 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003680 */
3681
3682static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003683time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003684{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003685 const char *type_name = Py_TYPE(self)->tp_name;
3686 int h = TIME_GET_HOUR(self);
3687 int m = TIME_GET_MINUTE(self);
3688 int s = TIME_GET_SECOND(self);
3689 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003690 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003691 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003693 if (us)
3694 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3695 type_name, h, m, s, us);
3696 else if (s)
3697 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3698 type_name, h, m, s);
3699 else
3700 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3701 if (result != NULL && HASTZINFO(self))
3702 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003703 if (result != NULL && fold)
3704 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003705 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003706}
3707
Tim Peters37f39822003-01-10 03:49:02 +00003708static PyObject *
3709time_str(PyDateTime_Time *self)
3710{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003711 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003712}
Tim Peters2a799bf2002-12-16 20:18:38 +00003713
3714static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003715time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003717 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003718 char *timespec = NULL;
3719 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003720 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003721 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003722 static char *specs[][2] = {
3723 {"hours", "%02d"},
3724 {"minutes", "%02d:%02d"},
3725 {"seconds", "%02d:%02d:%02d"},
3726 {"milliseconds", "%02d:%02d:%02d.%03d"},
3727 {"microseconds", "%02d:%02d:%02d.%06d"},
3728 };
3729 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003730
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003731 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3732 return NULL;
3733
3734 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3735 if (us == 0) {
3736 /* seconds */
3737 given_spec = 2;
3738 }
3739 else {
3740 /* microseconds */
3741 given_spec = 4;
3742 }
3743 }
3744 else {
3745 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3746 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3747 if (given_spec == 3) {
3748 /* milliseconds */
3749 us = us / 1000;
3750 }
3751 break;
3752 }
3753 }
3754 }
3755
3756 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3757 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3758 return NULL;
3759 }
3760 else {
3761 result = PyUnicode_FromFormat(specs[given_spec][1],
3762 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3763 TIME_GET_SECOND(self), us);
3764 }
Tim Peters37f39822003-01-10 03:49:02 +00003765
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003766 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003767 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003769 /* We need to append the UTC offset. */
3770 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3771 Py_None) < 0) {
3772 Py_DECREF(result);
3773 return NULL;
3774 }
3775 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3776 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003777}
3778
Tim Peters37f39822003-01-10 03:49:02 +00003779static PyObject *
3780time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003782 PyObject *result;
3783 PyObject *tuple;
3784 PyObject *format;
3785 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003787 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3788 &format))
3789 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003791 /* Python's strftime does insane things with the year part of the
3792 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003793 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003794 */
3795 tuple = Py_BuildValue("iiiiiiiii",
3796 1900, 1, 1, /* year, month, day */
3797 TIME_GET_HOUR(self),
3798 TIME_GET_MINUTE(self),
3799 TIME_GET_SECOND(self),
3800 0, 1, -1); /* weekday, daynum, dst */
3801 if (tuple == NULL)
3802 return NULL;
3803 assert(PyTuple_Size(tuple) == 9);
3804 result = wrap_strftime((PyObject *)self, format, tuple,
3805 Py_None);
3806 Py_DECREF(tuple);
3807 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003808}
Tim Peters2a799bf2002-12-16 20:18:38 +00003809
3810/*
3811 * Miscellaneous methods.
3812 */
3813
Tim Peters37f39822003-01-10 03:49:02 +00003814static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003815time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003816{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003817 PyObject *result = NULL;
3818 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003819 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003820
Brian Curtindfc80e32011-08-10 20:28:54 -05003821 if (! PyTime_Check(other))
3822 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003823
3824 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003825 diff = memcmp(((PyDateTime_Time *)self)->data,
3826 ((PyDateTime_Time *)other)->data,
3827 _PyDateTime_TIME_DATASIZE);
3828 return diff_to_bool(diff, op);
3829 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003830 offset1 = time_utcoffset(self, NULL);
3831 if (offset1 == NULL)
3832 return NULL;
3833 offset2 = time_utcoffset(other, NULL);
3834 if (offset2 == NULL)
3835 goto done;
3836 /* If they're both naive, or both aware and have the same offsets,
3837 * we get off cheap. Note that if they're both naive, offset1 ==
3838 * offset2 == Py_None at this point.
3839 */
3840 if ((offset1 == offset2) ||
3841 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3842 delta_cmp(offset1, offset2) == 0)) {
3843 diff = memcmp(((PyDateTime_Time *)self)->data,
3844 ((PyDateTime_Time *)other)->data,
3845 _PyDateTime_TIME_DATASIZE);
3846 result = diff_to_bool(diff, op);
3847 }
3848 /* The hard case: both aware with different UTC offsets */
3849 else if (offset1 != Py_None && offset2 != Py_None) {
3850 int offsecs1, offsecs2;
3851 assert(offset1 != offset2); /* else last "if" handled it */
3852 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3853 TIME_GET_MINUTE(self) * 60 +
3854 TIME_GET_SECOND(self) -
3855 GET_TD_DAYS(offset1) * 86400 -
3856 GET_TD_SECONDS(offset1);
3857 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3858 TIME_GET_MINUTE(other) * 60 +
3859 TIME_GET_SECOND(other) -
3860 GET_TD_DAYS(offset2) * 86400 -
3861 GET_TD_SECONDS(offset2);
3862 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003863 if (diff == 0)
3864 diff = TIME_GET_MICROSECOND(self) -
3865 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003866 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003867 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003868 else if (op == Py_EQ) {
3869 result = Py_False;
3870 Py_INCREF(result);
3871 }
3872 else if (op == Py_NE) {
3873 result = Py_True;
3874 Py_INCREF(result);
3875 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003876 else {
3877 PyErr_SetString(PyExc_TypeError,
3878 "can't compare offset-naive and "
3879 "offset-aware times");
3880 }
3881 done:
3882 Py_DECREF(offset1);
3883 Py_XDECREF(offset2);
3884 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003885}
3886
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003887static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003888time_hash(PyDateTime_Time *self)
3889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003890 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003891 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01003892 if (TIME_GET_FOLD(self)) {
3893 self0 = new_time_ex2(TIME_GET_HOUR(self),
3894 TIME_GET_MINUTE(self),
3895 TIME_GET_SECOND(self),
3896 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003897 HASTZINFO(self) ? self->tzinfo : Py_None,
3898 0, Py_TYPE(self));
3899 if (self0 == NULL)
3900 return -1;
3901 }
3902 else {
3903 self0 = (PyObject *)self;
3904 Py_INCREF(self0);
3905 }
3906 offset = time_utcoffset(self0, NULL);
3907 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003908
3909 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003910 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003912 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003913 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003914 self->hashcode = generic_hash(
3915 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003916 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003917 PyObject *temp1, *temp2;
3918 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003919 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003920 seconds = TIME_GET_HOUR(self) * 3600 +
3921 TIME_GET_MINUTE(self) * 60 +
3922 TIME_GET_SECOND(self);
3923 microseconds = TIME_GET_MICROSECOND(self);
3924 temp1 = new_delta(0, seconds, microseconds, 1);
3925 if (temp1 == NULL) {
3926 Py_DECREF(offset);
3927 return -1;
3928 }
3929 temp2 = delta_subtract(temp1, offset);
3930 Py_DECREF(temp1);
3931 if (temp2 == NULL) {
3932 Py_DECREF(offset);
3933 return -1;
3934 }
3935 self->hashcode = PyObject_Hash(temp2);
3936 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003937 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003938 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003939 }
3940 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003941}
Tim Peters2a799bf2002-12-16 20:18:38 +00003942
Tim Peters12bf3392002-12-24 05:41:27 +00003943static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003944time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003946 PyObject *clone;
3947 PyObject *tuple;
3948 int hh = TIME_GET_HOUR(self);
3949 int mm = TIME_GET_MINUTE(self);
3950 int ss = TIME_GET_SECOND(self);
3951 int us = TIME_GET_MICROSECOND(self);
3952 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003953 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003954
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003955 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003956 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003957 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003958 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03003959 if (fold != 0 && fold != 1) {
3960 PyErr_SetString(PyExc_ValueError,
3961 "fold must be either 0 or 1");
3962 return NULL;
3963 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003964 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3965 if (tuple == NULL)
3966 return NULL;
3967 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003968 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003969 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003970 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003971 Py_DECREF(tuple);
3972 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003973}
3974
Tim Peters371935f2003-02-01 01:52:50 +00003975/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003976
Tim Peters33e0f382003-01-10 02:05:14 +00003977/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003978 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3979 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003980 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003981 */
3982static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003983time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00003984{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003985 PyObject *basestate;
3986 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003988 basestate = PyBytes_FromStringAndSize((char *)self->data,
3989 _PyDateTime_TIME_DATASIZE);
3990 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003991 if (proto > 3 && TIME_GET_FOLD(self))
3992 /* Set the first bit of the first byte */
3993 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003994 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3995 result = PyTuple_Pack(1, basestate);
3996 else
3997 result = PyTuple_Pack(2, basestate, self->tzinfo);
3998 Py_DECREF(basestate);
3999 }
4000 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004001}
4002
4003static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004004time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00004005{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004006 int proto;
4007 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004008 return NULL;
4009
4010 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00004011}
4012
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004013static PyObject *
4014time_reduce(PyDateTime_Time *self, PyObject *arg)
4015{
4016 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
4017}
4018
Tim Peters37f39822003-01-10 03:49:02 +00004019static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004020
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004021 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4022 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4023 "[+HH:MM].\n\n"
4024 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004026 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4027 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00004028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004029 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4030 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004032 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4033 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004035 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4036 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004038 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4039 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004041 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4042 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004043
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004044 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004045 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004046
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004047 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4048 PyDoc_STR("__reduce__() -> (cls, state)")},
4049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004050 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004051};
4052
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004053static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004054PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4055\n\
4056All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004057a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004058
Neal Norwitz227b5332006-03-22 09:28:35 +00004059static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004060 PyVarObject_HEAD_INIT(NULL, 0)
4061 "datetime.time", /* tp_name */
4062 sizeof(PyDateTime_Time), /* tp_basicsize */
4063 0, /* tp_itemsize */
4064 (destructor)time_dealloc, /* tp_dealloc */
4065 0, /* tp_print */
4066 0, /* tp_getattr */
4067 0, /* tp_setattr */
4068 0, /* tp_reserved */
4069 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004070 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004071 0, /* tp_as_sequence */
4072 0, /* tp_as_mapping */
4073 (hashfunc)time_hash, /* tp_hash */
4074 0, /* tp_call */
4075 (reprfunc)time_str, /* tp_str */
4076 PyObject_GenericGetAttr, /* tp_getattro */
4077 0, /* tp_setattro */
4078 0, /* tp_as_buffer */
4079 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4080 time_doc, /* tp_doc */
4081 0, /* tp_traverse */
4082 0, /* tp_clear */
4083 time_richcompare, /* tp_richcompare */
4084 0, /* tp_weaklistoffset */
4085 0, /* tp_iter */
4086 0, /* tp_iternext */
4087 time_methods, /* tp_methods */
4088 0, /* tp_members */
4089 time_getset, /* tp_getset */
4090 0, /* tp_base */
4091 0, /* tp_dict */
4092 0, /* tp_descr_get */
4093 0, /* tp_descr_set */
4094 0, /* tp_dictoffset */
4095 0, /* tp_init */
4096 time_alloc, /* tp_alloc */
4097 time_new, /* tp_new */
4098 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004099};
4100
4101/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004102 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004103 */
4104
Tim Petersa9bc1682003-01-11 03:39:11 +00004105/* Accessor properties. Properties for day, month, and year are inherited
4106 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004107 */
4108
4109static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004110datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004111{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004112 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004113}
4114
Tim Petersa9bc1682003-01-11 03:39:11 +00004115static PyObject *
4116datetime_minute(PyDateTime_DateTime *self, void *unused)
4117{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004118 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004119}
4120
4121static PyObject *
4122datetime_second(PyDateTime_DateTime *self, void *unused)
4123{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004124 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004125}
4126
4127static PyObject *
4128datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004131}
4132
4133static PyObject *
4134datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004136 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4137 Py_INCREF(result);
4138 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004139}
4140
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004141static PyObject *
4142datetime_fold(PyDateTime_DateTime *self, void *unused)
4143{
4144 return PyLong_FromLong(DATE_GET_FOLD(self));
4145}
4146
Tim Petersa9bc1682003-01-11 03:39:11 +00004147static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004148 {"hour", (getter)datetime_hour},
4149 {"minute", (getter)datetime_minute},
4150 {"second", (getter)datetime_second},
4151 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004152 {"tzinfo", (getter)datetime_tzinfo},
4153 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004154 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004155};
4156
4157/*
4158 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004159 */
4160
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004161static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004162 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004163 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004164};
4165
Tim Peters2a799bf2002-12-16 20:18:38 +00004166static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004167datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004169 PyObject *self = NULL;
4170 PyObject *state;
4171 int year;
4172 int month;
4173 int day;
4174 int hour = 0;
4175 int minute = 0;
4176 int second = 0;
4177 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004178 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004179 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004181 /* Check for invocation from pickle with __getstate__ state */
4182 if (PyTuple_GET_SIZE(args) >= 1 &&
4183 PyTuple_GET_SIZE(args) <= 2 &&
4184 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4185 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004186 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004187 {
4188 PyDateTime_DateTime *me;
4189 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 if (PyTuple_GET_SIZE(args) == 2) {
4192 tzinfo = PyTuple_GET_ITEM(args, 1);
4193 if (check_tzinfo_subclass(tzinfo) < 0) {
4194 PyErr_SetString(PyExc_TypeError, "bad "
4195 "tzinfo state arg");
4196 return NULL;
4197 }
4198 }
4199 aware = (char)(tzinfo != Py_None);
4200 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4201 if (me != NULL) {
4202 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004204 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4205 me->hashcode = -1;
4206 me->hastzinfo = aware;
4207 if (aware) {
4208 Py_INCREF(tzinfo);
4209 me->tzinfo = tzinfo;
4210 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004211 if (pdata[2] & (1 << 7)) {
4212 me->data[2] -= 128;
4213 me->fold = 1;
4214 }
4215 else {
4216 me->fold = 0;
4217 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004218 }
4219 return (PyObject *)me;
4220 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004221
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004222 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004223 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004224 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004225 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004227 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004228 }
4229 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004230}
4231
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004232/* TM_FUNC is the shared type of _PyTime_localtime() and
4233 * _PyTime_gmtime(). */
4234typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004235
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004236/* As of version 2015f max fold in IANA database is
4237 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004238static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004239/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004240static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004241
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004242static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004243utc_to_seconds(int year, int month, int day,
4244 int hour, int minute, int second)
4245{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004246 long long ordinal;
4247
4248 /* ymd_to_ord() doesn't support year <= 0 */
4249 if (year < MINYEAR || year > MAXYEAR) {
4250 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4251 return -1;
4252 }
4253
4254 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004255 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4256}
4257
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004258static long long
4259local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004260{
4261 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004262 time_t t;
4263 u -= epoch;
4264 t = u;
4265 if (t != u) {
4266 PyErr_SetString(PyExc_OverflowError,
4267 "timestamp out of range for platform time_t");
4268 return -1;
4269 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004270 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004271 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004272 return utc_to_seconds(local_time.tm_year + 1900,
4273 local_time.tm_mon + 1,
4274 local_time.tm_mday,
4275 local_time.tm_hour,
4276 local_time.tm_min,
4277 local_time.tm_sec);
4278}
4279
Tim Petersa9bc1682003-01-11 03:39:11 +00004280/* Internal helper.
4281 * Build datetime from a time_t and a distinct count of microseconds.
4282 * Pass localtime or gmtime for f, to control the interpretation of timet.
4283 */
4284static PyObject *
4285datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004286 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004287{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004288 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004289 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004290
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004291 if (f(timet, &tm) != 0)
4292 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004293
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004294 year = tm.tm_year + 1900;
4295 month = tm.tm_mon + 1;
4296 day = tm.tm_mday;
4297 hour = tm.tm_hour;
4298 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004299 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004300 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004301 * except to the extent that passing them on to the datetime
4302 * constructor would raise ValueError for a reason that
4303 * made no sense to the user.
4304 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004305 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004306
Victor Stinnerb67f0962017-02-10 10:34:02 +01004307 /* local timezone requires to compute fold */
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004308 if (tzinfo == Py_None && f == _PyTime_localtime) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004309 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004310
4311 result_seconds = utc_to_seconds(year, month, day,
4312 hour, minute, second);
4313 /* Probe max_fold_seconds to detect a fold. */
4314 probe_seconds = local(epoch + timet - max_fold_seconds);
4315 if (probe_seconds == -1)
4316 return NULL;
4317 transition = result_seconds - probe_seconds - max_fold_seconds;
4318 if (transition < 0) {
4319 probe_seconds = local(epoch + timet + transition);
4320 if (probe_seconds == -1)
4321 return NULL;
4322 if (probe_seconds == result_seconds)
4323 fold = 1;
4324 }
4325 }
4326 return new_datetime_ex2(year, month, day, hour,
4327 minute, second, us, tzinfo, fold,
4328 (PyTypeObject *)cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004329}
4330
4331/* Internal helper.
4332 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4333 * to control the interpretation of the timestamp. Since a double doesn't
4334 * have enough bits to cover a datetime's full range of precision, it's
4335 * better to call datetime_from_timet_and_us provided you have a way
4336 * to get that much precision (e.g., C time() isn't good enough).
4337 */
4338static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004339datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004340 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004342 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004343 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004344
Victor Stinnere4a994d2015-03-30 01:10:14 +02004345 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004346 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004347 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004348
Victor Stinner21f58932012-03-14 00:15:40 +01004349 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004350}
4351
4352/* Internal helper.
4353 * Build most accurate possible datetime for current time. Pass localtime or
4354 * gmtime for f as appropriate.
4355 */
4356static PyObject *
4357datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4358{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004359 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004360 time_t secs;
4361 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004362
Victor Stinner1e2b6882015-09-18 13:23:02 +02004363 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004364 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004365 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004366
Victor Stinner1e2b6882015-09-18 13:23:02 +02004367 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004368}
4369
Larry Hastings61272b72014-01-07 12:41:53 -08004370/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004371
4372@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004373datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004374
4375 tz: object = None
4376 Timezone object.
4377
4378Returns new datetime object representing current time local to tz.
4379
4380If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004381[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004382
Larry Hastings31826802013-10-19 00:09:25 -07004383static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004384datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004385/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004387 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004388
Larry Hastings31826802013-10-19 00:09:25 -07004389 /* Return best possible local time -- this isn't constrained by the
4390 * precision of a timestamp.
4391 */
4392 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004393 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004394
Larry Hastings5c661892014-01-24 06:17:25 -08004395 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004396 tz == Py_None ? _PyTime_localtime :
4397 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004398 tz);
4399 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004400 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004401 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004402 }
4403 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004404}
4405
Tim Petersa9bc1682003-01-11 03:39:11 +00004406/* Return best possible UTC time -- this isn't constrained by the
4407 * precision of a timestamp.
4408 */
4409static PyObject *
4410datetime_utcnow(PyObject *cls, PyObject *dummy)
4411{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004412 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004413}
4414
Tim Peters2a799bf2002-12-16 20:18:38 +00004415/* Return new local datetime from timestamp (Python timestamp -- a double). */
4416static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004417datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004419 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004420 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004421 PyObject *tzinfo = Py_None;
4422 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004423
Victor Stinner5d272cc2012-03-13 13:35:55 +01004424 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004425 keywords, &timestamp, &tzinfo))
4426 return NULL;
4427 if (check_tzinfo_subclass(tzinfo) < 0)
4428 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004430 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004431 tzinfo == Py_None ? _PyTime_localtime :
4432 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004433 timestamp,
4434 tzinfo);
4435 if (self != NULL && tzinfo != Py_None) {
4436 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004437 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004438 }
4439 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004440}
4441
Tim Petersa9bc1682003-01-11 03:39:11 +00004442/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4443static PyObject *
4444datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4445{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004446 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004447 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004448
Victor Stinner5d272cc2012-03-13 13:35:55 +01004449 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004450 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004451 Py_None);
4452 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004453}
4454
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004455/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004456static PyObject *
4457datetime_strptime(PyObject *cls, PyObject *args)
4458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004459 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004460 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004461 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004462
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004463 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004464 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004465
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004466 if (module == NULL) {
4467 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004468 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004469 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004470 }
Victor Stinner20401de2016-12-09 15:24:31 +01004471 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4472 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004473}
4474
Tim Petersa9bc1682003-01-11 03:39:11 +00004475/* Return new datetime from date/datetime and time arguments. */
4476static PyObject *
4477datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4478{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004479 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004480 PyObject *date;
4481 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004482 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004483 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004484
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004485 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004486 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004487 &PyDateTime_TimeType, &time, &tzinfo)) {
4488 if (tzinfo == NULL) {
4489 if (HASTZINFO(time))
4490 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4491 else
4492 tzinfo = Py_None;
4493 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004494 result = PyObject_CallFunction(cls, "iiiiiiiO",
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004495 GET_YEAR(date),
4496 GET_MONTH(date),
4497 GET_DAY(date),
4498 TIME_GET_HOUR(time),
4499 TIME_GET_MINUTE(time),
4500 TIME_GET_SECOND(time),
4501 TIME_GET_MICROSECOND(time),
4502 tzinfo);
4503 if (result)
4504 DATE_SET_FOLD(result, TIME_GET_FOLD(time));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004505 }
4506 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004507}
Tim Peters2a799bf2002-12-16 20:18:38 +00004508
4509/*
4510 * Destructor.
4511 */
4512
4513static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004514datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004515{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004516 if (HASTZINFO(self)) {
4517 Py_XDECREF(self->tzinfo);
4518 }
4519 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004520}
4521
4522/*
4523 * Indirect access to tzinfo methods.
4524 */
4525
Tim Peters2a799bf2002-12-16 20:18:38 +00004526/* These are all METH_NOARGS, so don't need to check the arglist. */
4527static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004528datetime_utcoffset(PyObject *self, PyObject *unused) {
4529 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004530}
4531
4532static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004533datetime_dst(PyObject *self, PyObject *unused) {
4534 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004535}
4536
4537static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004538datetime_tzname(PyObject *self, PyObject *unused) {
4539 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004540}
4541
4542/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004543 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004544 */
4545
Tim Petersa9bc1682003-01-11 03:39:11 +00004546/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4547 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004548 */
4549static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004550add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004551 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004552{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004553 /* Note that the C-level additions can't overflow, because of
4554 * invariant bounds on the member values.
4555 */
4556 int year = GET_YEAR(date);
4557 int month = GET_MONTH(date);
4558 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4559 int hour = DATE_GET_HOUR(date);
4560 int minute = DATE_GET_MINUTE(date);
4561 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4562 int microsecond = DATE_GET_MICROSECOND(date) +
4563 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004565 assert(factor == 1 || factor == -1);
4566 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01004567 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004568 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01004569 }
4570
4571 return new_datetime(year, month, day,
4572 hour, minute, second, microsecond,
4573 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004574}
4575
4576static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004577datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004578{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004579 if (PyDateTime_Check(left)) {
4580 /* datetime + ??? */
4581 if (PyDelta_Check(right))
4582 /* datetime + delta */
4583 return add_datetime_timedelta(
4584 (PyDateTime_DateTime *)left,
4585 (PyDateTime_Delta *)right,
4586 1);
4587 }
4588 else if (PyDelta_Check(left)) {
4589 /* delta + datetime */
4590 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4591 (PyDateTime_Delta *) left,
4592 1);
4593 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004594 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004595}
4596
4597static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004598datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004600 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004602 if (PyDateTime_Check(left)) {
4603 /* datetime - ??? */
4604 if (PyDateTime_Check(right)) {
4605 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004606 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004607 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004608
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004609 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4610 offset2 = offset1 = Py_None;
4611 Py_INCREF(offset1);
4612 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004613 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004614 else {
4615 offset1 = datetime_utcoffset(left, NULL);
4616 if (offset1 == NULL)
4617 return NULL;
4618 offset2 = datetime_utcoffset(right, NULL);
4619 if (offset2 == NULL) {
4620 Py_DECREF(offset1);
4621 return NULL;
4622 }
4623 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4624 PyErr_SetString(PyExc_TypeError,
4625 "can't subtract offset-naive and "
4626 "offset-aware datetimes");
4627 Py_DECREF(offset1);
4628 Py_DECREF(offset2);
4629 return NULL;
4630 }
4631 }
4632 if ((offset1 != offset2) &&
4633 delta_cmp(offset1, offset2) != 0) {
4634 offdiff = delta_subtract(offset1, offset2);
4635 if (offdiff == NULL) {
4636 Py_DECREF(offset1);
4637 Py_DECREF(offset2);
4638 return NULL;
4639 }
4640 }
4641 Py_DECREF(offset1);
4642 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004643 delta_d = ymd_to_ord(GET_YEAR(left),
4644 GET_MONTH(left),
4645 GET_DAY(left)) -
4646 ymd_to_ord(GET_YEAR(right),
4647 GET_MONTH(right),
4648 GET_DAY(right));
4649 /* These can't overflow, since the values are
4650 * normalized. At most this gives the number of
4651 * seconds in one day.
4652 */
4653 delta_s = (DATE_GET_HOUR(left) -
4654 DATE_GET_HOUR(right)) * 3600 +
4655 (DATE_GET_MINUTE(left) -
4656 DATE_GET_MINUTE(right)) * 60 +
4657 (DATE_GET_SECOND(left) -
4658 DATE_GET_SECOND(right));
4659 delta_us = DATE_GET_MICROSECOND(left) -
4660 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004661 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004662 if (result == NULL)
4663 return NULL;
4664
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004665 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004666 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004667 Py_DECREF(offdiff);
4668 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004669 }
4670 else if (PyDelta_Check(right)) {
4671 /* datetime - delta */
4672 result = add_datetime_timedelta(
4673 (PyDateTime_DateTime *)left,
4674 (PyDateTime_Delta *)right,
4675 -1);
4676 }
4677 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004679 if (result == Py_NotImplemented)
4680 Py_INCREF(result);
4681 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004682}
4683
4684/* Various ways to turn a datetime into a string. */
4685
4686static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004687datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004689 const char *type_name = Py_TYPE(self)->tp_name;
4690 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004692 if (DATE_GET_MICROSECOND(self)) {
4693 baserepr = PyUnicode_FromFormat(
4694 "%s(%d, %d, %d, %d, %d, %d, %d)",
4695 type_name,
4696 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4697 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4698 DATE_GET_SECOND(self),
4699 DATE_GET_MICROSECOND(self));
4700 }
4701 else if (DATE_GET_SECOND(self)) {
4702 baserepr = PyUnicode_FromFormat(
4703 "%s(%d, %d, %d, %d, %d, %d)",
4704 type_name,
4705 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4706 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4707 DATE_GET_SECOND(self));
4708 }
4709 else {
4710 baserepr = PyUnicode_FromFormat(
4711 "%s(%d, %d, %d, %d, %d)",
4712 type_name,
4713 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4714 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4715 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004716 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4717 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004718 if (baserepr == NULL || ! HASTZINFO(self))
4719 return baserepr;
4720 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004721}
4722
Tim Petersa9bc1682003-01-11 03:39:11 +00004723static PyObject *
4724datetime_str(PyDateTime_DateTime *self)
4725{
Victor Stinner4c381542016-12-09 00:33:39 +01004726 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004727}
Tim Peters2a799bf2002-12-16 20:18:38 +00004728
4729static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004730datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004732 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004733 char *timespec = NULL;
4734 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004735 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004736 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004737 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004738 static char *specs[][2] = {
4739 {"hours", "%04d-%02d-%02d%c%02d"},
4740 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4741 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4742 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4743 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4744 };
4745 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004746
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004747 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004748 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004749
4750 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4751 if (us == 0) {
4752 /* seconds */
4753 given_spec = 2;
4754 }
4755 else {
4756 /* microseconds */
4757 given_spec = 4;
4758 }
4759 }
4760 else {
4761 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4762 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4763 if (given_spec == 3) {
4764 us = us / 1000;
4765 }
4766 break;
4767 }
4768 }
4769 }
4770
4771 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4772 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4773 return NULL;
4774 }
4775 else {
4776 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004777 GET_YEAR(self), GET_MONTH(self),
4778 GET_DAY(self), (int)sep,
4779 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4780 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004781 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004783 if (!result || !HASTZINFO(self))
4784 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004786 /* We need to append the UTC offset. */
4787 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4788 (PyObject *)self) < 0) {
4789 Py_DECREF(result);
4790 return NULL;
4791 }
4792 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4793 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004794}
4795
Tim Petersa9bc1682003-01-11 03:39:11 +00004796static PyObject *
4797datetime_ctime(PyDateTime_DateTime *self)
4798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004799 return format_ctime((PyDateTime_Date *)self,
4800 DATE_GET_HOUR(self),
4801 DATE_GET_MINUTE(self),
4802 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004803}
4804
Tim Peters2a799bf2002-12-16 20:18:38 +00004805/* Miscellaneous methods. */
4806
Tim Petersa9bc1682003-01-11 03:39:11 +00004807static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004808flip_fold(PyObject *dt)
4809{
4810 return new_datetime_ex2(GET_YEAR(dt),
4811 GET_MONTH(dt),
4812 GET_DAY(dt),
4813 DATE_GET_HOUR(dt),
4814 DATE_GET_MINUTE(dt),
4815 DATE_GET_SECOND(dt),
4816 DATE_GET_MICROSECOND(dt),
4817 HASTZINFO(dt) ?
4818 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4819 !DATE_GET_FOLD(dt),
4820 Py_TYPE(dt));
4821}
4822
4823static PyObject *
4824get_flip_fold_offset(PyObject *dt)
4825{
4826 PyObject *result, *flip_dt;
4827
4828 flip_dt = flip_fold(dt);
4829 if (flip_dt == NULL)
4830 return NULL;
4831 result = datetime_utcoffset(flip_dt, NULL);
4832 Py_DECREF(flip_dt);
4833 return result;
4834}
4835
4836/* PEP 495 exception: Whenever one or both of the operands in
4837 * inter-zone comparison is such that its utcoffset() depends
4838 * on the value of its fold fold attribute, the result is False.
4839 *
4840 * Return 1 if exception applies, 0 if not, and -1 on error.
4841 */
4842static int
4843pep495_eq_exception(PyObject *self, PyObject *other,
4844 PyObject *offset_self, PyObject *offset_other)
4845{
4846 int result = 0;
4847 PyObject *flip_offset;
4848
4849 flip_offset = get_flip_fold_offset(self);
4850 if (flip_offset == NULL)
4851 return -1;
4852 if (flip_offset != offset_self &&
4853 delta_cmp(flip_offset, offset_self))
4854 {
4855 result = 1;
4856 goto done;
4857 }
4858 Py_DECREF(flip_offset);
4859
4860 flip_offset = get_flip_fold_offset(other);
4861 if (flip_offset == NULL)
4862 return -1;
4863 if (flip_offset != offset_other &&
4864 delta_cmp(flip_offset, offset_other))
4865 result = 1;
4866 done:
4867 Py_DECREF(flip_offset);
4868 return result;
4869}
4870
4871static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004872datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004873{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004874 PyObject *result = NULL;
4875 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004876 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004878 if (! PyDateTime_Check(other)) {
4879 if (PyDate_Check(other)) {
4880 /* Prevent invocation of date_richcompare. We want to
4881 return NotImplemented here to give the other object
4882 a chance. But since DateTime is a subclass of
4883 Date, if the other object is a Date, it would
4884 compute an ordering based on the date part alone,
4885 and we don't want that. So force unequal or
4886 uncomparable here in that case. */
4887 if (op == Py_EQ)
4888 Py_RETURN_FALSE;
4889 if (op == Py_NE)
4890 Py_RETURN_TRUE;
4891 return cmperror(self, other);
4892 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004893 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004894 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004895
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004896 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004897 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4898 ((PyDateTime_DateTime *)other)->data,
4899 _PyDateTime_DATETIME_DATASIZE);
4900 return diff_to_bool(diff, op);
4901 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004902 offset1 = datetime_utcoffset(self, NULL);
4903 if (offset1 == NULL)
4904 return NULL;
4905 offset2 = datetime_utcoffset(other, NULL);
4906 if (offset2 == NULL)
4907 goto done;
4908 /* If they're both naive, or both aware and have the same offsets,
4909 * we get off cheap. Note that if they're both naive, offset1 ==
4910 * offset2 == Py_None at this point.
4911 */
4912 if ((offset1 == offset2) ||
4913 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4914 delta_cmp(offset1, offset2) == 0)) {
4915 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4916 ((PyDateTime_DateTime *)other)->data,
4917 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004918 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4919 int ex = pep495_eq_exception(self, other, offset1, offset2);
4920 if (ex == -1)
4921 goto done;
4922 if (ex)
4923 diff = 1;
4924 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004925 result = diff_to_bool(diff, op);
4926 }
4927 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004928 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004929
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004930 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004931 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4932 other);
4933 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004934 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004935 diff = GET_TD_DAYS(delta);
4936 if (diff == 0)
4937 diff = GET_TD_SECONDS(delta) |
4938 GET_TD_MICROSECONDS(delta);
4939 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004940 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4941 int ex = pep495_eq_exception(self, other, offset1, offset2);
4942 if (ex == -1)
4943 goto done;
4944 if (ex)
4945 diff = 1;
4946 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004947 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004948 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004949 else if (op == Py_EQ) {
4950 result = Py_False;
4951 Py_INCREF(result);
4952 }
4953 else if (op == Py_NE) {
4954 result = Py_True;
4955 Py_INCREF(result);
4956 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004957 else {
4958 PyErr_SetString(PyExc_TypeError,
4959 "can't compare offset-naive and "
4960 "offset-aware datetimes");
4961 }
4962 done:
4963 Py_DECREF(offset1);
4964 Py_XDECREF(offset2);
4965 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004966}
4967
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004968static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004969datetime_hash(PyDateTime_DateTime *self)
4970{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004971 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004972 PyObject *offset, *self0;
4973 if (DATE_GET_FOLD(self)) {
4974 self0 = new_datetime_ex2(GET_YEAR(self),
4975 GET_MONTH(self),
4976 GET_DAY(self),
4977 DATE_GET_HOUR(self),
4978 DATE_GET_MINUTE(self),
4979 DATE_GET_SECOND(self),
4980 DATE_GET_MICROSECOND(self),
4981 HASTZINFO(self) ? self->tzinfo : Py_None,
4982 0, Py_TYPE(self));
4983 if (self0 == NULL)
4984 return -1;
4985 }
4986 else {
4987 self0 = (PyObject *)self;
4988 Py_INCREF(self0);
4989 }
4990 offset = datetime_utcoffset(self0, NULL);
4991 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004992
4993 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004994 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004996 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004997 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004998 self->hashcode = generic_hash(
4999 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005000 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005001 PyObject *temp1, *temp2;
5002 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00005003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005004 assert(HASTZINFO(self));
5005 days = ymd_to_ord(GET_YEAR(self),
5006 GET_MONTH(self),
5007 GET_DAY(self));
5008 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005009 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005010 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005011 temp1 = new_delta(days, seconds,
5012 DATE_GET_MICROSECOND(self),
5013 1);
5014 if (temp1 == NULL) {
5015 Py_DECREF(offset);
5016 return -1;
5017 }
5018 temp2 = delta_subtract(temp1, offset);
5019 Py_DECREF(temp1);
5020 if (temp2 == NULL) {
5021 Py_DECREF(offset);
5022 return -1;
5023 }
5024 self->hashcode = PyObject_Hash(temp2);
5025 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005026 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005027 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005028 }
5029 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005030}
Tim Peters2a799bf2002-12-16 20:18:38 +00005031
5032static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005033datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 PyObject *clone;
5036 PyObject *tuple;
5037 int y = GET_YEAR(self);
5038 int m = GET_MONTH(self);
5039 int d = GET_DAY(self);
5040 int hh = DATE_GET_HOUR(self);
5041 int mm = DATE_GET_MINUTE(self);
5042 int ss = DATE_GET_SECOND(self);
5043 int us = DATE_GET_MICROSECOND(self);
5044 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005045 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005046
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005047 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005048 datetime_kws,
5049 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005050 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005051 return NULL;
Serhiy Storchaka314d6fc2017-03-31 22:48:16 +03005052 if (fold != 0 && fold != 1) {
5053 PyErr_SetString(PyExc_ValueError,
5054 "fold must be either 0 or 1");
5055 return NULL;
5056 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005057 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5058 if (tuple == NULL)
5059 return NULL;
5060 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005061 if (clone != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005062 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005063 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005064 Py_DECREF(tuple);
5065 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005066}
5067
5068static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005069local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005070{
5071 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005072 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005073 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005074 PyObject *nameo = NULL;
5075 const char *zone = NULL;
5076
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005077 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005078 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005079#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005080 zone = local_time_tm.tm_zone;
5081 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005082#else /* HAVE_STRUCT_TM_TM_ZONE */
5083 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005084 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005085 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005086 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005087 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005088 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005089 local_time = new_datetime(local_time_tm.tm_year + 1900,
5090 local_time_tm.tm_mon + 1,
5091 local_time_tm.tm_mday,
5092 local_time_tm.tm_hour,
5093 local_time_tm.tm_min,
5094 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005095 if (local_time == NULL) {
5096 return NULL;
5097 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005098 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005099 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005100 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5101 utc_time_tm.tm_mon + 1,
5102 utc_time_tm.tm_mday,
5103 utc_time_tm.tm_hour,
5104 utc_time_tm.tm_min,
5105 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005106 if (utc_time == NULL) {
5107 Py_DECREF(local_time);
5108 return NULL;
5109 }
5110 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005111 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005112 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005113 }
5114#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005115 if (delta == NULL) {
5116 return NULL;
5117 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005118 if (zone != NULL) {
5119 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5120 if (nameo == NULL)
5121 goto error;
5122 }
5123 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005124 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005125 error:
5126 Py_DECREF(delta);
5127 return result;
5128}
5129
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005130static PyObject *
5131local_timezone(PyDateTime_DateTime *utc_time)
5132{
5133 time_t timestamp;
5134 PyObject *delta;
5135 PyObject *one_second;
5136 PyObject *seconds;
5137
5138 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5139 if (delta == NULL)
5140 return NULL;
5141 one_second = new_delta(0, 1, 0, 0);
5142 if (one_second == NULL) {
5143 Py_DECREF(delta);
5144 return NULL;
5145 }
5146 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5147 (PyDateTime_Delta *)one_second);
5148 Py_DECREF(one_second);
5149 Py_DECREF(delta);
5150 if (seconds == NULL)
5151 return NULL;
5152 timestamp = _PyLong_AsTime_t(seconds);
5153 Py_DECREF(seconds);
5154 if (timestamp == -1 && PyErr_Occurred())
5155 return NULL;
5156 return local_timezone_from_timestamp(timestamp);
5157}
5158
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005159static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005160local_to_seconds(int year, int month, int day,
5161 int hour, int minute, int second, int fold);
5162
5163static PyObject *
5164local_timezone_from_local(PyDateTime_DateTime *local_dt)
5165{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005166 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005167 time_t timestamp;
5168 seconds = local_to_seconds(GET_YEAR(local_dt),
5169 GET_MONTH(local_dt),
5170 GET_DAY(local_dt),
5171 DATE_GET_HOUR(local_dt),
5172 DATE_GET_MINUTE(local_dt),
5173 DATE_GET_SECOND(local_dt),
5174 DATE_GET_FOLD(local_dt));
5175 if (seconds == -1)
5176 return NULL;
5177 /* XXX: add bounds check */
5178 timestamp = seconds - epoch;
5179 return local_timezone_from_timestamp(timestamp);
5180}
5181
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005182static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005183datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005184{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005185 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005186 PyObject *offset;
5187 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005188 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005189 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005190 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005191
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005192 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005193 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005194 return NULL;
5195
5196 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005197 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005198
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005199 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5200 self_tzinfo = local_timezone_from_local(self);
5201 if (self_tzinfo == NULL)
5202 return NULL;
5203 } else {
5204 self_tzinfo = self->tzinfo;
5205 Py_INCREF(self_tzinfo);
5206 }
Tim Peters521fc152002-12-31 17:36:56 +00005207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005208 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005209 if (self_tzinfo == tzinfo) {
5210 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005211 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005212 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005213 }
Tim Peters521fc152002-12-31 17:36:56 +00005214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005215 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005216 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5217 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005218 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005219 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005220 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005221 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5222 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005223 Py_DECREF(offset);
5224 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005225 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005226
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005227 /* Make sure result is aware and UTC. */
5228 if (!HASTZINFO(result)) {
5229 temp = (PyObject *)result;
5230 result = (PyDateTime_DateTime *)
5231 new_datetime_ex2(GET_YEAR(result),
5232 GET_MONTH(result),
5233 GET_DAY(result),
5234 DATE_GET_HOUR(result),
5235 DATE_GET_MINUTE(result),
5236 DATE_GET_SECOND(result),
5237 DATE_GET_MICROSECOND(result),
5238 PyDateTime_TimeZone_UTC,
5239 DATE_GET_FOLD(result),
5240 Py_TYPE(result));
5241 Py_DECREF(temp);
5242 if (result == NULL)
5243 return NULL;
5244 }
5245 else {
5246 /* Result is already aware - just replace tzinfo. */
5247 temp = result->tzinfo;
5248 result->tzinfo = PyDateTime_TimeZone_UTC;
5249 Py_INCREF(result->tzinfo);
5250 Py_DECREF(temp);
5251 }
5252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005253 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005254 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005255 if (tzinfo == Py_None) {
5256 tzinfo = local_timezone(result);
5257 if (tzinfo == NULL) {
5258 Py_DECREF(result);
5259 return NULL;
5260 }
5261 }
5262 else
5263 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005264 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005265 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005266
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005267 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005268 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005269 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005270 Py_DECREF(temp);
5271
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005272 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005273}
5274
5275static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005276datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005277{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005278 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005280 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005281 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005282
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005283 dst = call_dst(self->tzinfo, (PyObject *)self);
5284 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005285 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005286
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005287 if (dst != Py_None)
5288 dstflag = delta_bool((PyDateTime_Delta *)dst);
5289 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005290 }
5291 return build_struct_time(GET_YEAR(self),
5292 GET_MONTH(self),
5293 GET_DAY(self),
5294 DATE_GET_HOUR(self),
5295 DATE_GET_MINUTE(self),
5296 DATE_GET_SECOND(self),
5297 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005298}
5299
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005300static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005301local_to_seconds(int year, int month, int day,
5302 int hour, int minute, int second, int fold)
5303{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005304 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005305 t = utc_to_seconds(year, month, day, hour, minute, second);
5306 /* Our goal is to solve t = local(u) for u. */
5307 lt = local(t);
5308 if (lt == -1)
5309 return -1;
5310 a = lt - t;
5311 u1 = t - a;
5312 t1 = local(u1);
5313 if (t1 == -1)
5314 return -1;
5315 if (t1 == t) {
5316 /* We found one solution, but it may not be the one we need.
5317 * Look for an earlier solution (if `fold` is 0), or a
5318 * later one (if `fold` is 1). */
5319 if (fold)
5320 u2 = u1 + max_fold_seconds;
5321 else
5322 u2 = u1 - max_fold_seconds;
5323 lt = local(u2);
5324 if (lt == -1)
5325 return -1;
5326 b = lt - u2;
5327 if (a == b)
5328 return u1;
5329 }
5330 else {
5331 b = t1 - u1;
5332 assert(a != b);
5333 }
5334 u2 = t - b;
5335 t2 = local(u2);
5336 if (t2 == -1)
5337 return -1;
5338 if (t2 == t)
5339 return u2;
5340 if (t1 == t)
5341 return u1;
5342 /* We have found both offsets a and b, but neither t - a nor t - b is
5343 * a solution. This means t is in the gap. */
5344 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5345}
5346
5347/* date(1970,1,1).toordinal() == 719163 */
5348#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5349
Tim Peters2a799bf2002-12-16 20:18:38 +00005350static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005351datetime_timestamp(PyDateTime_DateTime *self)
5352{
5353 PyObject *result;
5354
5355 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5356 PyObject *delta;
5357 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5358 if (delta == NULL)
5359 return NULL;
5360 result = delta_total_seconds(delta);
5361 Py_DECREF(delta);
5362 }
5363 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005364 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005365 seconds = local_to_seconds(GET_YEAR(self),
5366 GET_MONTH(self),
5367 GET_DAY(self),
5368 DATE_GET_HOUR(self),
5369 DATE_GET_MINUTE(self),
5370 DATE_GET_SECOND(self),
5371 DATE_GET_FOLD(self));
5372 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005373 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005374 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5375 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005376 }
5377 return result;
5378}
5379
5380static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005381datetime_getdate(PyDateTime_DateTime *self)
5382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005383 return new_date(GET_YEAR(self),
5384 GET_MONTH(self),
5385 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005386}
5387
5388static PyObject *
5389datetime_gettime(PyDateTime_DateTime *self)
5390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005391 return new_time(DATE_GET_HOUR(self),
5392 DATE_GET_MINUTE(self),
5393 DATE_GET_SECOND(self),
5394 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005395 Py_None,
5396 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005397}
5398
5399static PyObject *
5400datetime_gettimetz(PyDateTime_DateTime *self)
5401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005402 return new_time(DATE_GET_HOUR(self),
5403 DATE_GET_MINUTE(self),
5404 DATE_GET_SECOND(self),
5405 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005406 GET_DT_TZINFO(self),
5407 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005408}
5409
5410static PyObject *
5411datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005412{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005413 int y, m, d, hh, mm, ss;
5414 PyObject *tzinfo;
5415 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005416
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005417 tzinfo = GET_DT_TZINFO(self);
5418 if (tzinfo == Py_None) {
5419 utcself = self;
5420 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005421 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005422 else {
5423 PyObject *offset;
5424 offset = call_utcoffset(tzinfo, (PyObject *)self);
5425 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005426 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005427 if (offset == Py_None) {
5428 Py_DECREF(offset);
5429 utcself = self;
5430 Py_INCREF(utcself);
5431 }
5432 else {
5433 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5434 (PyDateTime_Delta *)offset, -1);
5435 Py_DECREF(offset);
5436 if (utcself == NULL)
5437 return NULL;
5438 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005439 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005440 y = GET_YEAR(utcself);
5441 m = GET_MONTH(utcself);
5442 d = GET_DAY(utcself);
5443 hh = DATE_GET_HOUR(utcself);
5444 mm = DATE_GET_MINUTE(utcself);
5445 ss = DATE_GET_SECOND(utcself);
5446
5447 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005448 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005449}
5450
Tim Peters371935f2003-02-01 01:52:50 +00005451/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005452
Tim Petersa9bc1682003-01-11 03:39:11 +00005453/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005454 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5455 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005456 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005457 */
5458static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005459datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005461 PyObject *basestate;
5462 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005464 basestate = PyBytes_FromStringAndSize((char *)self->data,
5465 _PyDateTime_DATETIME_DATASIZE);
5466 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005467 if (proto > 3 && DATE_GET_FOLD(self))
5468 /* Set the first bit of the third byte */
5469 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005470 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5471 result = PyTuple_Pack(1, basestate);
5472 else
5473 result = PyTuple_Pack(2, basestate, self->tzinfo);
5474 Py_DECREF(basestate);
5475 }
5476 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005477}
5478
5479static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005480datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005481{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005482 int proto;
5483 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005484 return NULL;
5485
5486 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005487}
5488
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005489static PyObject *
5490datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5491{
5492 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5493}
5494
Tim Petersa9bc1682003-01-11 03:39:11 +00005495static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005497 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005498
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005499 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005501 {"utcnow", (PyCFunction)datetime_utcnow,
5502 METH_NOARGS | METH_CLASS,
5503 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005505 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5506 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5507 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005509 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5510 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005511 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005513 {"strptime", (PyCFunction)datetime_strptime,
5514 METH_VARARGS | METH_CLASS,
5515 PyDoc_STR("string, format -> new datetime parsed from a string "
5516 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005518 {"combine", (PyCFunction)datetime_combine,
5519 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5520 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005522 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005524 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5525 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005527 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5528 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005530 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5531 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005533 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5534 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005536 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5537 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005538
Alexander Belopolskya4415142012-06-08 12:33:09 -04005539 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5540 PyDoc_STR("Return POSIX timestamp as float.")},
5541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005542 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5543 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005545 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5546 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005547 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005548 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005549 "defaults to 'T'.\n"
5550 "timespec specifies what components of the time to include"
5551 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5552 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005554 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5555 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005557 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5558 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005560 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5561 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005563 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5564 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005566 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5567 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005568
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005569 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005570 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005571
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005572 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5573 PyDoc_STR("__reduce__() -> (cls, state)")},
5574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005575 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005576};
5577
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005578static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005579PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5580\n\
5581The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005582instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005583
Tim Petersa9bc1682003-01-11 03:39:11 +00005584static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005585 datetime_add, /* nb_add */
5586 datetime_subtract, /* nb_subtract */
5587 0, /* nb_multiply */
5588 0, /* nb_remainder */
5589 0, /* nb_divmod */
5590 0, /* nb_power */
5591 0, /* nb_negative */
5592 0, /* nb_positive */
5593 0, /* nb_absolute */
5594 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005595};
5596
Neal Norwitz227b5332006-03-22 09:28:35 +00005597static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005598 PyVarObject_HEAD_INIT(NULL, 0)
5599 "datetime.datetime", /* tp_name */
5600 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5601 0, /* tp_itemsize */
5602 (destructor)datetime_dealloc, /* tp_dealloc */
5603 0, /* tp_print */
5604 0, /* tp_getattr */
5605 0, /* tp_setattr */
5606 0, /* tp_reserved */
5607 (reprfunc)datetime_repr, /* tp_repr */
5608 &datetime_as_number, /* tp_as_number */
5609 0, /* tp_as_sequence */
5610 0, /* tp_as_mapping */
5611 (hashfunc)datetime_hash, /* tp_hash */
5612 0, /* tp_call */
5613 (reprfunc)datetime_str, /* tp_str */
5614 PyObject_GenericGetAttr, /* tp_getattro */
5615 0, /* tp_setattro */
5616 0, /* tp_as_buffer */
5617 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5618 datetime_doc, /* tp_doc */
5619 0, /* tp_traverse */
5620 0, /* tp_clear */
5621 datetime_richcompare, /* tp_richcompare */
5622 0, /* tp_weaklistoffset */
5623 0, /* tp_iter */
5624 0, /* tp_iternext */
5625 datetime_methods, /* tp_methods */
5626 0, /* tp_members */
5627 datetime_getset, /* tp_getset */
5628 &PyDateTime_DateType, /* tp_base */
5629 0, /* tp_dict */
5630 0, /* tp_descr_get */
5631 0, /* tp_descr_set */
5632 0, /* tp_dictoffset */
5633 0, /* tp_init */
5634 datetime_alloc, /* tp_alloc */
5635 datetime_new, /* tp_new */
5636 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005637};
5638
5639/* ---------------------------------------------------------------------------
5640 * Module methods and initialization.
5641 */
5642
5643static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005644 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005645};
5646
Tim Peters9ddf40b2004-06-20 22:41:32 +00005647/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5648 * datetime.h.
5649 */
5650static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005651 &PyDateTime_DateType,
5652 &PyDateTime_DateTimeType,
5653 &PyDateTime_TimeType,
5654 &PyDateTime_DeltaType,
5655 &PyDateTime_TZInfoType,
5656 new_date_ex,
5657 new_datetime_ex,
5658 new_time_ex,
5659 new_delta_ex,
5660 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005661 date_fromtimestamp,
5662 new_datetime_ex2,
5663 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00005664};
5665
5666
Martin v. Löwis1a214512008-06-11 05:26:20 +00005667
5668static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005669 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005670 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005671 "Fast implementation of the datetime type.",
5672 -1,
5673 module_methods,
5674 NULL,
5675 NULL,
5676 NULL,
5677 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005678};
5679
Tim Peters2a799bf2002-12-16 20:18:38 +00005680PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005681PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005682{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005683 PyObject *m; /* a module object */
5684 PyObject *d; /* its dict */
5685 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005686 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005688 m = PyModule_Create(&datetimemodule);
5689 if (m == NULL)
5690 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005692 if (PyType_Ready(&PyDateTime_DateType) < 0)
5693 return NULL;
5694 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5695 return NULL;
5696 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5697 return NULL;
5698 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5699 return NULL;
5700 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5701 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005702 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5703 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005705 /* timedelta values */
5706 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005708 x = new_delta(0, 0, 1, 0);
5709 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5710 return NULL;
5711 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005713 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5714 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5715 return NULL;
5716 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005718 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5719 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5720 return NULL;
5721 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005723 /* date values */
5724 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005726 x = new_date(1, 1, 1);
5727 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5728 return NULL;
5729 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005731 x = new_date(MAXYEAR, 12, 31);
5732 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5733 return NULL;
5734 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005736 x = new_delta(1, 0, 0, 0);
5737 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5738 return NULL;
5739 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005741 /* time values */
5742 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005743
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005744 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005745 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5746 return NULL;
5747 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005748
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005749 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005750 if (x == NULL || PyDict_SetItemString(d, "max", 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(0, 0, 1, 0);
5755 if (x == NULL || PyDict_SetItemString(d, "resolution", 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 /* datetime values */
5760 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005761
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005762 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005763 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5764 return NULL;
5765 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005766
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005767 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005768 if (x == NULL || PyDict_SetItemString(d, "max", 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_delta(0, 0, 1, 0);
5773 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5774 return NULL;
5775 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005776
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005777 /* timezone values */
5778 d = PyDateTime_TimeZoneType.tp_dict;
5779
5780 delta = new_delta(0, 0, 0, 0);
5781 if (delta == NULL)
5782 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005783 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005784 Py_DECREF(delta);
5785 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5786 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005787 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005788
5789 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5790 if (delta == NULL)
5791 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005792 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005793 Py_DECREF(delta);
5794 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5795 return NULL;
5796 Py_DECREF(x);
5797
5798 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5799 if (delta == NULL)
5800 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005801 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005802 Py_DECREF(delta);
5803 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5804 return NULL;
5805 Py_DECREF(x);
5806
Alexander Belopolskya4415142012-06-08 12:33:09 -04005807 /* Epoch */
5808 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005809 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005810 if (PyDateTime_Epoch == NULL)
5811 return NULL;
5812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005813 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005814 PyModule_AddIntMacro(m, MINYEAR);
5815 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005817 Py_INCREF(&PyDateTime_DateType);
5818 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005820 Py_INCREF(&PyDateTime_DateTimeType);
5821 PyModule_AddObject(m, "datetime",
5822 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005824 Py_INCREF(&PyDateTime_TimeType);
5825 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005827 Py_INCREF(&PyDateTime_DeltaType);
5828 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005830 Py_INCREF(&PyDateTime_TZInfoType);
5831 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005832
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005833 Py_INCREF(&PyDateTime_TimeZoneType);
5834 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005836 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5837 if (x == NULL)
5838 return NULL;
5839 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005841 /* A 4-year cycle has an extra leap day over what we'd get from
5842 * pasting together 4 single years.
5843 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005844 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005845 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005847 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5848 * get from pasting together 4 100-year cycles.
5849 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005850 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005851 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005853 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5854 * pasting together 25 4-year cycles.
5855 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005856 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005857 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005859 us_per_ms = PyLong_FromLong(1000);
5860 us_per_second = PyLong_FromLong(1000000);
5861 us_per_minute = PyLong_FromLong(60000000);
5862 seconds_per_day = PyLong_FromLong(24 * 3600);
Serhiy Storchakaba85d692017-03-30 09:09:41 +03005863 if (us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005864 us_per_minute == NULL || seconds_per_day == NULL)
5865 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005867 /* The rest are too big for 32-bit ints, but even
5868 * us_per_week fits in 40 bits, so doubles should be exact.
5869 */
5870 us_per_hour = PyLong_FromDouble(3600000000.0);
5871 us_per_day = PyLong_FromDouble(86400000000.0);
5872 us_per_week = PyLong_FromDouble(604800000000.0);
5873 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5874 return NULL;
5875 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005876}
Tim Petersf3615152003-01-01 21:51:37 +00005877
5878/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005879Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005880 x.n = x stripped of its timezone -- its naive time.
5881 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005882 return None
Tim Petersf3615152003-01-01 21:51:37 +00005883 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005884 return None
Tim Petersf3615152003-01-01 21:51:37 +00005885 x.s = x's standard offset, x.o - x.d
5886
5887Now some derived rules, where k is a duration (timedelta).
5888
58891. x.o = x.s + x.d
5890 This follows from the definition of x.s.
5891
Tim Petersc5dc4da2003-01-02 17:55:03 +000058922. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005893 This is actually a requirement, an assumption we need to make about
5894 sane tzinfo classes.
5895
58963. The naive UTC time corresponding to x is x.n - x.o.
5897 This is again a requirement for a sane tzinfo class.
5898
58994. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005900 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005901
Tim Petersc5dc4da2003-01-02 17:55:03 +000059025. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005903 Again follows from how arithmetic is defined.
5904
Tim Peters8bb5ad22003-01-24 02:44:45 +00005905Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005906(meaning that the various tzinfo methods exist, and don't blow up or return
5907None when called).
5908
Tim Petersa9bc1682003-01-11 03:39:11 +00005909The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005910x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005911
5912By #3, we want
5913
Tim Peters8bb5ad22003-01-24 02:44:45 +00005914 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005915
5916The algorithm starts by attaching tz to x.n, and calling that y. So
5917x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5918becomes true; in effect, we want to solve [2] for k:
5919
Tim Peters8bb5ad22003-01-24 02:44:45 +00005920 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005921
5922By #1, this is the same as
5923
Tim Peters8bb5ad22003-01-24 02:44:45 +00005924 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005925
5926By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5927Substituting that into [3],
5928
Tim Peters8bb5ad22003-01-24 02:44:45 +00005929 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5930 k - (y+k).s - (y+k).d = 0; rearranging,
5931 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5932 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005933
Tim Peters8bb5ad22003-01-24 02:44:45 +00005934On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5935approximate k by ignoring the (y+k).d term at first. Note that k can't be
5936very large, since all offset-returning methods return a duration of magnitude
5937less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5938be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005939
5940In any case, the new value is
5941
Tim Peters8bb5ad22003-01-24 02:44:45 +00005942 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005943
Tim Peters8bb5ad22003-01-24 02:44:45 +00005944It's helpful to step back at look at [4] from a higher level: it's simply
5945mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005946
5947At this point, if
5948
Tim Peters8bb5ad22003-01-24 02:44:45 +00005949 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005950
5951we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005952at the start of daylight time. Picture US Eastern for concreteness. The wall
5953time 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 +00005954sense then. The docs ask that an Eastern tzinfo class consider such a time to
5955be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5956on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005957the only spelling that makes sense on the local wall clock.
5958
Tim Petersc5dc4da2003-01-02 17:55:03 +00005959In fact, if [5] holds at this point, we do have the standard-time spelling,
5960but that takes a bit of proof. We first prove a stronger result. What's the
5961difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005962
Tim Peters8bb5ad22003-01-24 02:44:45 +00005963 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005964
Tim Petersc5dc4da2003-01-02 17:55:03 +00005965Now
5966 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005967 (y + y.s).n = by #5
5968 y.n + y.s = since y.n = x.n
5969 x.n + y.s = since z and y are have the same tzinfo member,
5970 y.s = z.s by #2
5971 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005972
Tim Petersc5dc4da2003-01-02 17:55:03 +00005973Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005974
Tim Petersc5dc4da2003-01-02 17:55:03 +00005975 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005976 x.n - ((x.n + z.s) - z.o) = expanding
5977 x.n - x.n - z.s + z.o = cancelling
5978 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005979 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005980
Tim Petersc5dc4da2003-01-02 17:55:03 +00005981So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005982
Tim Petersc5dc4da2003-01-02 17:55:03 +00005983If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005984spelling we wanted in the endcase described above. We're done. Contrarily,
5985if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005986
Tim Petersc5dc4da2003-01-02 17:55:03 +00005987If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5988add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005989local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005990
Tim Petersc5dc4da2003-01-02 17:55:03 +00005991Let
Tim Petersf3615152003-01-01 21:51:37 +00005992
Tim Peters4fede1a2003-01-04 00:26:59 +00005993 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005994
Tim Peters4fede1a2003-01-04 00:26:59 +00005995and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005996
Tim Peters8bb5ad22003-01-24 02:44:45 +00005997 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005998
Tim Peters8bb5ad22003-01-24 02:44:45 +00005999If so, we're done. If not, the tzinfo class is insane, according to the
6000assumptions we've made. This also requires a bit of proof. As before, let's
6001compute the difference between the LHS and RHS of [8] (and skipping some of
6002the justifications for the kinds of substitutions we've done several times
6003already):
Tim Peters4fede1a2003-01-04 00:26:59 +00006004
Tim Peters8bb5ad22003-01-24 02:44:45 +00006005 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006006 x.n - (z.n + diff - z'.o) = replacing diff via [6]
6007 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
6008 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
6009 - z.n + z.n - z.o + z'.o = cancel z.n
6010 - z.o + z'.o = #1 twice
6011 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
6012 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00006013
6014So 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 +00006015we've found the UTC-equivalent so are done. In fact, we stop with [7] and
6016return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00006017
Tim Peters8bb5ad22003-01-24 02:44:45 +00006018How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6019a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6020would have to change the result dst() returns: we start in DST, and moving
6021a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00006022
Tim Peters8bb5ad22003-01-24 02:44:45 +00006023There isn't a sane case where this can happen. The closest it gets is at
6024the end of DST, where there's an hour in UTC with no spelling in a hybrid
6025tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6026that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6027UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6028time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6029clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6030standard time. Since that's what the local clock *does*, we want to map both
6031UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006032in local time, but so it goes -- it's the way the local clock works.
6033
Tim Peters8bb5ad22003-01-24 02:44:45 +00006034When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6035so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6036z' = 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 +00006037(correctly) concludes that z' is not UTC-equivalent to x.
6038
6039Because we know z.d said z was in daylight time (else [5] would have held and
6040we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006041and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006042return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6043but the reasoning doesn't depend on the example -- it depends on there being
6044two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006045z' must be in standard time, and is the spelling we want in this case.
6046
6047Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6048concerned (because it takes z' as being in standard time rather than the
6049daylight time we intend here), but returning it gives the real-life "local
6050clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6051tz.
6052
6053When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6054the 1:MM standard time spelling we want.
6055
6056So how can this break? One of the assumptions must be violated. Two
6057possibilities:
6058
60591) [2] effectively says that y.s is invariant across all y belong to a given
6060 time zone. This isn't true if, for political reasons or continental drift,
6061 a region decides to change its base offset from UTC.
6062
60632) There may be versions of "double daylight" time where the tail end of
6064 the analysis gives up a step too early. I haven't thought about that
6065 enough to say.
6066
6067In any case, it's clear that the default fromutc() is strong enough to handle
6068"almost all" time zones: so long as the standard offset is invariant, it
6069doesn't matter if daylight time transition points change from year to year, or
6070if daylight time is skipped in some years; it doesn't matter how large or
6071small dst() may get within its bounds; and it doesn't even matter if some
6072perverse time zone returns a negative dst()). So a breaking case must be
6073pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006074--------------------------------------------------------------------------- */