blob: c784d0f4a9099999f888ec1aee65041b5bc2d35b [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_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
863 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400864 " representing a whole number of minutes,"
865 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000866 return NULL;
867 }
868 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
869 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
870 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
871 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400872 " timedelta(hours=24),"
873 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000874 return NULL;
875 }
876
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000877 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000878}
879
Tim Petersb0c854d2003-05-17 15:57:00 +0000880/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000881 * tzinfo helpers.
882 */
883
Tim Peters855fe882002-12-22 03:43:39 +0000884/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
885 * raise TypeError and return -1.
886 */
887static int
888check_tzinfo_subclass(PyObject *p)
889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 if (p == Py_None || PyTZInfo_Check(p))
891 return 0;
892 PyErr_Format(PyExc_TypeError,
893 "tzinfo argument must be None or of a tzinfo subclass, "
894 "not type '%s'",
895 Py_TYPE(p)->tp_name);
896 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000897}
898
Tim Peters2a799bf2002-12-16 20:18:38 +0000899/* If self has a tzinfo member, return a BORROWED reference to it. Else
900 * return NULL, which is NOT AN ERROR. There are no error returns here,
901 * and the caller must not decref the result.
902 */
903static PyObject *
904get_tzinfo_member(PyObject *self)
905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 if (PyDateTime_Check(self) && HASTZINFO(self))
909 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
910 else if (PyTime_Check(self) && HASTZINFO(self))
911 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000914}
915
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000916/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
917 * be an instance of the tzinfo class. If the method returns None, this
918 * returns None. If the method doesn't return None or timedelta, TypeError is
919 * raised and this returns NULL. If it returns a timedelta and the value is
920 * out of range or isn't a whole number of minutes, ValueError is raised and
921 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000922 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000923static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200924call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000925{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000926 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000929 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000931
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000932 if (tzinfo == Py_None)
933 Py_RETURN_NONE;
934 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
935 if (offset == Py_None || offset == NULL)
936 return offset;
937 if (PyDelta_Check(offset)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400938 if (GET_TD_MICROSECONDS(offset) != 0) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000939 Py_DECREF(offset);
940 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400941 " representing a whole number of seconds");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000942 return NULL;
943 }
944 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
945 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
946 Py_DECREF(offset);
947 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
948 " strictly between -timedelta(hours=24) and"
949 " timedelta(hours=24).");
950 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 }
952 }
953 else {
954 PyErr_Format(PyExc_TypeError,
955 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000956 "timedelta, not '%.200s'",
957 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -0700958 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000959 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000961
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000962 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000963}
964
965/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
966 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
967 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000968 * doesn't return None or timedelta, TypeError is raised and this returns -1.
969 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
970 * # of minutes), ValueError is raised and this returns -1. Else *none is
971 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000972 */
Tim Peters855fe882002-12-22 03:43:39 +0000973static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000974call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
975{
976 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000977}
978
Tim Peters2a799bf2002-12-16 20:18:38 +0000979/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
980 * result. tzinfo must be an instance of the tzinfo class. If dst()
981 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000982 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000983 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000984 * ValueError is raised and this returns -1. Else *none is set to 0 and
985 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000986 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000987static PyObject *
988call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000989{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000990 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000991}
992
Tim Petersbad8ff02002-12-30 20:52:32 +0000993/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000994 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000995 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000996 * returns NULL. If the result is a string, we ensure it is a Unicode
997 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000998 */
999static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001000call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001003 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +00001004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 assert(tzinfo != NULL);
1006 assert(check_tzinfo_subclass(tzinfo) >= 0);
1007 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001010 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001011
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001012 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001013
1014 if (result == NULL || result == Py_None)
1015 return result;
1016
1017 if (!PyUnicode_Check(result)) {
1018 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1019 "return None or a string, not '%s'",
1020 Py_TYPE(result)->tp_name);
1021 Py_DECREF(result);
1022 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001024
1025 return result;
Tim Peters00237032002-12-27 02:21:51 +00001026}
1027
Tim Peters2a799bf2002-12-16 20:18:38 +00001028/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1029 * stuff
1030 * ", tzinfo=" + repr(tzinfo)
1031 * before the closing ")".
1032 */
1033static PyObject *
1034append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 assert(PyUnicode_Check(repr));
1039 assert(tzinfo);
1040 if (tzinfo == Py_None)
1041 return repr;
1042 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001043 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1044 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 Py_DECREF(repr);
1046 if (temp == NULL)
1047 return NULL;
1048 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1049 Py_DECREF(temp);
1050 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001051}
1052
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001053/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1054 * stuff
1055 * ", fold=" + repr(tzinfo)
1056 * before the closing ")".
1057 */
1058static PyObject *
1059append_keyword_fold(PyObject *repr, int fold)
1060{
1061 PyObject *temp;
1062
1063 assert(PyUnicode_Check(repr));
1064 if (fold == 0)
1065 return repr;
1066 /* Get rid of the trailing ')'. */
1067 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1068 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1069 Py_DECREF(repr);
1070 if (temp == NULL)
1071 return NULL;
1072 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1073 Py_DECREF(temp);
1074 return repr;
1075}
1076
Tim Peters2a799bf2002-12-16 20:18:38 +00001077/* ---------------------------------------------------------------------------
1078 * String format helpers.
1079 */
1080
1081static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001082format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001083{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001084 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1086 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001087 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1089 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1090 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1095 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1096 GET_DAY(date), hours, minutes, seconds,
1097 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001098}
1099
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001100static PyObject *delta_negative(PyDateTime_Delta *self);
1101
Tim Peters2a799bf2002-12-16 20:18:38 +00001102/* Add an hours & minutes UTC offset string to buf. buf has no more than
1103 * buflen bytes remaining. The UTC offset is gotten by calling
1104 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1105 * *buf, and that's all. Else the returned value is checked for sanity (an
1106 * integer in range), and if that's OK it's converted to an hours & minutes
1107 * string of the form
1108 * sign HH sep MM
1109 * Returns 0 if everything is OK. If the return value from utcoffset() is
1110 * bogus, an appropriate exception is set and -1 is returned.
1111 */
1112static int
Tim Peters328fff72002-12-20 01:31:27 +00001113format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001115{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001116 PyObject *offset;
1117 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001121
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001122 offset = call_utcoffset(tzinfo, tzinfoarg);
1123 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001125 if (offset == Py_None) {
1126 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 *buf = '\0';
1128 return 0;
1129 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001130 /* Offset is normalized, so it is negative if days < 0 */
1131 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001133 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001134 if (offset == NULL)
1135 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001137 else {
1138 sign = '+';
1139 }
1140 /* Offset is not negative here. */
1141 seconds = GET_TD_SECONDS(offset);
1142 Py_DECREF(offset);
1143 minutes = divmod(seconds, 60, &seconds);
1144 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001145 if (seconds == 0)
1146 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1147 else
1148 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1149 sep, minutes, sep, seconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001151}
1152
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001153static PyObject *
1154make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1155{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 PyObject *temp;
1157 PyObject *tzinfo = get_tzinfo_member(object);
1158 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001159 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 if (Zreplacement == NULL)
1162 return NULL;
1163 if (tzinfo == Py_None || tzinfo == NULL)
1164 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 assert(tzinfoarg != NULL);
1167 temp = call_tzname(tzinfo, tzinfoarg);
1168 if (temp == NULL)
1169 goto Error;
1170 if (temp == Py_None) {
1171 Py_DECREF(temp);
1172 return Zreplacement;
1173 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 assert(PyUnicode_Check(temp));
1176 /* Since the tzname is getting stuffed into the
1177 * format, we have to double any % signs so that
1178 * strftime doesn't treat them as format codes.
1179 */
1180 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001181 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 Py_DECREF(temp);
1183 if (Zreplacement == NULL)
1184 return NULL;
1185 if (!PyUnicode_Check(Zreplacement)) {
1186 PyErr_SetString(PyExc_TypeError,
1187 "tzname.replace() did not return a string");
1188 goto Error;
1189 }
1190 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001191
1192 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 Py_DECREF(Zreplacement);
1194 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001195}
1196
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001197static PyObject *
1198make_freplacement(PyObject *object)
1199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 char freplacement[64];
1201 if (PyTime_Check(object))
1202 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1203 else if (PyDateTime_Check(object))
1204 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1205 else
1206 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001209}
1210
Tim Peters2a799bf2002-12-16 20:18:38 +00001211/* I sure don't want to reproduce the strftime code from the time module,
1212 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001213 * giving special meanings to the %z, %Z and %f format codes via a
1214 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001215 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1216 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001217 */
1218static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001219wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1225 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1226 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 const char *pin; /* pointer to next char in input format */
1229 Py_ssize_t flen; /* length of input format */
1230 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 PyObject *newfmt = NULL; /* py string, the output format */
1233 char *pnew; /* pointer to available byte in output format */
1234 size_t totalnew; /* number bytes total in output format buffer,
1235 exclusive of trailing \0 */
1236 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 const char *ptoappend; /* ptr to string to append to output buffer */
1239 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 assert(object && format && timetuple);
1242 assert(PyUnicode_Check(format));
1243 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001244 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 if (!pin)
1246 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 /* Scan the input format, looking for %z/%Z/%f escapes, building
1249 * a new format. Since computing the replacements for those codes
1250 * is expensive, don't unless they're actually used.
1251 */
1252 if (flen > INT_MAX - 1) {
1253 PyErr_NoMemory();
1254 goto Done;
1255 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 totalnew = flen + 1; /* realistic if no %z/%Z */
1258 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1259 if (newfmt == NULL) goto Done;
1260 pnew = PyBytes_AsString(newfmt);
1261 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 while ((ch = *pin++) != '\0') {
1264 if (ch != '%') {
1265 ptoappend = pin - 1;
1266 ntoappend = 1;
1267 }
1268 else if ((ch = *pin++) == '\0') {
1269 /* There's a lone trailing %; doesn't make sense. */
1270 PyErr_SetString(PyExc_ValueError, "strftime format "
1271 "ends with raw %");
1272 goto Done;
1273 }
1274 /* A % has been seen and ch is the character after it. */
1275 else if (ch == 'z') {
1276 if (zreplacement == NULL) {
1277 /* format utcoffset */
1278 char buf[100];
1279 PyObject *tzinfo = get_tzinfo_member(object);
1280 zreplacement = PyBytes_FromStringAndSize("", 0);
1281 if (zreplacement == NULL) goto Done;
1282 if (tzinfo != Py_None && tzinfo != NULL) {
1283 assert(tzinfoarg != NULL);
1284 if (format_utcoffset(buf,
1285 sizeof(buf),
1286 "",
1287 tzinfo,
1288 tzinfoarg) < 0)
1289 goto Done;
1290 Py_DECREF(zreplacement);
1291 zreplacement =
1292 PyBytes_FromStringAndSize(buf,
1293 strlen(buf));
1294 if (zreplacement == NULL)
1295 goto Done;
1296 }
1297 }
1298 assert(zreplacement != NULL);
1299 ptoappend = PyBytes_AS_STRING(zreplacement);
1300 ntoappend = PyBytes_GET_SIZE(zreplacement);
1301 }
1302 else if (ch == 'Z') {
1303 /* format tzname */
1304 if (Zreplacement == NULL) {
1305 Zreplacement = make_Zreplacement(object,
1306 tzinfoarg);
1307 if (Zreplacement == NULL)
1308 goto Done;
1309 }
1310 assert(Zreplacement != NULL);
1311 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001312 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001314 if (ptoappend == NULL)
1315 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 }
1317 else if (ch == 'f') {
1318 /* format microseconds */
1319 if (freplacement == NULL) {
1320 freplacement = make_freplacement(object);
1321 if (freplacement == NULL)
1322 goto Done;
1323 }
1324 assert(freplacement != NULL);
1325 assert(PyBytes_Check(freplacement));
1326 ptoappend = PyBytes_AS_STRING(freplacement);
1327 ntoappend = PyBytes_GET_SIZE(freplacement);
1328 }
1329 else {
1330 /* percent followed by neither z nor Z */
1331 ptoappend = pin - 2;
1332 ntoappend = 2;
1333 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 /* Append the ntoappend chars starting at ptoappend to
1336 * the new format.
1337 */
1338 if (ntoappend == 0)
1339 continue;
1340 assert(ptoappend != NULL);
1341 assert(ntoappend > 0);
1342 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001343 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 PyErr_NoMemory();
1345 goto Done;
1346 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001347 totalnew <<= 1;
1348 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 pnew = PyBytes_AsString(newfmt) + usednew;
1351 }
1352 memcpy(pnew, ptoappend, ntoappend);
1353 pnew += ntoappend;
1354 usednew += ntoappend;
1355 assert(usednew <= totalnew);
1356 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1359 goto Done;
1360 {
1361 PyObject *format;
1362 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 if (time == NULL)
1365 goto Done;
1366 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1367 if (format != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001368 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1369 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 Py_DECREF(format);
1371 }
1372 Py_DECREF(time);
1373 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001374 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 Py_XDECREF(freplacement);
1376 Py_XDECREF(zreplacement);
1377 Py_XDECREF(Zreplacement);
1378 Py_XDECREF(newfmt);
1379 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001380}
1381
Tim Peters2a799bf2002-12-16 20:18:38 +00001382/* ---------------------------------------------------------------------------
1383 * Wrap functions from the time module. These aren't directly available
1384 * from C. Perhaps they should be.
1385 */
1386
1387/* Call time.time() and return its result (a Python float). */
1388static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001389time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 PyObject *result = NULL;
1392 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001395 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001396
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001397 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 Py_DECREF(time);
1399 }
1400 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001401}
1402
1403/* Build a time.struct_time. The weekday and day number are automatically
1404 * computed from the y,m,d args.
1405 */
1406static PyObject *
1407build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 PyObject *time;
1410 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 time = PyImport_ImportModuleNoBlock("time");
1413 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001414 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001415
1416 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1417 "((iiiiiiiii))",
1418 y, m, d,
1419 hh, mm, ss,
1420 weekday(y, m, d),
1421 days_before_month(y, m) + d,
1422 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 Py_DECREF(time);
1424 }
1425 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001426}
1427
1428/* ---------------------------------------------------------------------------
1429 * Miscellaneous helpers.
1430 */
1431
Mark Dickinsone94c6792009-02-02 20:36:42 +00001432/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001433 * The comparisons here all most naturally compute a cmp()-like result.
1434 * This little helper turns that into a bool result for rich comparisons.
1435 */
1436static PyObject *
1437diff_to_bool(int diff, int op)
1438{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 PyObject *result;
1440 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 switch (op) {
1443 case Py_EQ: istrue = diff == 0; break;
1444 case Py_NE: istrue = diff != 0; break;
1445 case Py_LE: istrue = diff <= 0; break;
1446 case Py_GE: istrue = diff >= 0; break;
1447 case Py_LT: istrue = diff < 0; break;
1448 case Py_GT: istrue = diff > 0; break;
1449 default:
1450 assert(! "op unknown");
1451 istrue = 0; /* To shut up compiler */
1452 }
1453 result = istrue ? Py_True : Py_False;
1454 Py_INCREF(result);
1455 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001456}
1457
Tim Peters07534a62003-02-07 22:50:28 +00001458/* Raises a "can't compare" TypeError and returns NULL. */
1459static PyObject *
1460cmperror(PyObject *a, PyObject *b)
1461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 PyErr_Format(PyExc_TypeError,
1463 "can't compare %s to %s",
1464 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1465 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001466}
1467
Tim Peters2a799bf2002-12-16 20:18:38 +00001468/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001469 * Cached Python objects; these are set by the module init function.
1470 */
1471
1472/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001473static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474static PyObject *us_per_ms = NULL; /* 1000 */
1475static PyObject *us_per_second = NULL; /* 1000000 */
1476static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001477static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1478static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1479static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001480static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1481
Tim Peters2a799bf2002-12-16 20:18:38 +00001482/* ---------------------------------------------------------------------------
1483 * Class implementations.
1484 */
1485
1486/*
1487 * PyDateTime_Delta implementation.
1488 */
1489
1490/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001492 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001493 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1494 * due to ubiquitous overflow possibilities.
1495 */
1496static PyObject *
1497delta_to_microseconds(PyDateTime_Delta *self)
1498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 PyObject *x1 = NULL;
1500 PyObject *x2 = NULL;
1501 PyObject *x3 = NULL;
1502 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1505 if (x1 == NULL)
1506 goto Done;
1507 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1508 if (x2 == NULL)
1509 goto Done;
1510 Py_DECREF(x1);
1511 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 /* x2 has days in seconds */
1514 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1515 if (x1 == NULL)
1516 goto Done;
1517 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1518 if (x3 == NULL)
1519 goto Done;
1520 Py_DECREF(x1);
1521 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001522 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 /* x3 has days+seconds in seconds */
1525 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1526 if (x1 == NULL)
1527 goto Done;
1528 Py_DECREF(x3);
1529 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 /* x1 has days+seconds in us */
1532 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1533 if (x2 == NULL)
1534 goto Done;
1535 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001536
1537Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 Py_XDECREF(x1);
1539 Py_XDECREF(x2);
1540 Py_XDECREF(x3);
1541 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001542}
1543
Serhiy Storchaka95949422013-08-27 19:40:23 +03001544/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001545 */
1546static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001547microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 int us;
1550 int s;
1551 int d;
1552 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 PyObject *tuple = NULL;
1555 PyObject *num = NULL;
1556 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 tuple = PyNumber_Divmod(pyus, us_per_second);
1559 if (tuple == NULL)
1560 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 num = PyTuple_GetItem(tuple, 1); /* us */
1563 if (num == NULL)
1564 goto Done;
1565 temp = PyLong_AsLong(num);
1566 num = NULL;
1567 if (temp == -1 && PyErr_Occurred())
1568 goto Done;
1569 assert(0 <= temp && temp < 1000000);
1570 us = (int)temp;
1571 if (us < 0) {
1572 /* The divisor was positive, so this must be an error. */
1573 assert(PyErr_Occurred());
1574 goto Done;
1575 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1578 if (num == NULL)
1579 goto Done;
1580 Py_INCREF(num);
1581 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 tuple = PyNumber_Divmod(num, seconds_per_day);
1584 if (tuple == NULL)
1585 goto Done;
1586 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 num = PyTuple_GetItem(tuple, 1); /* seconds */
1589 if (num == NULL)
1590 goto Done;
1591 temp = PyLong_AsLong(num);
1592 num = NULL;
1593 if (temp == -1 && PyErr_Occurred())
1594 goto Done;
1595 assert(0 <= temp && temp < 24*3600);
1596 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 if (s < 0) {
1599 /* The divisor was positive, so this must be an error. */
1600 assert(PyErr_Occurred());
1601 goto Done;
1602 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1605 if (num == NULL)
1606 goto Done;
1607 Py_INCREF(num);
1608 temp = PyLong_AsLong(num);
1609 if (temp == -1 && PyErr_Occurred())
1610 goto Done;
1611 d = (int)temp;
1612 if ((long)d != temp) {
1613 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1614 "large to fit in a C int");
1615 goto Done;
1616 }
1617 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001618
1619Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 Py_XDECREF(tuple);
1621 Py_XDECREF(num);
1622 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001623}
1624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625#define microseconds_to_delta(pymicros) \
1626 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001627
Tim Peters2a799bf2002-12-16 20:18:38 +00001628static PyObject *
1629multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 PyObject *pyus_in;
1632 PyObject *pyus_out;
1633 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 pyus_in = delta_to_microseconds(delta);
1636 if (pyus_in == NULL)
1637 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1640 Py_DECREF(pyus_in);
1641 if (pyus_out == NULL)
1642 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 result = microseconds_to_delta(pyus_out);
1645 Py_DECREF(pyus_out);
1646 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001647}
1648
1649static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001650multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1651{
1652 PyObject *result = NULL;
1653 PyObject *pyus_in = NULL, *temp, *pyus_out;
1654 PyObject *ratio = NULL;
1655
1656 pyus_in = delta_to_microseconds(delta);
1657 if (pyus_in == NULL)
1658 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001659 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001660 if (ratio == NULL)
1661 goto error;
1662 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1663 Py_DECREF(pyus_in);
1664 pyus_in = NULL;
1665 if (temp == NULL)
1666 goto error;
1667 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1668 Py_DECREF(temp);
1669 if (pyus_out == NULL)
1670 goto error;
1671 result = microseconds_to_delta(pyus_out);
1672 Py_DECREF(pyus_out);
1673 error:
1674 Py_XDECREF(pyus_in);
1675 Py_XDECREF(ratio);
1676
1677 return result;
1678}
1679
1680static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001681divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1682{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 PyObject *pyus_in;
1684 PyObject *pyus_out;
1685 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 pyus_in = delta_to_microseconds(delta);
1688 if (pyus_in == NULL)
1689 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1692 Py_DECREF(pyus_in);
1693 if (pyus_out == NULL)
1694 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001695
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001696 result = microseconds_to_delta(pyus_out);
1697 Py_DECREF(pyus_out);
1698 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001699}
1700
1701static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001702divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1703{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001704 PyObject *pyus_left;
1705 PyObject *pyus_right;
1706 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 pyus_left = delta_to_microseconds(left);
1709 if (pyus_left == NULL)
1710 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 pyus_right = delta_to_microseconds(right);
1713 if (pyus_right == NULL) {
1714 Py_DECREF(pyus_left);
1715 return NULL;
1716 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1719 Py_DECREF(pyus_left);
1720 Py_DECREF(pyus_right);
1721 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001722}
1723
1724static PyObject *
1725truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 PyObject *pyus_left;
1728 PyObject *pyus_right;
1729 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 pyus_left = delta_to_microseconds(left);
1732 if (pyus_left == NULL)
1733 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 pyus_right = delta_to_microseconds(right);
1736 if (pyus_right == NULL) {
1737 Py_DECREF(pyus_left);
1738 return NULL;
1739 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001741 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1742 Py_DECREF(pyus_left);
1743 Py_DECREF(pyus_right);
1744 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001745}
1746
1747static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001748truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1749{
1750 PyObject *result = NULL;
1751 PyObject *pyus_in = NULL, *temp, *pyus_out;
1752 PyObject *ratio = NULL;
1753
1754 pyus_in = delta_to_microseconds(delta);
1755 if (pyus_in == NULL)
1756 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001757 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001758 if (ratio == NULL)
1759 goto error;
1760 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1761 Py_DECREF(pyus_in);
1762 pyus_in = NULL;
1763 if (temp == NULL)
1764 goto error;
1765 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1766 Py_DECREF(temp);
1767 if (pyus_out == NULL)
1768 goto error;
1769 result = microseconds_to_delta(pyus_out);
1770 Py_DECREF(pyus_out);
1771 error:
1772 Py_XDECREF(pyus_in);
1773 Py_XDECREF(ratio);
1774
1775 return result;
1776}
1777
1778static PyObject *
1779truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1780{
1781 PyObject *result;
1782 PyObject *pyus_in, *pyus_out;
1783 pyus_in = delta_to_microseconds(delta);
1784 if (pyus_in == NULL)
1785 return NULL;
1786 pyus_out = divide_nearest(pyus_in, i);
1787 Py_DECREF(pyus_in);
1788 if (pyus_out == NULL)
1789 return NULL;
1790 result = microseconds_to_delta(pyus_out);
1791 Py_DECREF(pyus_out);
1792
1793 return result;
1794}
1795
1796static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001797delta_add(PyObject *left, PyObject *right)
1798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1802 /* delta + delta */
1803 /* The C-level additions can't overflow because of the
1804 * invariant bounds.
1805 */
1806 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1807 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1808 int microseconds = GET_TD_MICROSECONDS(left) +
1809 GET_TD_MICROSECONDS(right);
1810 result = new_delta(days, seconds, microseconds, 1);
1811 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 if (result == Py_NotImplemented)
1814 Py_INCREF(result);
1815 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001816}
1817
1818static PyObject *
1819delta_negative(PyDateTime_Delta *self)
1820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 return new_delta(-GET_TD_DAYS(self),
1822 -GET_TD_SECONDS(self),
1823 -GET_TD_MICROSECONDS(self),
1824 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001825}
1826
1827static PyObject *
1828delta_positive(PyDateTime_Delta *self)
1829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 /* Could optimize this (by returning self) if this isn't a
1831 * subclass -- but who uses unary + ? Approximately nobody.
1832 */
1833 return new_delta(GET_TD_DAYS(self),
1834 GET_TD_SECONDS(self),
1835 GET_TD_MICROSECONDS(self),
1836 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001837}
1838
1839static PyObject *
1840delta_abs(PyDateTime_Delta *self)
1841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 assert(GET_TD_MICROSECONDS(self) >= 0);
1845 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 if (GET_TD_DAYS(self) < 0)
1848 result = delta_negative(self);
1849 else
1850 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001853}
1854
1855static PyObject *
1856delta_subtract(PyObject *left, PyObject *right)
1857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1861 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001862 /* The C-level additions can't overflow because of the
1863 * invariant bounds.
1864 */
1865 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1866 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1867 int microseconds = GET_TD_MICROSECONDS(left) -
1868 GET_TD_MICROSECONDS(right);
1869 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 if (result == Py_NotImplemented)
1873 Py_INCREF(result);
1874 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001875}
1876
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001877static int
1878delta_cmp(PyObject *self, PyObject *other)
1879{
1880 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1881 if (diff == 0) {
1882 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1883 if (diff == 0)
1884 diff = GET_TD_MICROSECONDS(self) -
1885 GET_TD_MICROSECONDS(other);
1886 }
1887 return diff;
1888}
1889
Tim Peters2a799bf2002-12-16 20:18:38 +00001890static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001891delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001892{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001894 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 return diff_to_bool(diff, op);
1896 }
1897 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001898 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001900}
1901
1902static PyObject *delta_getstate(PyDateTime_Delta *self);
1903
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001904static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001905delta_hash(PyDateTime_Delta *self)
1906{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 if (self->hashcode == -1) {
1908 PyObject *temp = delta_getstate(self);
1909 if (temp != NULL) {
1910 self->hashcode = PyObject_Hash(temp);
1911 Py_DECREF(temp);
1912 }
1913 }
1914 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001915}
1916
1917static PyObject *
1918delta_multiply(PyObject *left, PyObject *right)
1919{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 if (PyDelta_Check(left)) {
1923 /* delta * ??? */
1924 if (PyLong_Check(right))
1925 result = multiply_int_timedelta(right,
1926 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001927 else if (PyFloat_Check(right))
1928 result = multiply_float_timedelta(right,
1929 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 }
1931 else if (PyLong_Check(left))
1932 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001933 (PyDateTime_Delta *) right);
1934 else if (PyFloat_Check(left))
1935 result = multiply_float_timedelta(left,
1936 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 if (result == Py_NotImplemented)
1939 Py_INCREF(result);
1940 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001941}
1942
1943static PyObject *
1944delta_divide(PyObject *left, PyObject *right)
1945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 if (PyDelta_Check(left)) {
1949 /* delta * ??? */
1950 if (PyLong_Check(right))
1951 result = divide_timedelta_int(
1952 (PyDateTime_Delta *)left,
1953 right);
1954 else if (PyDelta_Check(right))
1955 result = divide_timedelta_timedelta(
1956 (PyDateTime_Delta *)left,
1957 (PyDateTime_Delta *)right);
1958 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 if (result == Py_NotImplemented)
1961 Py_INCREF(result);
1962 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001963}
1964
Mark Dickinson7c186e22010-04-20 22:32:49 +00001965static PyObject *
1966delta_truedivide(PyObject *left, PyObject *right)
1967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 if (PyDelta_Check(left)) {
1971 if (PyDelta_Check(right))
1972 result = truedivide_timedelta_timedelta(
1973 (PyDateTime_Delta *)left,
1974 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001975 else if (PyFloat_Check(right))
1976 result = truedivide_timedelta_float(
1977 (PyDateTime_Delta *)left, right);
1978 else if (PyLong_Check(right))
1979 result = truedivide_timedelta_int(
1980 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 if (result == Py_NotImplemented)
1984 Py_INCREF(result);
1985 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001986}
1987
1988static PyObject *
1989delta_remainder(PyObject *left, PyObject *right)
1990{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 PyObject *pyus_left;
1992 PyObject *pyus_right;
1993 PyObject *pyus_remainder;
1994 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001995
Brian Curtindfc80e32011-08-10 20:28:54 -05001996 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1997 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2000 if (pyus_left == NULL)
2001 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2004 if (pyus_right == NULL) {
2005 Py_DECREF(pyus_left);
2006 return NULL;
2007 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2010 Py_DECREF(pyus_left);
2011 Py_DECREF(pyus_right);
2012 if (pyus_remainder == NULL)
2013 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 remainder = microseconds_to_delta(pyus_remainder);
2016 Py_DECREF(pyus_remainder);
2017 if (remainder == NULL)
2018 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002021}
2022
2023static PyObject *
2024delta_divmod(PyObject *left, PyObject *right)
2025{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 PyObject *pyus_left;
2027 PyObject *pyus_right;
2028 PyObject *divmod;
2029 PyObject *delta;
2030 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002031
Brian Curtindfc80e32011-08-10 20:28:54 -05002032 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2033 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2036 if (pyus_left == NULL)
2037 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2040 if (pyus_right == NULL) {
2041 Py_DECREF(pyus_left);
2042 return NULL;
2043 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2046 Py_DECREF(pyus_left);
2047 Py_DECREF(pyus_right);
2048 if (divmod == NULL)
2049 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 assert(PyTuple_Size(divmod) == 2);
2052 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2053 if (delta == NULL) {
2054 Py_DECREF(divmod);
2055 return NULL;
2056 }
2057 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2058 Py_DECREF(delta);
2059 Py_DECREF(divmod);
2060 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002061}
2062
Tim Peters2a799bf2002-12-16 20:18:38 +00002063/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2064 * timedelta constructor. sofar is the # of microseconds accounted for
2065 * so far, and there are factor microseconds per current unit, the number
2066 * of which is given by num. num * factor is added to sofar in a
2067 * numerically careful way, and that's the result. Any fractional
2068 * microseconds left over (this can happen if num is a float type) are
2069 * added into *leftover.
2070 * Note that there are many ways this can give an error (NULL) return.
2071 */
2072static PyObject *
2073accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2074 double *leftover)
2075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 PyObject *prod;
2077 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002079 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 if (PyLong_Check(num)) {
2082 prod = PyNumber_Multiply(num, factor);
2083 if (prod == NULL)
2084 return NULL;
2085 sum = PyNumber_Add(sofar, prod);
2086 Py_DECREF(prod);
2087 return sum;
2088 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 if (PyFloat_Check(num)) {
2091 double dnum;
2092 double fracpart;
2093 double intpart;
2094 PyObject *x;
2095 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 /* The Plan: decompose num into an integer part and a
2098 * fractional part, num = intpart + fracpart.
2099 * Then num * factor ==
2100 * intpart * factor + fracpart * factor
2101 * and the LHS can be computed exactly in long arithmetic.
2102 * The RHS is again broken into an int part and frac part.
2103 * and the frac part is added into *leftover.
2104 */
2105 dnum = PyFloat_AsDouble(num);
2106 if (dnum == -1.0 && PyErr_Occurred())
2107 return NULL;
2108 fracpart = modf(dnum, &intpart);
2109 x = PyLong_FromDouble(intpart);
2110 if (x == NULL)
2111 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 prod = PyNumber_Multiply(x, factor);
2114 Py_DECREF(x);
2115 if (prod == NULL)
2116 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 sum = PyNumber_Add(sofar, prod);
2119 Py_DECREF(prod);
2120 if (sum == NULL)
2121 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 if (fracpart == 0.0)
2124 return sum;
2125 /* So far we've lost no information. Dealing with the
2126 * fractional part requires float arithmetic, and may
2127 * lose a little info.
2128 */
2129 assert(PyLong_Check(factor));
2130 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002132 dnum *= fracpart;
2133 fracpart = modf(dnum, &intpart);
2134 x = PyLong_FromDouble(intpart);
2135 if (x == NULL) {
2136 Py_DECREF(sum);
2137 return NULL;
2138 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 y = PyNumber_Add(sum, x);
2141 Py_DECREF(sum);
2142 Py_DECREF(x);
2143 *leftover += fracpart;
2144 return y;
2145 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 PyErr_Format(PyExc_TypeError,
2148 "unsupported type for timedelta %s component: %s",
2149 tag, Py_TYPE(num)->tp_name);
2150 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002151}
2152
2153static PyObject *
2154delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2155{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 /* Argument objects. */
2159 PyObject *day = NULL;
2160 PyObject *second = NULL;
2161 PyObject *us = NULL;
2162 PyObject *ms = NULL;
2163 PyObject *minute = NULL;
2164 PyObject *hour = NULL;
2165 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 PyObject *x = NULL; /* running sum of microseconds */
2168 PyObject *y = NULL; /* temp sum of microseconds */
2169 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 static char *keywords[] = {
2172 "days", "seconds", "microseconds", "milliseconds",
2173 "minutes", "hours", "weeks", NULL
2174 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2177 keywords,
2178 &day, &second, &us,
2179 &ms, &minute, &hour, &week) == 0)
2180 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 x = PyLong_FromLong(0);
2183 if (x == NULL)
2184 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186#define CLEANUP \
2187 Py_DECREF(x); \
2188 x = y; \
2189 if (x == NULL) \
2190 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002193 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 CLEANUP;
2195 }
2196 if (ms) {
2197 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2198 CLEANUP;
2199 }
2200 if (second) {
2201 y = accum("seconds", x, second, us_per_second, &leftover_us);
2202 CLEANUP;
2203 }
2204 if (minute) {
2205 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2206 CLEANUP;
2207 }
2208 if (hour) {
2209 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2210 CLEANUP;
2211 }
2212 if (day) {
2213 y = accum("days", x, day, us_per_day, &leftover_us);
2214 CLEANUP;
2215 }
2216 if (week) {
2217 y = accum("weeks", x, week, us_per_week, &leftover_us);
2218 CLEANUP;
2219 }
2220 if (leftover_us) {
2221 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002222 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002223 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002224 PyObject *temp;
2225
Victor Stinner69cc4872015-09-08 23:58:54 +02002226 whole_us = round(leftover_us);
2227 if (fabs(whole_us - leftover_us) == 0.5) {
2228 /* We're exactly halfway between two integers. In order
2229 * to do round-half-to-even, we must determine whether x
2230 * is odd. Note that x is odd when it's last bit is 1. The
2231 * code below uses bitwise and operation to check the last
2232 * bit. */
2233 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2234 if (temp == NULL) {
2235 Py_DECREF(x);
2236 goto Done;
2237 }
2238 x_is_odd = PyObject_IsTrue(temp);
2239 Py_DECREF(temp);
2240 if (x_is_odd == -1) {
2241 Py_DECREF(x);
2242 goto Done;
2243 }
2244 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2245 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002246
Victor Stinner36a5a062013-08-28 01:53:39 +02002247 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 if (temp == NULL) {
2250 Py_DECREF(x);
2251 goto Done;
2252 }
2253 y = PyNumber_Add(x, temp);
2254 Py_DECREF(temp);
2255 CLEANUP;
2256 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 self = microseconds_to_delta_ex(x, type);
2259 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002260Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002262
2263#undef CLEANUP
2264}
2265
2266static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002267delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 return (GET_TD_DAYS(self) != 0
2270 || GET_TD_SECONDS(self) != 0
2271 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002272}
2273
2274static PyObject *
2275delta_repr(PyDateTime_Delta *self)
2276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 if (GET_TD_MICROSECONDS(self) != 0)
2278 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2279 Py_TYPE(self)->tp_name,
2280 GET_TD_DAYS(self),
2281 GET_TD_SECONDS(self),
2282 GET_TD_MICROSECONDS(self));
2283 if (GET_TD_SECONDS(self) != 0)
2284 return PyUnicode_FromFormat("%s(%d, %d)",
2285 Py_TYPE(self)->tp_name,
2286 GET_TD_DAYS(self),
2287 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 return PyUnicode_FromFormat("%s(%d)",
2290 Py_TYPE(self)->tp_name,
2291 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002292}
2293
2294static PyObject *
2295delta_str(PyDateTime_Delta *self)
2296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002297 int us = GET_TD_MICROSECONDS(self);
2298 int seconds = GET_TD_SECONDS(self);
2299 int minutes = divmod(seconds, 60, &seconds);
2300 int hours = divmod(minutes, 60, &minutes);
2301 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002303 if (days) {
2304 if (us)
2305 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2306 days, (days == 1 || days == -1) ? "" : "s",
2307 hours, minutes, seconds, us);
2308 else
2309 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2310 days, (days == 1 || days == -1) ? "" : "s",
2311 hours, minutes, seconds);
2312 } else {
2313 if (us)
2314 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2315 hours, minutes, seconds, us);
2316 else
2317 return PyUnicode_FromFormat("%d:%02d:%02d",
2318 hours, minutes, seconds);
2319 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002320
Tim Peters2a799bf2002-12-16 20:18:38 +00002321}
2322
Tim Peters371935f2003-02-01 01:52:50 +00002323/* Pickle support, a simple use of __reduce__. */
2324
Tim Petersb57f8f02003-02-01 02:54:15 +00002325/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002326static PyObject *
2327delta_getstate(PyDateTime_Delta *self)
2328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002329 return Py_BuildValue("iii", GET_TD_DAYS(self),
2330 GET_TD_SECONDS(self),
2331 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002332}
2333
Tim Peters2a799bf2002-12-16 20:18:38 +00002334static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002335delta_total_seconds(PyObject *self)
2336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 PyObject *total_seconds;
2338 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002340 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2341 if (total_microseconds == NULL)
2342 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002343
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002344 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002348}
2349
2350static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002351delta_reduce(PyDateTime_Delta* self)
2352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002354}
2355
2356#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2357
2358static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 {"days", T_INT, OFFSET(days), READONLY,
2361 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 {"seconds", T_INT, OFFSET(seconds), READONLY,
2364 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002366 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2367 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2368 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002369};
2370
2371static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2373 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2376 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002378 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002379};
2380
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002381static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002382PyDoc_STR("Difference between two datetime values.");
2383
2384static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 delta_add, /* nb_add */
2386 delta_subtract, /* nb_subtract */
2387 delta_multiply, /* nb_multiply */
2388 delta_remainder, /* nb_remainder */
2389 delta_divmod, /* nb_divmod */
2390 0, /* nb_power */
2391 (unaryfunc)delta_negative, /* nb_negative */
2392 (unaryfunc)delta_positive, /* nb_positive */
2393 (unaryfunc)delta_abs, /* nb_absolute */
2394 (inquiry)delta_bool, /* nb_bool */
2395 0, /*nb_invert*/
2396 0, /*nb_lshift*/
2397 0, /*nb_rshift*/
2398 0, /*nb_and*/
2399 0, /*nb_xor*/
2400 0, /*nb_or*/
2401 0, /*nb_int*/
2402 0, /*nb_reserved*/
2403 0, /*nb_float*/
2404 0, /*nb_inplace_add*/
2405 0, /*nb_inplace_subtract*/
2406 0, /*nb_inplace_multiply*/
2407 0, /*nb_inplace_remainder*/
2408 0, /*nb_inplace_power*/
2409 0, /*nb_inplace_lshift*/
2410 0, /*nb_inplace_rshift*/
2411 0, /*nb_inplace_and*/
2412 0, /*nb_inplace_xor*/
2413 0, /*nb_inplace_or*/
2414 delta_divide, /* nb_floor_divide */
2415 delta_truedivide, /* nb_true_divide */
2416 0, /* nb_inplace_floor_divide */
2417 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002418};
2419
2420static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 PyVarObject_HEAD_INIT(NULL, 0)
2422 "datetime.timedelta", /* tp_name */
2423 sizeof(PyDateTime_Delta), /* tp_basicsize */
2424 0, /* tp_itemsize */
2425 0, /* tp_dealloc */
2426 0, /* tp_print */
2427 0, /* tp_getattr */
2428 0, /* tp_setattr */
2429 0, /* tp_reserved */
2430 (reprfunc)delta_repr, /* tp_repr */
2431 &delta_as_number, /* tp_as_number */
2432 0, /* tp_as_sequence */
2433 0, /* tp_as_mapping */
2434 (hashfunc)delta_hash, /* tp_hash */
2435 0, /* tp_call */
2436 (reprfunc)delta_str, /* tp_str */
2437 PyObject_GenericGetAttr, /* tp_getattro */
2438 0, /* tp_setattro */
2439 0, /* tp_as_buffer */
2440 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2441 delta_doc, /* tp_doc */
2442 0, /* tp_traverse */
2443 0, /* tp_clear */
2444 delta_richcompare, /* tp_richcompare */
2445 0, /* tp_weaklistoffset */
2446 0, /* tp_iter */
2447 0, /* tp_iternext */
2448 delta_methods, /* tp_methods */
2449 delta_members, /* tp_members */
2450 0, /* tp_getset */
2451 0, /* tp_base */
2452 0, /* tp_dict */
2453 0, /* tp_descr_get */
2454 0, /* tp_descr_set */
2455 0, /* tp_dictoffset */
2456 0, /* tp_init */
2457 0, /* tp_alloc */
2458 delta_new, /* tp_new */
2459 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002460};
2461
2462/*
2463 * PyDateTime_Date implementation.
2464 */
2465
2466/* Accessor properties. */
2467
2468static PyObject *
2469date_year(PyDateTime_Date *self, void *unused)
2470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002472}
2473
2474static PyObject *
2475date_month(PyDateTime_Date *self, void *unused)
2476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002478}
2479
2480static PyObject *
2481date_day(PyDateTime_Date *self, void *unused)
2482{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002484}
2485
2486static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 {"year", (getter)date_year},
2488 {"month", (getter)date_month},
2489 {"day", (getter)date_day},
2490 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002491};
2492
2493/* Constructors. */
2494
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002495static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002496
Tim Peters2a799bf2002-12-16 20:18:38 +00002497static PyObject *
2498date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 PyObject *self = NULL;
2501 PyObject *state;
2502 int year;
2503 int month;
2504 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002506 /* Check for invocation from pickle with __getstate__ state */
2507 if (PyTuple_GET_SIZE(args) == 1 &&
2508 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2509 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2510 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2511 {
2512 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002514 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2515 if (me != NULL) {
2516 char *pdata = PyBytes_AS_STRING(state);
2517 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2518 me->hashcode = -1;
2519 }
2520 return (PyObject *)me;
2521 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2524 &year, &month, &day)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002525 self = new_date_ex(year, month, day, type);
2526 }
2527 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002528}
2529
2530/* Return new date from localtime(t). */
2531static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002532date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002533{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002534 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002535 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002536
Victor Stinnere4a994d2015-03-30 01:10:14 +02002537 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002538 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002539
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002540 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002541 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002542
2543 return PyObject_CallFunction(cls, "iii",
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002544 tm.tm_year + 1900,
2545 tm.tm_mon + 1,
2546 tm.tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002547}
2548
2549/* Return new date from current time.
2550 * We say this is equivalent to fromtimestamp(time.time()), and the
2551 * only way to be sure of that is to *call* time.time(). That's not
2552 * generally the same as calling C's time.
2553 */
2554static PyObject *
2555date_today(PyObject *cls, PyObject *dummy)
2556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002557 PyObject *time;
2558 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002559 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 time = time_time();
2562 if (time == NULL)
2563 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 /* Note well: today() is a class method, so this may not call
2566 * date.fromtimestamp. For example, it may call
2567 * datetime.fromtimestamp. That's why we need all the accuracy
2568 * time.time() delivers; if someone were gonzo about optimization,
2569 * date.today() could get away with plain C time().
2570 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002571 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 Py_DECREF(time);
2573 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002574}
2575
2576/* Return new date from given timestamp (Python timestamp -- a double). */
2577static PyObject *
2578date_fromtimestamp(PyObject *cls, PyObject *args)
2579{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002580 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002582
Victor Stinner5d272cc2012-03-13 13:35:55 +01002583 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2584 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002585 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002586}
2587
2588/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2589 * the ordinal is out of range.
2590 */
2591static PyObject *
2592date_fromordinal(PyObject *cls, PyObject *args)
2593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 PyObject *result = NULL;
2595 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2598 int year;
2599 int month;
2600 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002602 if (ordinal < 1)
2603 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2604 ">= 1");
2605 else {
2606 ord_to_ymd(ordinal, &year, &month, &day);
2607 result = PyObject_CallFunction(cls, "iii",
2608 year, month, day);
2609 }
2610 }
2611 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002612}
2613
2614/*
2615 * Date arithmetic.
2616 */
2617
2618/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2619 * instead.
2620 */
2621static PyObject *
2622add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 PyObject *result = NULL;
2625 int year = GET_YEAR(date);
2626 int month = GET_MONTH(date);
2627 int deltadays = GET_TD_DAYS(delta);
2628 /* C-level overflow is impossible because |deltadays| < 1e9. */
2629 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 if (normalize_date(&year, &month, &day) >= 0)
2632 result = new_date(year, month, day);
2633 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002634}
2635
2636static PyObject *
2637date_add(PyObject *left, PyObject *right)
2638{
Brian Curtindfc80e32011-08-10 20:28:54 -05002639 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2640 Py_RETURN_NOTIMPLEMENTED;
2641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 if (PyDate_Check(left)) {
2643 /* date + ??? */
2644 if (PyDelta_Check(right))
2645 /* date + delta */
2646 return add_date_timedelta((PyDateTime_Date *) left,
2647 (PyDateTime_Delta *) right,
2648 0);
2649 }
2650 else {
2651 /* ??? + date
2652 * 'right' must be one of us, or we wouldn't have been called
2653 */
2654 if (PyDelta_Check(left))
2655 /* delta + date */
2656 return add_date_timedelta((PyDateTime_Date *) right,
2657 (PyDateTime_Delta *) left,
2658 0);
2659 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002660 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002661}
2662
2663static PyObject *
2664date_subtract(PyObject *left, PyObject *right)
2665{
Brian Curtindfc80e32011-08-10 20:28:54 -05002666 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2667 Py_RETURN_NOTIMPLEMENTED;
2668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002669 if (PyDate_Check(left)) {
2670 if (PyDate_Check(right)) {
2671 /* date - date */
2672 int left_ord = ymd_to_ord(GET_YEAR(left),
2673 GET_MONTH(left),
2674 GET_DAY(left));
2675 int right_ord = ymd_to_ord(GET_YEAR(right),
2676 GET_MONTH(right),
2677 GET_DAY(right));
2678 return new_delta(left_ord - right_ord, 0, 0, 0);
2679 }
2680 if (PyDelta_Check(right)) {
2681 /* date - delta */
2682 return add_date_timedelta((PyDateTime_Date *) left,
2683 (PyDateTime_Delta *) right,
2684 1);
2685 }
2686 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002687 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002688}
2689
2690
2691/* Various ways to turn a date into a string. */
2692
2693static PyObject *
2694date_repr(PyDateTime_Date *self)
2695{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002696 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2697 Py_TYPE(self)->tp_name,
2698 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002699}
2700
2701static PyObject *
2702date_isoformat(PyDateTime_Date *self)
2703{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002704 return PyUnicode_FromFormat("%04d-%02d-%02d",
2705 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002706}
2707
Tim Peterse2df5ff2003-05-02 18:39:55 +00002708/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002709static PyObject *
2710date_str(PyDateTime_Date *self)
2711{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002712 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002713}
2714
2715
2716static PyObject *
2717date_ctime(PyDateTime_Date *self)
2718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002719 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002720}
2721
2722static PyObject *
2723date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002725 /* This method can be inherited, and needs to call the
2726 * timetuple() method appropriate to self's class.
2727 */
2728 PyObject *result;
2729 PyObject *tuple;
2730 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002731 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002732 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002734 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2735 &format))
2736 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002737
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002738 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002739 if (tuple == NULL)
2740 return NULL;
2741 result = wrap_strftime((PyObject *)self, format, tuple,
2742 (PyObject *)self);
2743 Py_DECREF(tuple);
2744 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002745}
2746
Eric Smith1ba31142007-09-11 18:06:02 +00002747static PyObject *
2748date_format(PyDateTime_Date *self, PyObject *args)
2749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002750 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002752 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2753 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002755 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002756 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002757 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002758
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002759 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002760}
2761
Tim Peters2a799bf2002-12-16 20:18:38 +00002762/* ISO methods. */
2763
2764static PyObject *
2765date_isoweekday(PyDateTime_Date *self)
2766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002767 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002769 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002770}
2771
2772static PyObject *
2773date_isocalendar(PyDateTime_Date *self)
2774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002775 int year = GET_YEAR(self);
2776 int week1_monday = iso_week1_monday(year);
2777 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2778 int week;
2779 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002781 week = divmod(today - week1_monday, 7, &day);
2782 if (week < 0) {
2783 --year;
2784 week1_monday = iso_week1_monday(year);
2785 week = divmod(today - week1_monday, 7, &day);
2786 }
2787 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2788 ++year;
2789 week = 0;
2790 }
2791 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002792}
2793
2794/* Miscellaneous methods. */
2795
Tim Peters2a799bf2002-12-16 20:18:38 +00002796static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002797date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002799 if (PyDate_Check(other)) {
2800 int diff = memcmp(((PyDateTime_Date *)self)->data,
2801 ((PyDateTime_Date *)other)->data,
2802 _PyDateTime_DATE_DATASIZE);
2803 return diff_to_bool(diff, op);
2804 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002805 else
2806 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002807}
2808
2809static PyObject *
2810date_timetuple(PyDateTime_Date *self)
2811{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002812 return build_struct_time(GET_YEAR(self),
2813 GET_MONTH(self),
2814 GET_DAY(self),
2815 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002816}
2817
Tim Peters12bf3392002-12-24 05:41:27 +00002818static PyObject *
2819date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002821 PyObject *clone;
2822 PyObject *tuple;
2823 int year = GET_YEAR(self);
2824 int month = GET_MONTH(self);
2825 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002827 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2828 &year, &month, &day))
2829 return NULL;
2830 tuple = Py_BuildValue("iii", year, month, day);
2831 if (tuple == NULL)
2832 return NULL;
2833 clone = date_new(Py_TYPE(self), tuple, NULL);
2834 Py_DECREF(tuple);
2835 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002836}
2837
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002838static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002839generic_hash(unsigned char *data, int len)
2840{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002841 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002842}
2843
2844
2845static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002846
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002847static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002848date_hash(PyDateTime_Date *self)
2849{
Benjamin Petersondec2df32016-09-09 17:46:24 -07002850 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 self->hashcode = generic_hash(
2852 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07002853 }
Guido van Rossum254348e2007-11-21 19:29:53 +00002854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002855 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002856}
2857
2858static PyObject *
2859date_toordinal(PyDateTime_Date *self)
2860{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002861 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2862 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002863}
2864
2865static PyObject *
2866date_weekday(PyDateTime_Date *self)
2867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002870 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002871}
2872
Tim Peters371935f2003-02-01 01:52:50 +00002873/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002874
Tim Petersb57f8f02003-02-01 02:54:15 +00002875/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002876static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002877date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002878{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002879 PyObject* field;
2880 field = PyBytes_FromStringAndSize((char*)self->data,
2881 _PyDateTime_DATE_DATASIZE);
2882 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002883}
2884
2885static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002886date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002888 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002889}
2890
2891static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002895 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2896 METH_CLASS,
2897 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2898 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002900 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2901 METH_CLASS,
2902 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2903 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002905 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2906 PyDoc_STR("Current date or datetime: same as "
2907 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002909 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002911 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2912 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002914 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2915 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002917 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2918 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002920 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2921 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002923 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2924 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2925 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002927 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2928 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002930 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2931 PyDoc_STR("Return the day of the week represented by the date.\n"
2932 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002934 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2935 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2936 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002938 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2939 PyDoc_STR("Return the day of the week represented by the date.\n"
2940 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002942 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2943 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002945 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2946 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002948 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002949};
2950
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002951static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002952PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002953
2954static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002955 date_add, /* nb_add */
2956 date_subtract, /* nb_subtract */
2957 0, /* nb_multiply */
2958 0, /* nb_remainder */
2959 0, /* nb_divmod */
2960 0, /* nb_power */
2961 0, /* nb_negative */
2962 0, /* nb_positive */
2963 0, /* nb_absolute */
2964 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002965};
2966
2967static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002968 PyVarObject_HEAD_INIT(NULL, 0)
2969 "datetime.date", /* tp_name */
2970 sizeof(PyDateTime_Date), /* tp_basicsize */
2971 0, /* tp_itemsize */
2972 0, /* tp_dealloc */
2973 0, /* tp_print */
2974 0, /* tp_getattr */
2975 0, /* tp_setattr */
2976 0, /* tp_reserved */
2977 (reprfunc)date_repr, /* tp_repr */
2978 &date_as_number, /* tp_as_number */
2979 0, /* tp_as_sequence */
2980 0, /* tp_as_mapping */
2981 (hashfunc)date_hash, /* tp_hash */
2982 0, /* tp_call */
2983 (reprfunc)date_str, /* tp_str */
2984 PyObject_GenericGetAttr, /* tp_getattro */
2985 0, /* tp_setattro */
2986 0, /* tp_as_buffer */
2987 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2988 date_doc, /* tp_doc */
2989 0, /* tp_traverse */
2990 0, /* tp_clear */
2991 date_richcompare, /* tp_richcompare */
2992 0, /* tp_weaklistoffset */
2993 0, /* tp_iter */
2994 0, /* tp_iternext */
2995 date_methods, /* tp_methods */
2996 0, /* tp_members */
2997 date_getset, /* tp_getset */
2998 0, /* tp_base */
2999 0, /* tp_dict */
3000 0, /* tp_descr_get */
3001 0, /* tp_descr_set */
3002 0, /* tp_dictoffset */
3003 0, /* tp_init */
3004 0, /* tp_alloc */
3005 date_new, /* tp_new */
3006 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003007};
3008
3009/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003010 * PyDateTime_TZInfo implementation.
3011 */
3012
3013/* This is a pure abstract base class, so doesn't do anything beyond
3014 * raising NotImplemented exceptions. Real tzinfo classes need
3015 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003016 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003017 * be subclasses of this tzinfo class, which is easy and quick to check).
3018 *
3019 * Note: For reasons having to do with pickling of subclasses, we have
3020 * to allow tzinfo objects to be instantiated. This wasn't an issue
3021 * in the Python implementation (__init__() could raise NotImplementedError
3022 * there without ill effect), but doing so in the C implementation hit a
3023 * brick wall.
3024 */
3025
3026static PyObject *
3027tzinfo_nogo(const char* methodname)
3028{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003029 PyErr_Format(PyExc_NotImplementedError,
3030 "a tzinfo subclass must implement %s()",
3031 methodname);
3032 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003033}
3034
3035/* Methods. A subclass must implement these. */
3036
Tim Peters52dcce22003-01-23 16:36:11 +00003037static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003038tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3039{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003040 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003041}
3042
Tim Peters52dcce22003-01-23 16:36:11 +00003043static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003044tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3045{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003046 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003047}
3048
Tim Peters52dcce22003-01-23 16:36:11 +00003049static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003050tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3051{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003052 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003053}
3054
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003055
3056static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3057 PyDateTime_Delta *delta,
3058 int factor);
3059static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3060static PyObject *datetime_dst(PyObject *self, PyObject *);
3061
Tim Peters52dcce22003-01-23 16:36:11 +00003062static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003063tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003064{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003065 PyObject *result = NULL;
3066 PyObject *off = NULL, *dst = NULL;
3067 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003068
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003069 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003070 PyErr_SetString(PyExc_TypeError,
3071 "fromutc: argument must be a datetime");
3072 return NULL;
3073 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003074 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003075 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3076 "is not self");
3077 return NULL;
3078 }
Tim Peters52dcce22003-01-23 16:36:11 +00003079
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003080 off = datetime_utcoffset(dt, NULL);
3081 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003082 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003083 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003084 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3085 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003086 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003087 }
Tim Peters52dcce22003-01-23 16:36:11 +00003088
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003089 dst = datetime_dst(dt, NULL);
3090 if (dst == NULL)
3091 goto Fail;
3092 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003093 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3094 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003095 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003096 }
Tim Peters52dcce22003-01-23 16:36:11 +00003097
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003098 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3099 if (delta == NULL)
3100 goto Fail;
3101 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003102 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003103 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003104
3105 Py_DECREF(dst);
3106 dst = call_dst(GET_DT_TZINFO(dt), result);
3107 if (dst == NULL)
3108 goto Fail;
3109 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003111 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003112 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003113 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003114 if (result == NULL)
3115 goto Fail;
3116 }
3117 Py_DECREF(delta);
3118 Py_DECREF(dst);
3119 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003120 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003121
3122Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003123 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3124 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003126 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003127Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003128 Py_XDECREF(off);
3129 Py_XDECREF(dst);
3130 Py_XDECREF(delta);
3131 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003132 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003133}
3134
Tim Peters2a799bf2002-12-16 20:18:38 +00003135/*
3136 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003137 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003138 */
3139
Guido van Rossum177e41a2003-01-30 22:06:23 +00003140static PyObject *
3141tzinfo_reduce(PyObject *self)
3142{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003143 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003144 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003145 _Py_IDENTIFIER(__getinitargs__);
3146 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003147
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003148 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003149 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003150 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003151 Py_DECREF(getinitargs);
3152 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003153 return NULL;
3154 }
3155 }
3156 else {
3157 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003158
3159 args = PyTuple_New(0);
3160 if (args == NULL) {
3161 return NULL;
3162 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003163 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003164
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003165 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003166 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003167 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003168 Py_DECREF(getstate);
3169 if (state == NULL) {
3170 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003171 return NULL;
3172 }
3173 }
3174 else {
3175 PyObject **dictptr;
3176 PyErr_Clear();
3177 state = Py_None;
3178 dictptr = _PyObject_GetDictPtr(self);
Victor Stinnerd1584d32016-08-23 00:11:04 +02003179 if (dictptr && *dictptr && PyDict_Size(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003180 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003181 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003182 Py_INCREF(state);
3183 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003185 if (state == Py_None) {
3186 Py_DECREF(state);
3187 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3188 }
3189 else
3190 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003191}
Tim Peters2a799bf2002-12-16 20:18:38 +00003192
3193static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003195 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3196 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003199 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3200 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003202 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3203 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003205 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003206 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3209 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003211 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003212};
3213
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003214static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003215PyDoc_STR("Abstract base class for time zone info objects.");
3216
Neal Norwitz227b5332006-03-22 09:28:35 +00003217static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003218 PyVarObject_HEAD_INIT(NULL, 0)
3219 "datetime.tzinfo", /* tp_name */
3220 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3221 0, /* tp_itemsize */
3222 0, /* tp_dealloc */
3223 0, /* tp_print */
3224 0, /* tp_getattr */
3225 0, /* tp_setattr */
3226 0, /* tp_reserved */
3227 0, /* tp_repr */
3228 0, /* tp_as_number */
3229 0, /* tp_as_sequence */
3230 0, /* tp_as_mapping */
3231 0, /* tp_hash */
3232 0, /* tp_call */
3233 0, /* tp_str */
3234 PyObject_GenericGetAttr, /* tp_getattro */
3235 0, /* tp_setattro */
3236 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003237 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003238 tzinfo_doc, /* tp_doc */
3239 0, /* tp_traverse */
3240 0, /* tp_clear */
3241 0, /* tp_richcompare */
3242 0, /* tp_weaklistoffset */
3243 0, /* tp_iter */
3244 0, /* tp_iternext */
3245 tzinfo_methods, /* tp_methods */
3246 0, /* tp_members */
3247 0, /* tp_getset */
3248 0, /* tp_base */
3249 0, /* tp_dict */
3250 0, /* tp_descr_get */
3251 0, /* tp_descr_set */
3252 0, /* tp_dictoffset */
3253 0, /* tp_init */
3254 0, /* tp_alloc */
3255 PyType_GenericNew, /* tp_new */
3256 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003257};
3258
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003259static char *timezone_kws[] = {"offset", "name", NULL};
3260
3261static PyObject *
3262timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3263{
3264 PyObject *offset;
3265 PyObject *name = NULL;
3266 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3267 &PyDateTime_DeltaType, &offset,
3268 &PyUnicode_Type, &name))
3269 return new_timezone(offset, name);
3270
3271 return NULL;
3272}
3273
3274static void
3275timezone_dealloc(PyDateTime_TimeZone *self)
3276{
3277 Py_CLEAR(self->offset);
3278 Py_CLEAR(self->name);
3279 Py_TYPE(self)->tp_free((PyObject *)self);
3280}
3281
3282static PyObject *
3283timezone_richcompare(PyDateTime_TimeZone *self,
3284 PyDateTime_TimeZone *other, int op)
3285{
Brian Curtindfc80e32011-08-10 20:28:54 -05003286 if (op != Py_EQ && op != Py_NE)
3287 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003288 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003289 if (op == Py_EQ)
3290 Py_RETURN_FALSE;
3291 else
3292 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003293 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003294 return delta_richcompare(self->offset, other->offset, op);
3295}
3296
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003297static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003298timezone_hash(PyDateTime_TimeZone *self)
3299{
3300 return delta_hash((PyDateTime_Delta *)self->offset);
3301}
3302
3303/* Check argument type passed to tzname, utcoffset, or dst methods.
3304 Returns 0 for good argument. Returns -1 and sets exception info
3305 otherwise.
3306 */
3307static int
3308_timezone_check_argument(PyObject *dt, const char *meth)
3309{
3310 if (dt == Py_None || PyDateTime_Check(dt))
3311 return 0;
3312 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3313 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3314 return -1;
3315}
3316
3317static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003318timezone_repr(PyDateTime_TimeZone *self)
3319{
3320 /* Note that although timezone is not subclassable, it is convenient
3321 to use Py_TYPE(self)->tp_name here. */
3322 const char *type_name = Py_TYPE(self)->tp_name;
3323
3324 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3325 return PyUnicode_FromFormat("%s.utc", type_name);
3326
3327 if (self->name == NULL)
3328 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3329
3330 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3331 self->name);
3332}
3333
3334
3335static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003336timezone_str(PyDateTime_TimeZone *self)
3337{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003338 int hours, minutes, seconds;
3339 PyObject *offset;
3340 char sign;
3341
3342 if (self->name != NULL) {
3343 Py_INCREF(self->name);
3344 return self->name;
3345 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003346 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003347 (GET_TD_DAYS(self->offset) == 0 &&
3348 GET_TD_SECONDS(self->offset) == 0 &&
3349 GET_TD_MICROSECONDS(self->offset) == 0))
3350 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003351 /* Offset is normalized, so it is negative if days < 0 */
3352 if (GET_TD_DAYS(self->offset) < 0) {
3353 sign = '-';
3354 offset = delta_negative((PyDateTime_Delta *)self->offset);
3355 if (offset == NULL)
3356 return NULL;
3357 }
3358 else {
3359 sign = '+';
3360 offset = self->offset;
3361 Py_INCREF(offset);
3362 }
3363 /* Offset is not negative here. */
3364 seconds = GET_TD_SECONDS(offset);
3365 Py_DECREF(offset);
3366 minutes = divmod(seconds, 60, &seconds);
3367 hours = divmod(minutes, 60, &minutes);
Martin Pantere26da7c2016-06-02 10:07:09 +00003368 /* XXX ignore sub-minute data, currently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003369 assert(seconds == 0);
3370 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003371}
3372
3373static PyObject *
3374timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3375{
3376 if (_timezone_check_argument(dt, "tzname") == -1)
3377 return NULL;
3378
3379 return timezone_str(self);
3380}
3381
3382static PyObject *
3383timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3384{
3385 if (_timezone_check_argument(dt, "utcoffset") == -1)
3386 return NULL;
3387
3388 Py_INCREF(self->offset);
3389 return self->offset;
3390}
3391
3392static PyObject *
3393timezone_dst(PyObject *self, PyObject *dt)
3394{
3395 if (_timezone_check_argument(dt, "dst") == -1)
3396 return NULL;
3397
3398 Py_RETURN_NONE;
3399}
3400
3401static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003402timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3403{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003404 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003405 PyErr_SetString(PyExc_TypeError,
3406 "fromutc: argument must be a datetime");
3407 return NULL;
3408 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003409 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003410 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3411 "is not self");
3412 return NULL;
3413 }
3414
3415 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3416}
3417
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003418static PyObject *
3419timezone_getinitargs(PyDateTime_TimeZone *self)
3420{
3421 if (self->name == NULL)
3422 return Py_BuildValue("(O)", self->offset);
3423 return Py_BuildValue("(OO)", self->offset, self->name);
3424}
3425
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003426static PyMethodDef timezone_methods[] = {
3427 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3428 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003429 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003430
3431 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003432 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003433
3434 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003435 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003436
3437 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3438 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3439
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003440 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3441 PyDoc_STR("pickle support")},
3442
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003443 {NULL, NULL}
3444};
3445
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003446static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003447PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3448
3449static PyTypeObject PyDateTime_TimeZoneType = {
3450 PyVarObject_HEAD_INIT(NULL, 0)
3451 "datetime.timezone", /* tp_name */
3452 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3453 0, /* tp_itemsize */
3454 (destructor)timezone_dealloc, /* tp_dealloc */
3455 0, /* tp_print */
3456 0, /* tp_getattr */
3457 0, /* tp_setattr */
3458 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003459 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003460 0, /* tp_as_number */
3461 0, /* tp_as_sequence */
3462 0, /* tp_as_mapping */
3463 (hashfunc)timezone_hash, /* tp_hash */
3464 0, /* tp_call */
3465 (reprfunc)timezone_str, /* tp_str */
3466 0, /* tp_getattro */
3467 0, /* tp_setattro */
3468 0, /* tp_as_buffer */
3469 Py_TPFLAGS_DEFAULT, /* tp_flags */
3470 timezone_doc, /* tp_doc */
3471 0, /* tp_traverse */
3472 0, /* tp_clear */
3473 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3474 0, /* tp_weaklistoffset */
3475 0, /* tp_iter */
3476 0, /* tp_iternext */
3477 timezone_methods, /* tp_methods */
3478 0, /* tp_members */
3479 0, /* tp_getset */
3480 &PyDateTime_TZInfoType, /* tp_base */
3481 0, /* tp_dict */
3482 0, /* tp_descr_get */
3483 0, /* tp_descr_set */
3484 0, /* tp_dictoffset */
3485 0, /* tp_init */
3486 0, /* tp_alloc */
3487 timezone_new, /* tp_new */
3488};
3489
Tim Peters2a799bf2002-12-16 20:18:38 +00003490/*
Tim Peters37f39822003-01-10 03:49:02 +00003491 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003492 */
3493
Tim Peters37f39822003-01-10 03:49:02 +00003494/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003495 */
3496
3497static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003498time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003500 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003501}
3502
Tim Peters37f39822003-01-10 03:49:02 +00003503static PyObject *
3504time_minute(PyDateTime_Time *self, void *unused)
3505{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003506 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003507}
3508
3509/* The name time_second conflicted with some platform header file. */
3510static PyObject *
3511py_time_second(PyDateTime_Time *self, void *unused)
3512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003513 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003514}
3515
3516static PyObject *
3517time_microsecond(PyDateTime_Time *self, void *unused)
3518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003519 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003520}
3521
3522static PyObject *
3523time_tzinfo(PyDateTime_Time *self, void *unused)
3524{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003525 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3526 Py_INCREF(result);
3527 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003528}
3529
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003530static PyObject *
3531time_fold(PyDateTime_Time *self, void *unused)
3532{
3533 return PyLong_FromLong(TIME_GET_FOLD(self));
3534}
3535
Tim Peters37f39822003-01-10 03:49:02 +00003536static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003537 {"hour", (getter)time_hour},
3538 {"minute", (getter)time_minute},
3539 {"second", (getter)py_time_second},
3540 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003541 {"tzinfo", (getter)time_tzinfo},
3542 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003543 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003544};
3545
3546/*
3547 * Constructors.
3548 */
3549
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003550static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003551 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003552
Tim Peters2a799bf2002-12-16 20:18:38 +00003553static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003554time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003556 PyObject *self = NULL;
3557 PyObject *state;
3558 int hour = 0;
3559 int minute = 0;
3560 int second = 0;
3561 int usecond = 0;
3562 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003563 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003565 /* Check for invocation from pickle with __getstate__ state */
3566 if (PyTuple_GET_SIZE(args) >= 1 &&
3567 PyTuple_GET_SIZE(args) <= 2 &&
3568 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3569 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003570 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003571 {
3572 PyDateTime_Time *me;
3573 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003575 if (PyTuple_GET_SIZE(args) == 2) {
3576 tzinfo = PyTuple_GET_ITEM(args, 1);
3577 if (check_tzinfo_subclass(tzinfo) < 0) {
3578 PyErr_SetString(PyExc_TypeError, "bad "
3579 "tzinfo state arg");
3580 return NULL;
3581 }
3582 }
3583 aware = (char)(tzinfo != Py_None);
3584 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3585 if (me != NULL) {
3586 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003588 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3589 me->hashcode = -1;
3590 me->hastzinfo = aware;
3591 if (aware) {
3592 Py_INCREF(tzinfo);
3593 me->tzinfo = tzinfo;
3594 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003595 if (pdata[0] & (1 << 7)) {
3596 me->data[0] -= 128;
3597 me->fold = 1;
3598 }
3599 else {
3600 me->fold = 0;
3601 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003602 }
3603 return (PyObject *)me;
3604 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003605
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003606 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003607 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003608 &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003609 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3610 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003611 }
3612 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003613}
3614
3615/*
3616 * Destructor.
3617 */
3618
3619static void
Tim Peters37f39822003-01-10 03:49:02 +00003620time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003622 if (HASTZINFO(self)) {
3623 Py_XDECREF(self->tzinfo);
3624 }
3625 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003626}
3627
3628/*
Tim Peters855fe882002-12-22 03:43:39 +00003629 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003630 */
3631
Tim Peters2a799bf2002-12-16 20:18:38 +00003632/* These are all METH_NOARGS, so don't need to check the arglist. */
3633static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003634time_utcoffset(PyObject *self, PyObject *unused) {
3635 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003636}
3637
3638static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003639time_dst(PyObject *self, PyObject *unused) {
3640 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003641}
3642
3643static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003644time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003645 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003646}
3647
3648/*
Tim Peters37f39822003-01-10 03:49:02 +00003649 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003650 */
3651
3652static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003653time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003654{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003655 const char *type_name = Py_TYPE(self)->tp_name;
3656 int h = TIME_GET_HOUR(self);
3657 int m = TIME_GET_MINUTE(self);
3658 int s = TIME_GET_SECOND(self);
3659 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003660 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003661 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003663 if (us)
3664 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3665 type_name, h, m, s, us);
3666 else if (s)
3667 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3668 type_name, h, m, s);
3669 else
3670 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3671 if (result != NULL && HASTZINFO(self))
3672 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003673 if (result != NULL && fold)
3674 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003675 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003676}
3677
Tim Peters37f39822003-01-10 03:49:02 +00003678static PyObject *
3679time_str(PyDateTime_Time *self)
3680{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003681 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003682}
Tim Peters2a799bf2002-12-16 20:18:38 +00003683
3684static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003685time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003687 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003688 char *timespec = NULL;
3689 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003690 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003691 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003692 static char *specs[][2] = {
3693 {"hours", "%02d"},
3694 {"minutes", "%02d:%02d"},
3695 {"seconds", "%02d:%02d:%02d"},
3696 {"milliseconds", "%02d:%02d:%02d.%03d"},
3697 {"microseconds", "%02d:%02d:%02d.%06d"},
3698 };
3699 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003700
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003701 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3702 return NULL;
3703
3704 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3705 if (us == 0) {
3706 /* seconds */
3707 given_spec = 2;
3708 }
3709 else {
3710 /* microseconds */
3711 given_spec = 4;
3712 }
3713 }
3714 else {
3715 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3716 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3717 if (given_spec == 3) {
3718 /* milliseconds */
3719 us = us / 1000;
3720 }
3721 break;
3722 }
3723 }
3724 }
3725
3726 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3727 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3728 return NULL;
3729 }
3730 else {
3731 result = PyUnicode_FromFormat(specs[given_spec][1],
3732 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3733 TIME_GET_SECOND(self), us);
3734 }
Tim Peters37f39822003-01-10 03:49:02 +00003735
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003736 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003737 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003739 /* We need to append the UTC offset. */
3740 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3741 Py_None) < 0) {
3742 Py_DECREF(result);
3743 return NULL;
3744 }
3745 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3746 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003747}
3748
Tim Peters37f39822003-01-10 03:49:02 +00003749static PyObject *
3750time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003752 PyObject *result;
3753 PyObject *tuple;
3754 PyObject *format;
3755 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003757 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3758 &format))
3759 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003761 /* Python's strftime does insane things with the year part of the
3762 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003763 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003764 */
3765 tuple = Py_BuildValue("iiiiiiiii",
3766 1900, 1, 1, /* year, month, day */
3767 TIME_GET_HOUR(self),
3768 TIME_GET_MINUTE(self),
3769 TIME_GET_SECOND(self),
3770 0, 1, -1); /* weekday, daynum, dst */
3771 if (tuple == NULL)
3772 return NULL;
3773 assert(PyTuple_Size(tuple) == 9);
3774 result = wrap_strftime((PyObject *)self, format, tuple,
3775 Py_None);
3776 Py_DECREF(tuple);
3777 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003778}
Tim Peters2a799bf2002-12-16 20:18:38 +00003779
3780/*
3781 * Miscellaneous methods.
3782 */
3783
Tim Peters37f39822003-01-10 03:49:02 +00003784static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003785time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003786{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003787 PyObject *result = NULL;
3788 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003789 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003790
Brian Curtindfc80e32011-08-10 20:28:54 -05003791 if (! PyTime_Check(other))
3792 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003793
3794 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003795 diff = memcmp(((PyDateTime_Time *)self)->data,
3796 ((PyDateTime_Time *)other)->data,
3797 _PyDateTime_TIME_DATASIZE);
3798 return diff_to_bool(diff, op);
3799 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003800 offset1 = time_utcoffset(self, NULL);
3801 if (offset1 == NULL)
3802 return NULL;
3803 offset2 = time_utcoffset(other, NULL);
3804 if (offset2 == NULL)
3805 goto done;
3806 /* If they're both naive, or both aware and have the same offsets,
3807 * we get off cheap. Note that if they're both naive, offset1 ==
3808 * offset2 == Py_None at this point.
3809 */
3810 if ((offset1 == offset2) ||
3811 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3812 delta_cmp(offset1, offset2) == 0)) {
3813 diff = memcmp(((PyDateTime_Time *)self)->data,
3814 ((PyDateTime_Time *)other)->data,
3815 _PyDateTime_TIME_DATASIZE);
3816 result = diff_to_bool(diff, op);
3817 }
3818 /* The hard case: both aware with different UTC offsets */
3819 else if (offset1 != Py_None && offset2 != Py_None) {
3820 int offsecs1, offsecs2;
3821 assert(offset1 != offset2); /* else last "if" handled it */
3822 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3823 TIME_GET_MINUTE(self) * 60 +
3824 TIME_GET_SECOND(self) -
3825 GET_TD_DAYS(offset1) * 86400 -
3826 GET_TD_SECONDS(offset1);
3827 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3828 TIME_GET_MINUTE(other) * 60 +
3829 TIME_GET_SECOND(other) -
3830 GET_TD_DAYS(offset2) * 86400 -
3831 GET_TD_SECONDS(offset2);
3832 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003833 if (diff == 0)
3834 diff = TIME_GET_MICROSECOND(self) -
3835 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003836 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003837 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003838 else if (op == Py_EQ) {
3839 result = Py_False;
3840 Py_INCREF(result);
3841 }
3842 else if (op == Py_NE) {
3843 result = Py_True;
3844 Py_INCREF(result);
3845 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003846 else {
3847 PyErr_SetString(PyExc_TypeError,
3848 "can't compare offset-naive and "
3849 "offset-aware times");
3850 }
3851 done:
3852 Py_DECREF(offset1);
3853 Py_XDECREF(offset2);
3854 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003855}
3856
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003857static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003858time_hash(PyDateTime_Time *self)
3859{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003860 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003861 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01003862 if (TIME_GET_FOLD(self)) {
3863 self0 = new_time_ex2(TIME_GET_HOUR(self),
3864 TIME_GET_MINUTE(self),
3865 TIME_GET_SECOND(self),
3866 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003867 HASTZINFO(self) ? self->tzinfo : Py_None,
3868 0, Py_TYPE(self));
3869 if (self0 == NULL)
3870 return -1;
3871 }
3872 else {
3873 self0 = (PyObject *)self;
3874 Py_INCREF(self0);
3875 }
3876 offset = time_utcoffset(self0, NULL);
3877 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003878
3879 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003880 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003882 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003883 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003884 self->hashcode = generic_hash(
3885 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003886 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003887 PyObject *temp1, *temp2;
3888 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003889 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003890 seconds = TIME_GET_HOUR(self) * 3600 +
3891 TIME_GET_MINUTE(self) * 60 +
3892 TIME_GET_SECOND(self);
3893 microseconds = TIME_GET_MICROSECOND(self);
3894 temp1 = new_delta(0, seconds, microseconds, 1);
3895 if (temp1 == NULL) {
3896 Py_DECREF(offset);
3897 return -1;
3898 }
3899 temp2 = delta_subtract(temp1, offset);
3900 Py_DECREF(temp1);
3901 if (temp2 == NULL) {
3902 Py_DECREF(offset);
3903 return -1;
3904 }
3905 self->hashcode = PyObject_Hash(temp2);
3906 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003907 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003908 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003909 }
3910 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003911}
Tim Peters2a799bf2002-12-16 20:18:38 +00003912
Tim Peters12bf3392002-12-24 05:41:27 +00003913static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003914time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003916 PyObject *clone;
3917 PyObject *tuple;
3918 int hh = TIME_GET_HOUR(self);
3919 int mm = TIME_GET_MINUTE(self);
3920 int ss = TIME_GET_SECOND(self);
3921 int us = TIME_GET_MICROSECOND(self);
3922 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003923 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003924
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003925 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003926 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003927 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003928 return NULL;
3929 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3930 if (tuple == NULL)
3931 return NULL;
3932 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003933 if (clone != NULL) {
3934 if (fold != 0 && fold != 1) {
3935 PyErr_SetString(PyExc_ValueError,
3936 "fold must be either 0 or 1");
3937 return NULL;
3938 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003939 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003940 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003941 Py_DECREF(tuple);
3942 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003943}
3944
Tim Peters371935f2003-02-01 01:52:50 +00003945/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003946
Tim Peters33e0f382003-01-10 02:05:14 +00003947/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003948 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3949 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003950 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003951 */
3952static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003953time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00003954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003955 PyObject *basestate;
3956 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003958 basestate = PyBytes_FromStringAndSize((char *)self->data,
3959 _PyDateTime_TIME_DATASIZE);
3960 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003961 if (proto > 3 && TIME_GET_FOLD(self))
3962 /* Set the first bit of the first byte */
3963 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003964 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3965 result = PyTuple_Pack(1, basestate);
3966 else
3967 result = PyTuple_Pack(2, basestate, self->tzinfo);
3968 Py_DECREF(basestate);
3969 }
3970 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003971}
3972
3973static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003974time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00003975{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003976 int proto;
3977 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003978 return NULL;
3979
3980 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00003981}
3982
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003983static PyObject *
3984time_reduce(PyDateTime_Time *self, PyObject *arg)
3985{
3986 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
3987}
3988
Tim Peters37f39822003-01-10 03:49:02 +00003989static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003990
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003991 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
3992 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
3993 "[+HH:MM].\n\n"
3994 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003996 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3997 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003999 {"__format__", (PyCFunction)date_format, METH_VARARGS,
4000 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00004001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004002 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4003 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004005 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4006 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004008 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4009 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004011 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4012 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004013
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004014 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004015 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004016
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004017 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4018 PyDoc_STR("__reduce__() -> (cls, state)")},
4019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004020 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004021};
4022
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004023static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004024PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4025\n\
4026All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004027a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004028
Neal Norwitz227b5332006-03-22 09:28:35 +00004029static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004030 PyVarObject_HEAD_INIT(NULL, 0)
4031 "datetime.time", /* tp_name */
4032 sizeof(PyDateTime_Time), /* tp_basicsize */
4033 0, /* tp_itemsize */
4034 (destructor)time_dealloc, /* tp_dealloc */
4035 0, /* tp_print */
4036 0, /* tp_getattr */
4037 0, /* tp_setattr */
4038 0, /* tp_reserved */
4039 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004040 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004041 0, /* tp_as_sequence */
4042 0, /* tp_as_mapping */
4043 (hashfunc)time_hash, /* tp_hash */
4044 0, /* tp_call */
4045 (reprfunc)time_str, /* tp_str */
4046 PyObject_GenericGetAttr, /* tp_getattro */
4047 0, /* tp_setattro */
4048 0, /* tp_as_buffer */
4049 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4050 time_doc, /* tp_doc */
4051 0, /* tp_traverse */
4052 0, /* tp_clear */
4053 time_richcompare, /* tp_richcompare */
4054 0, /* tp_weaklistoffset */
4055 0, /* tp_iter */
4056 0, /* tp_iternext */
4057 time_methods, /* tp_methods */
4058 0, /* tp_members */
4059 time_getset, /* tp_getset */
4060 0, /* tp_base */
4061 0, /* tp_dict */
4062 0, /* tp_descr_get */
4063 0, /* tp_descr_set */
4064 0, /* tp_dictoffset */
4065 0, /* tp_init */
4066 time_alloc, /* tp_alloc */
4067 time_new, /* tp_new */
4068 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004069};
4070
4071/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004072 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004073 */
4074
Tim Petersa9bc1682003-01-11 03:39:11 +00004075/* Accessor properties. Properties for day, month, and year are inherited
4076 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004077 */
4078
4079static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004080datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004081{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004082 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004083}
4084
Tim Petersa9bc1682003-01-11 03:39:11 +00004085static PyObject *
4086datetime_minute(PyDateTime_DateTime *self, void *unused)
4087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004088 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004089}
4090
4091static PyObject *
4092datetime_second(PyDateTime_DateTime *self, void *unused)
4093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004094 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004095}
4096
4097static PyObject *
4098datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004100 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004101}
4102
4103static PyObject *
4104datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4105{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004106 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4107 Py_INCREF(result);
4108 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004109}
4110
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004111static PyObject *
4112datetime_fold(PyDateTime_DateTime *self, void *unused)
4113{
4114 return PyLong_FromLong(DATE_GET_FOLD(self));
4115}
4116
Tim Petersa9bc1682003-01-11 03:39:11 +00004117static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004118 {"hour", (getter)datetime_hour},
4119 {"minute", (getter)datetime_minute},
4120 {"second", (getter)datetime_second},
4121 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004122 {"tzinfo", (getter)datetime_tzinfo},
4123 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004124 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004125};
4126
4127/*
4128 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004129 */
4130
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004131static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004132 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004133 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004134};
4135
Tim Peters2a799bf2002-12-16 20:18:38 +00004136static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004137datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004138{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004139 PyObject *self = NULL;
4140 PyObject *state;
4141 int year;
4142 int month;
4143 int day;
4144 int hour = 0;
4145 int minute = 0;
4146 int second = 0;
4147 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004148 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004149 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004151 /* Check for invocation from pickle with __getstate__ state */
4152 if (PyTuple_GET_SIZE(args) >= 1 &&
4153 PyTuple_GET_SIZE(args) <= 2 &&
4154 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4155 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004156 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004157 {
4158 PyDateTime_DateTime *me;
4159 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004161 if (PyTuple_GET_SIZE(args) == 2) {
4162 tzinfo = PyTuple_GET_ITEM(args, 1);
4163 if (check_tzinfo_subclass(tzinfo) < 0) {
4164 PyErr_SetString(PyExc_TypeError, "bad "
4165 "tzinfo state arg");
4166 return NULL;
4167 }
4168 }
4169 aware = (char)(tzinfo != Py_None);
4170 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4171 if (me != NULL) {
4172 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004174 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4175 me->hashcode = -1;
4176 me->hastzinfo = aware;
4177 if (aware) {
4178 Py_INCREF(tzinfo);
4179 me->tzinfo = tzinfo;
4180 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004181 if (pdata[2] & (1 << 7)) {
4182 me->data[2] -= 128;
4183 me->fold = 1;
4184 }
4185 else {
4186 me->fold = 0;
4187 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004188 }
4189 return (PyObject *)me;
4190 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004191
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004192 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004194 &second, &usecond, &tzinfo, &fold)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004195 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004196 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004197 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004198 }
4199 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004200}
4201
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004202/* TM_FUNC is the shared type of _PyTime_localtime() and
4203 * _PyTime_gmtime(). */
4204typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004205
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004206/* As of version 2015f max fold in IANA database is
4207 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004208static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004209/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004210static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004211
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004212static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004213utc_to_seconds(int year, int month, int day,
4214 int hour, int minute, int second)
4215{
Victor Stinnerb67f0962017-02-10 10:34:02 +01004216 long long ordinal;
4217
4218 /* ymd_to_ord() doesn't support year <= 0 */
4219 if (year < MINYEAR || year > MAXYEAR) {
4220 PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4221 return -1;
4222 }
4223
4224 ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004225 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4226}
4227
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004228static long long
4229local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004230{
4231 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004232 time_t t;
4233 u -= epoch;
4234 t = u;
4235 if (t != u) {
4236 PyErr_SetString(PyExc_OverflowError,
4237 "timestamp out of range for platform time_t");
4238 return -1;
4239 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004240 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004241 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004242 return utc_to_seconds(local_time.tm_year + 1900,
4243 local_time.tm_mon + 1,
4244 local_time.tm_mday,
4245 local_time.tm_hour,
4246 local_time.tm_min,
4247 local_time.tm_sec);
4248}
4249
Tim Petersa9bc1682003-01-11 03:39:11 +00004250/* Internal helper.
4251 * Build datetime from a time_t and a distinct count of microseconds.
4252 * Pass localtime or gmtime for f, to control the interpretation of timet.
4253 */
4254static PyObject *
4255datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004256 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004257{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004258 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004259 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004260
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004261 if (f(timet, &tm) != 0)
4262 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004263
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004264 year = tm.tm_year + 1900;
4265 month = tm.tm_mon + 1;
4266 day = tm.tm_mday;
4267 hour = tm.tm_hour;
4268 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004269 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004270 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004271 * except to the extent that passing them on to the datetime
4272 * constructor would raise ValueError for a reason that
4273 * made no sense to the user.
4274 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004275 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004276
Victor Stinnerb67f0962017-02-10 10:34:02 +01004277 /* local timezone requires to compute fold */
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004278 if (tzinfo == Py_None && f == _PyTime_localtime) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004279 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004280
4281 result_seconds = utc_to_seconds(year, month, day,
4282 hour, minute, second);
4283 /* Probe max_fold_seconds to detect a fold. */
4284 probe_seconds = local(epoch + timet - max_fold_seconds);
4285 if (probe_seconds == -1)
4286 return NULL;
4287 transition = result_seconds - probe_seconds - max_fold_seconds;
4288 if (transition < 0) {
4289 probe_seconds = local(epoch + timet + transition);
4290 if (probe_seconds == -1)
4291 return NULL;
4292 if (probe_seconds == result_seconds)
4293 fold = 1;
4294 }
4295 }
4296 return new_datetime_ex2(year, month, day, hour,
4297 minute, second, us, tzinfo, fold,
4298 (PyTypeObject *)cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004299}
4300
4301/* Internal helper.
4302 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4303 * to control the interpretation of the timestamp. Since a double doesn't
4304 * have enough bits to cover a datetime's full range of precision, it's
4305 * better to call datetime_from_timet_and_us provided you have a way
4306 * to get that much precision (e.g., C time() isn't good enough).
4307 */
4308static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004309datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004310 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004312 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004313 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004314
Victor Stinnere4a994d2015-03-30 01:10:14 +02004315 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004316 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004317 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004318
Victor Stinner21f58932012-03-14 00:15:40 +01004319 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004320}
4321
4322/* Internal helper.
4323 * Build most accurate possible datetime for current time. Pass localtime or
4324 * gmtime for f as appropriate.
4325 */
4326static PyObject *
4327datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4328{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004329 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004330 time_t secs;
4331 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004332
Victor Stinner1e2b6882015-09-18 13:23:02 +02004333 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004334 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004335 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004336
Victor Stinner1e2b6882015-09-18 13:23:02 +02004337 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004338}
4339
Larry Hastings61272b72014-01-07 12:41:53 -08004340/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004341
4342@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004343datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004344
4345 tz: object = None
4346 Timezone object.
4347
4348Returns new datetime object representing current time local to tz.
4349
4350If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004351[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004352
Larry Hastings31826802013-10-19 00:09:25 -07004353static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004354datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004355/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004356{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004357 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004358
Larry Hastings31826802013-10-19 00:09:25 -07004359 /* Return best possible local time -- this isn't constrained by the
4360 * precision of a timestamp.
4361 */
4362 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004363 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004364
Larry Hastings5c661892014-01-24 06:17:25 -08004365 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004366 tz == Py_None ? _PyTime_localtime :
4367 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004368 tz);
4369 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004370 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004371 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004372 }
4373 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004374}
4375
Tim Petersa9bc1682003-01-11 03:39:11 +00004376/* Return best possible UTC time -- this isn't constrained by the
4377 * precision of a timestamp.
4378 */
4379static PyObject *
4380datetime_utcnow(PyObject *cls, PyObject *dummy)
4381{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004382 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004383}
4384
Tim Peters2a799bf2002-12-16 20:18:38 +00004385/* Return new local datetime from timestamp (Python timestamp -- a double). */
4386static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004387datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004389 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004390 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004391 PyObject *tzinfo = Py_None;
4392 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004393
Victor Stinner5d272cc2012-03-13 13:35:55 +01004394 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004395 keywords, &timestamp, &tzinfo))
4396 return NULL;
4397 if (check_tzinfo_subclass(tzinfo) < 0)
4398 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004400 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004401 tzinfo == Py_None ? _PyTime_localtime :
4402 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004403 timestamp,
4404 tzinfo);
4405 if (self != NULL && tzinfo != Py_None) {
4406 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004407 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004408 }
4409 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004410}
4411
Tim Petersa9bc1682003-01-11 03:39:11 +00004412/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4413static PyObject *
4414datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4415{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004416 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004417 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004418
Victor Stinner5d272cc2012-03-13 13:35:55 +01004419 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004420 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004421 Py_None);
4422 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004423}
4424
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004425/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004426static PyObject *
4427datetime_strptime(PyObject *cls, PyObject *args)
4428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004429 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004430 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004431 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004432
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004433 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004434 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004435
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004436 if (module == NULL) {
4437 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004438 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004439 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004440 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004441 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4442 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004443}
4444
Tim Petersa9bc1682003-01-11 03:39:11 +00004445/* Return new datetime from date/datetime and time arguments. */
4446static PyObject *
4447datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4448{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004449 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004450 PyObject *date;
4451 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004452 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004453 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004454
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004455 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004456 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004457 &PyDateTime_TimeType, &time, &tzinfo)) {
4458 if (tzinfo == NULL) {
4459 if (HASTZINFO(time))
4460 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4461 else
4462 tzinfo = Py_None;
4463 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004464 result = PyObject_CallFunction(cls, "iiiiiiiO",
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004465 GET_YEAR(date),
4466 GET_MONTH(date),
4467 GET_DAY(date),
4468 TIME_GET_HOUR(time),
4469 TIME_GET_MINUTE(time),
4470 TIME_GET_SECOND(time),
4471 TIME_GET_MICROSECOND(time),
4472 tzinfo);
4473 if (result)
4474 DATE_SET_FOLD(result, TIME_GET_FOLD(time));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004475 }
4476 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004477}
Tim Peters2a799bf2002-12-16 20:18:38 +00004478
4479/*
4480 * Destructor.
4481 */
4482
4483static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004484datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004486 if (HASTZINFO(self)) {
4487 Py_XDECREF(self->tzinfo);
4488 }
4489 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004490}
4491
4492/*
4493 * Indirect access to tzinfo methods.
4494 */
4495
Tim Peters2a799bf2002-12-16 20:18:38 +00004496/* These are all METH_NOARGS, so don't need to check the arglist. */
4497static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004498datetime_utcoffset(PyObject *self, PyObject *unused) {
4499 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004500}
4501
4502static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004503datetime_dst(PyObject *self, PyObject *unused) {
4504 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004505}
4506
4507static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004508datetime_tzname(PyObject *self, PyObject *unused) {
4509 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004510}
4511
4512/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004513 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004514 */
4515
Tim Petersa9bc1682003-01-11 03:39:11 +00004516/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4517 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004518 */
4519static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004520add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004521 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004523 /* Note that the C-level additions can't overflow, because of
4524 * invariant bounds on the member values.
4525 */
4526 int year = GET_YEAR(date);
4527 int month = GET_MONTH(date);
4528 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4529 int hour = DATE_GET_HOUR(date);
4530 int minute = DATE_GET_MINUTE(date);
4531 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4532 int microsecond = DATE_GET_MICROSECOND(date) +
4533 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004535 assert(factor == 1 || factor == -1);
4536 if (normalize_datetime(&year, &month, &day,
Victor Stinnerb67f0962017-02-10 10:34:02 +01004537 &hour, &minute, &second, &microsecond) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004538 return NULL;
Victor Stinnerb67f0962017-02-10 10:34:02 +01004539 }
4540
4541 return new_datetime(year, month, day,
4542 hour, minute, second, microsecond,
4543 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004544}
4545
4546static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004547datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004549 if (PyDateTime_Check(left)) {
4550 /* datetime + ??? */
4551 if (PyDelta_Check(right))
4552 /* datetime + delta */
4553 return add_datetime_timedelta(
4554 (PyDateTime_DateTime *)left,
4555 (PyDateTime_Delta *)right,
4556 1);
4557 }
4558 else if (PyDelta_Check(left)) {
4559 /* delta + datetime */
4560 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4561 (PyDateTime_Delta *) left,
4562 1);
4563 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004564 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004565}
4566
4567static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004568datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004569{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004570 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004572 if (PyDateTime_Check(left)) {
4573 /* datetime - ??? */
4574 if (PyDateTime_Check(right)) {
4575 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004576 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004577 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004578
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004579 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4580 offset2 = offset1 = Py_None;
4581 Py_INCREF(offset1);
4582 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004583 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004584 else {
4585 offset1 = datetime_utcoffset(left, NULL);
4586 if (offset1 == NULL)
4587 return NULL;
4588 offset2 = datetime_utcoffset(right, NULL);
4589 if (offset2 == NULL) {
4590 Py_DECREF(offset1);
4591 return NULL;
4592 }
4593 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4594 PyErr_SetString(PyExc_TypeError,
4595 "can't subtract offset-naive and "
4596 "offset-aware datetimes");
4597 Py_DECREF(offset1);
4598 Py_DECREF(offset2);
4599 return NULL;
4600 }
4601 }
4602 if ((offset1 != offset2) &&
4603 delta_cmp(offset1, offset2) != 0) {
4604 offdiff = delta_subtract(offset1, offset2);
4605 if (offdiff == NULL) {
4606 Py_DECREF(offset1);
4607 Py_DECREF(offset2);
4608 return NULL;
4609 }
4610 }
4611 Py_DECREF(offset1);
4612 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004613 delta_d = ymd_to_ord(GET_YEAR(left),
4614 GET_MONTH(left),
4615 GET_DAY(left)) -
4616 ymd_to_ord(GET_YEAR(right),
4617 GET_MONTH(right),
4618 GET_DAY(right));
4619 /* These can't overflow, since the values are
4620 * normalized. At most this gives the number of
4621 * seconds in one day.
4622 */
4623 delta_s = (DATE_GET_HOUR(left) -
4624 DATE_GET_HOUR(right)) * 3600 +
4625 (DATE_GET_MINUTE(left) -
4626 DATE_GET_MINUTE(right)) * 60 +
4627 (DATE_GET_SECOND(left) -
4628 DATE_GET_SECOND(right));
4629 delta_us = DATE_GET_MICROSECOND(left) -
4630 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004632 if (result == NULL)
4633 return NULL;
4634
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004635 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004636 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004637 Py_DECREF(offdiff);
4638 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 }
4640 else if (PyDelta_Check(right)) {
4641 /* datetime - delta */
4642 result = add_datetime_timedelta(
4643 (PyDateTime_DateTime *)left,
4644 (PyDateTime_Delta *)right,
4645 -1);
4646 }
4647 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004649 if (result == Py_NotImplemented)
4650 Py_INCREF(result);
4651 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004652}
4653
4654/* Various ways to turn a datetime into a string. */
4655
4656static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004657datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004658{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004659 const char *type_name = Py_TYPE(self)->tp_name;
4660 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004662 if (DATE_GET_MICROSECOND(self)) {
4663 baserepr = PyUnicode_FromFormat(
4664 "%s(%d, %d, %d, %d, %d, %d, %d)",
4665 type_name,
4666 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4667 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4668 DATE_GET_SECOND(self),
4669 DATE_GET_MICROSECOND(self));
4670 }
4671 else if (DATE_GET_SECOND(self)) {
4672 baserepr = PyUnicode_FromFormat(
4673 "%s(%d, %d, %d, %d, %d, %d)",
4674 type_name,
4675 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4676 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4677 DATE_GET_SECOND(self));
4678 }
4679 else {
4680 baserepr = PyUnicode_FromFormat(
4681 "%s(%d, %d, %d, %d, %d)",
4682 type_name,
4683 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4684 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4685 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004686 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4687 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004688 if (baserepr == NULL || ! HASTZINFO(self))
4689 return baserepr;
4690 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004691}
4692
Tim Petersa9bc1682003-01-11 03:39:11 +00004693static PyObject *
4694datetime_str(PyDateTime_DateTime *self)
4695{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004696 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004697}
Tim Peters2a799bf2002-12-16 20:18:38 +00004698
4699static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004700datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004701{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004702 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004703 char *timespec = NULL;
4704 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004705 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004706 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004707 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004708 static char *specs[][2] = {
4709 {"hours", "%04d-%02d-%02d%c%02d"},
4710 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4711 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4712 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4713 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4714 };
4715 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004716
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004717 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004718 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004719
4720 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4721 if (us == 0) {
4722 /* seconds */
4723 given_spec = 2;
4724 }
4725 else {
4726 /* microseconds */
4727 given_spec = 4;
4728 }
4729 }
4730 else {
4731 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4732 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4733 if (given_spec == 3) {
4734 us = us / 1000;
4735 }
4736 break;
4737 }
4738 }
4739 }
4740
4741 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4742 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4743 return NULL;
4744 }
4745 else {
4746 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004747 GET_YEAR(self), GET_MONTH(self),
4748 GET_DAY(self), (int)sep,
4749 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4750 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004751 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004752
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004753 if (!result || !HASTZINFO(self))
4754 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004756 /* We need to append the UTC offset. */
4757 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4758 (PyObject *)self) < 0) {
4759 Py_DECREF(result);
4760 return NULL;
4761 }
4762 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4763 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004764}
4765
Tim Petersa9bc1682003-01-11 03:39:11 +00004766static PyObject *
4767datetime_ctime(PyDateTime_DateTime *self)
4768{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004769 return format_ctime((PyDateTime_Date *)self,
4770 DATE_GET_HOUR(self),
4771 DATE_GET_MINUTE(self),
4772 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004773}
4774
Tim Peters2a799bf2002-12-16 20:18:38 +00004775/* Miscellaneous methods. */
4776
Tim Petersa9bc1682003-01-11 03:39:11 +00004777static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004778flip_fold(PyObject *dt)
4779{
4780 return new_datetime_ex2(GET_YEAR(dt),
4781 GET_MONTH(dt),
4782 GET_DAY(dt),
4783 DATE_GET_HOUR(dt),
4784 DATE_GET_MINUTE(dt),
4785 DATE_GET_SECOND(dt),
4786 DATE_GET_MICROSECOND(dt),
4787 HASTZINFO(dt) ?
4788 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4789 !DATE_GET_FOLD(dt),
4790 Py_TYPE(dt));
4791}
4792
4793static PyObject *
4794get_flip_fold_offset(PyObject *dt)
4795{
4796 PyObject *result, *flip_dt;
4797
4798 flip_dt = flip_fold(dt);
4799 if (flip_dt == NULL)
4800 return NULL;
4801 result = datetime_utcoffset(flip_dt, NULL);
4802 Py_DECREF(flip_dt);
4803 return result;
4804}
4805
4806/* PEP 495 exception: Whenever one or both of the operands in
4807 * inter-zone comparison is such that its utcoffset() depends
4808 * on the value of its fold fold attribute, the result is False.
4809 *
4810 * Return 1 if exception applies, 0 if not, and -1 on error.
4811 */
4812static int
4813pep495_eq_exception(PyObject *self, PyObject *other,
4814 PyObject *offset_self, PyObject *offset_other)
4815{
4816 int result = 0;
4817 PyObject *flip_offset;
4818
4819 flip_offset = get_flip_fold_offset(self);
4820 if (flip_offset == NULL)
4821 return -1;
4822 if (flip_offset != offset_self &&
4823 delta_cmp(flip_offset, offset_self))
4824 {
4825 result = 1;
4826 goto done;
4827 }
4828 Py_DECREF(flip_offset);
4829
4830 flip_offset = get_flip_fold_offset(other);
4831 if (flip_offset == NULL)
4832 return -1;
4833 if (flip_offset != offset_other &&
4834 delta_cmp(flip_offset, offset_other))
4835 result = 1;
4836 done:
4837 Py_DECREF(flip_offset);
4838 return result;
4839}
4840
4841static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004842datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004843{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004844 PyObject *result = NULL;
4845 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004846 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004848 if (! PyDateTime_Check(other)) {
4849 if (PyDate_Check(other)) {
4850 /* Prevent invocation of date_richcompare. We want to
4851 return NotImplemented here to give the other object
4852 a chance. But since DateTime is a subclass of
4853 Date, if the other object is a Date, it would
4854 compute an ordering based on the date part alone,
4855 and we don't want that. So force unequal or
4856 uncomparable here in that case. */
4857 if (op == Py_EQ)
4858 Py_RETURN_FALSE;
4859 if (op == Py_NE)
4860 Py_RETURN_TRUE;
4861 return cmperror(self, other);
4862 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004863 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004864 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004865
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004866 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004867 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4868 ((PyDateTime_DateTime *)other)->data,
4869 _PyDateTime_DATETIME_DATASIZE);
4870 return diff_to_bool(diff, op);
4871 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004872 offset1 = datetime_utcoffset(self, NULL);
4873 if (offset1 == NULL)
4874 return NULL;
4875 offset2 = datetime_utcoffset(other, NULL);
4876 if (offset2 == NULL)
4877 goto done;
4878 /* If they're both naive, or both aware and have the same offsets,
4879 * we get off cheap. Note that if they're both naive, offset1 ==
4880 * offset2 == Py_None at this point.
4881 */
4882 if ((offset1 == offset2) ||
4883 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4884 delta_cmp(offset1, offset2) == 0)) {
4885 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4886 ((PyDateTime_DateTime *)other)->data,
4887 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004888 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4889 int ex = pep495_eq_exception(self, other, offset1, offset2);
4890 if (ex == -1)
4891 goto done;
4892 if (ex)
4893 diff = 1;
4894 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004895 result = diff_to_bool(diff, op);
4896 }
4897 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004898 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004899
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004900 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004901 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4902 other);
4903 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004904 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004905 diff = GET_TD_DAYS(delta);
4906 if (diff == 0)
4907 diff = GET_TD_SECONDS(delta) |
4908 GET_TD_MICROSECONDS(delta);
4909 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004910 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4911 int ex = pep495_eq_exception(self, other, offset1, offset2);
4912 if (ex == -1)
4913 goto done;
4914 if (ex)
4915 diff = 1;
4916 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004917 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004918 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004919 else if (op == Py_EQ) {
4920 result = Py_False;
4921 Py_INCREF(result);
4922 }
4923 else if (op == Py_NE) {
4924 result = Py_True;
4925 Py_INCREF(result);
4926 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004927 else {
4928 PyErr_SetString(PyExc_TypeError,
4929 "can't compare offset-naive and "
4930 "offset-aware datetimes");
4931 }
4932 done:
4933 Py_DECREF(offset1);
4934 Py_XDECREF(offset2);
4935 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004936}
4937
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004938static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004939datetime_hash(PyDateTime_DateTime *self)
4940{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004941 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004942 PyObject *offset, *self0;
4943 if (DATE_GET_FOLD(self)) {
4944 self0 = new_datetime_ex2(GET_YEAR(self),
4945 GET_MONTH(self),
4946 GET_DAY(self),
4947 DATE_GET_HOUR(self),
4948 DATE_GET_MINUTE(self),
4949 DATE_GET_SECOND(self),
4950 DATE_GET_MICROSECOND(self),
4951 HASTZINFO(self) ? self->tzinfo : Py_None,
4952 0, Py_TYPE(self));
4953 if (self0 == NULL)
4954 return -1;
4955 }
4956 else {
4957 self0 = (PyObject *)self;
4958 Py_INCREF(self0);
4959 }
4960 offset = datetime_utcoffset(self0, NULL);
4961 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004962
4963 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004964 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004966 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004967 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004968 self->hashcode = generic_hash(
4969 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004970 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004971 PyObject *temp1, *temp2;
4972 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004974 assert(HASTZINFO(self));
4975 days = ymd_to_ord(GET_YEAR(self),
4976 GET_MONTH(self),
4977 GET_DAY(self));
4978 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004979 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004980 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004981 temp1 = new_delta(days, seconds,
4982 DATE_GET_MICROSECOND(self),
4983 1);
4984 if (temp1 == NULL) {
4985 Py_DECREF(offset);
4986 return -1;
4987 }
4988 temp2 = delta_subtract(temp1, offset);
4989 Py_DECREF(temp1);
4990 if (temp2 == NULL) {
4991 Py_DECREF(offset);
4992 return -1;
4993 }
4994 self->hashcode = PyObject_Hash(temp2);
4995 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004996 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004997 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004998 }
4999 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00005000}
Tim Peters2a799bf2002-12-16 20:18:38 +00005001
5002static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005003datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00005004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005005 PyObject *clone;
5006 PyObject *tuple;
5007 int y = GET_YEAR(self);
5008 int m = GET_MONTH(self);
5009 int d = GET_DAY(self);
5010 int hh = DATE_GET_HOUR(self);
5011 int mm = DATE_GET_MINUTE(self);
5012 int ss = DATE_GET_SECOND(self);
5013 int us = DATE_GET_MICROSECOND(self);
5014 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005015 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005016
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005017 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005018 datetime_kws,
5019 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005020 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005021 return NULL;
5022 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5023 if (tuple == NULL)
5024 return NULL;
5025 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005026
5027 if (clone != NULL) {
5028 if (fold != 0 && fold != 1) {
5029 PyErr_SetString(PyExc_ValueError,
5030 "fold must be either 0 or 1");
5031 return NULL;
5032 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005033 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005034 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 Py_DECREF(tuple);
5036 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005037}
5038
5039static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005040local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005041{
5042 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005043 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005044 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005045 PyObject *nameo = NULL;
5046 const char *zone = NULL;
5047
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005048 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005049 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005050#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005051 zone = local_time_tm.tm_zone;
5052 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005053#else /* HAVE_STRUCT_TM_TM_ZONE */
5054 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005055 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005056 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005057 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005058 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005059 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005060 local_time = new_datetime(local_time_tm.tm_year + 1900,
5061 local_time_tm.tm_mon + 1,
5062 local_time_tm.tm_mday,
5063 local_time_tm.tm_hour,
5064 local_time_tm.tm_min,
5065 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005066 if (local_time == NULL) {
5067 return NULL;
5068 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005069 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005070 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005071 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5072 utc_time_tm.tm_mon + 1,
5073 utc_time_tm.tm_mday,
5074 utc_time_tm.tm_hour,
5075 utc_time_tm.tm_min,
5076 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005077 if (utc_time == NULL) {
5078 Py_DECREF(local_time);
5079 return NULL;
5080 }
5081 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005082 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005083 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005084 }
5085#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005086 if (delta == NULL) {
5087 return NULL;
5088 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005089 if (zone != NULL) {
5090 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5091 if (nameo == NULL)
5092 goto error;
5093 }
5094 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005095 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005096 error:
5097 Py_DECREF(delta);
5098 return result;
5099}
5100
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005101static PyObject *
5102local_timezone(PyDateTime_DateTime *utc_time)
5103{
5104 time_t timestamp;
5105 PyObject *delta;
5106 PyObject *one_second;
5107 PyObject *seconds;
5108
5109 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5110 if (delta == NULL)
5111 return NULL;
5112 one_second = new_delta(0, 1, 0, 0);
5113 if (one_second == NULL) {
5114 Py_DECREF(delta);
5115 return NULL;
5116 }
5117 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5118 (PyDateTime_Delta *)one_second);
5119 Py_DECREF(one_second);
5120 Py_DECREF(delta);
5121 if (seconds == NULL)
5122 return NULL;
5123 timestamp = _PyLong_AsTime_t(seconds);
5124 Py_DECREF(seconds);
5125 if (timestamp == -1 && PyErr_Occurred())
5126 return NULL;
5127 return local_timezone_from_timestamp(timestamp);
5128}
5129
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005130static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005131local_to_seconds(int year, int month, int day,
5132 int hour, int minute, int second, int fold);
5133
5134static PyObject *
5135local_timezone_from_local(PyDateTime_DateTime *local_dt)
5136{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005137 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005138 time_t timestamp;
5139 seconds = local_to_seconds(GET_YEAR(local_dt),
5140 GET_MONTH(local_dt),
5141 GET_DAY(local_dt),
5142 DATE_GET_HOUR(local_dt),
5143 DATE_GET_MINUTE(local_dt),
5144 DATE_GET_SECOND(local_dt),
5145 DATE_GET_FOLD(local_dt));
5146 if (seconds == -1)
5147 return NULL;
5148 /* XXX: add bounds check */
5149 timestamp = seconds - epoch;
5150 return local_timezone_from_timestamp(timestamp);
5151}
5152
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005153static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005154datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005155{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005156 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005157 PyObject *offset;
5158 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005159 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005160 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005161 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005162
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005163 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005164 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005165 return NULL;
5166
5167 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005168 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005169
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005170 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5171 self_tzinfo = local_timezone_from_local(self);
5172 if (self_tzinfo == NULL)
5173 return NULL;
5174 } else {
5175 self_tzinfo = self->tzinfo;
5176 Py_INCREF(self_tzinfo);
5177 }
Tim Peters521fc152002-12-31 17:36:56 +00005178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005179 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005180 if (self_tzinfo == tzinfo) {
5181 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005182 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005183 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005184 }
Tim Peters521fc152002-12-31 17:36:56 +00005185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005186 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005187 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5188 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005189 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005190 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005191 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005192 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5193 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005194 Py_DECREF(offset);
5195 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005196 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005197
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005198 /* Make sure result is aware and UTC. */
5199 if (!HASTZINFO(result)) {
5200 temp = (PyObject *)result;
5201 result = (PyDateTime_DateTime *)
5202 new_datetime_ex2(GET_YEAR(result),
5203 GET_MONTH(result),
5204 GET_DAY(result),
5205 DATE_GET_HOUR(result),
5206 DATE_GET_MINUTE(result),
5207 DATE_GET_SECOND(result),
5208 DATE_GET_MICROSECOND(result),
5209 PyDateTime_TimeZone_UTC,
5210 DATE_GET_FOLD(result),
5211 Py_TYPE(result));
5212 Py_DECREF(temp);
5213 if (result == NULL)
5214 return NULL;
5215 }
5216 else {
5217 /* Result is already aware - just replace tzinfo. */
5218 temp = result->tzinfo;
5219 result->tzinfo = PyDateTime_TimeZone_UTC;
5220 Py_INCREF(result->tzinfo);
5221 Py_DECREF(temp);
5222 }
5223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005224 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005225 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005226 if (tzinfo == Py_None) {
5227 tzinfo = local_timezone(result);
5228 if (tzinfo == NULL) {
5229 Py_DECREF(result);
5230 return NULL;
5231 }
5232 }
5233 else
5234 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005235 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005236 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005237
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005238 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005239 result = (PyDateTime_DateTime *)
5240 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005241 Py_DECREF(temp);
5242
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005243 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005244}
5245
5246static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005247datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005248{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005249 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005251 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005252 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005253
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005254 dst = call_dst(self->tzinfo, (PyObject *)self);
5255 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005256 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005257
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005258 if (dst != Py_None)
5259 dstflag = delta_bool((PyDateTime_Delta *)dst);
5260 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005261 }
5262 return build_struct_time(GET_YEAR(self),
5263 GET_MONTH(self),
5264 GET_DAY(self),
5265 DATE_GET_HOUR(self),
5266 DATE_GET_MINUTE(self),
5267 DATE_GET_SECOND(self),
5268 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005269}
5270
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005271static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005272local_to_seconds(int year, int month, int day,
5273 int hour, int minute, int second, int fold)
5274{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005275 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005276 t = utc_to_seconds(year, month, day, hour, minute, second);
5277 /* Our goal is to solve t = local(u) for u. */
5278 lt = local(t);
5279 if (lt == -1)
5280 return -1;
5281 a = lt - t;
5282 u1 = t - a;
5283 t1 = local(u1);
5284 if (t1 == -1)
5285 return -1;
5286 if (t1 == t) {
5287 /* We found one solution, but it may not be the one we need.
5288 * Look for an earlier solution (if `fold` is 0), or a
5289 * later one (if `fold` is 1). */
5290 if (fold)
5291 u2 = u1 + max_fold_seconds;
5292 else
5293 u2 = u1 - max_fold_seconds;
5294 lt = local(u2);
5295 if (lt == -1)
5296 return -1;
5297 b = lt - u2;
5298 if (a == b)
5299 return u1;
5300 }
5301 else {
5302 b = t1 - u1;
5303 assert(a != b);
5304 }
5305 u2 = t - b;
5306 t2 = local(u2);
5307 if (t2 == -1)
5308 return -1;
5309 if (t2 == t)
5310 return u2;
5311 if (t1 == t)
5312 return u1;
5313 /* We have found both offsets a and b, but neither t - a nor t - b is
5314 * a solution. This means t is in the gap. */
5315 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5316}
5317
5318/* date(1970,1,1).toordinal() == 719163 */
5319#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5320
Tim Peters2a799bf2002-12-16 20:18:38 +00005321static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005322datetime_timestamp(PyDateTime_DateTime *self)
5323{
5324 PyObject *result;
5325
5326 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5327 PyObject *delta;
5328 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5329 if (delta == NULL)
5330 return NULL;
5331 result = delta_total_seconds(delta);
5332 Py_DECREF(delta);
5333 }
5334 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005335 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005336 seconds = local_to_seconds(GET_YEAR(self),
5337 GET_MONTH(self),
5338 GET_DAY(self),
5339 DATE_GET_HOUR(self),
5340 DATE_GET_MINUTE(self),
5341 DATE_GET_SECOND(self),
5342 DATE_GET_FOLD(self));
5343 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005344 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005345 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5346 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005347 }
5348 return result;
5349}
5350
5351static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005352datetime_getdate(PyDateTime_DateTime *self)
5353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005354 return new_date(GET_YEAR(self),
5355 GET_MONTH(self),
5356 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005357}
5358
5359static PyObject *
5360datetime_gettime(PyDateTime_DateTime *self)
5361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005362 return new_time(DATE_GET_HOUR(self),
5363 DATE_GET_MINUTE(self),
5364 DATE_GET_SECOND(self),
5365 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005366 Py_None,
5367 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005368}
5369
5370static PyObject *
5371datetime_gettimetz(PyDateTime_DateTime *self)
5372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005373 return new_time(DATE_GET_HOUR(self),
5374 DATE_GET_MINUTE(self),
5375 DATE_GET_SECOND(self),
5376 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005377 GET_DT_TZINFO(self),
5378 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005379}
5380
5381static PyObject *
5382datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005383{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005384 int y, m, d, hh, mm, ss;
5385 PyObject *tzinfo;
5386 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005387
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005388 tzinfo = GET_DT_TZINFO(self);
5389 if (tzinfo == Py_None) {
5390 utcself = self;
5391 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005392 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005393 else {
5394 PyObject *offset;
5395 offset = call_utcoffset(tzinfo, (PyObject *)self);
5396 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005397 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005398 if (offset == Py_None) {
5399 Py_DECREF(offset);
5400 utcself = self;
5401 Py_INCREF(utcself);
5402 }
5403 else {
5404 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5405 (PyDateTime_Delta *)offset, -1);
5406 Py_DECREF(offset);
5407 if (utcself == NULL)
5408 return NULL;
5409 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005410 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005411 y = GET_YEAR(utcself);
5412 m = GET_MONTH(utcself);
5413 d = GET_DAY(utcself);
5414 hh = DATE_GET_HOUR(utcself);
5415 mm = DATE_GET_MINUTE(utcself);
5416 ss = DATE_GET_SECOND(utcself);
5417
5418 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005419 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005420}
5421
Tim Peters371935f2003-02-01 01:52:50 +00005422/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005423
Tim Petersa9bc1682003-01-11 03:39:11 +00005424/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005425 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5426 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005427 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005428 */
5429static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005430datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005432 PyObject *basestate;
5433 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005435 basestate = PyBytes_FromStringAndSize((char *)self->data,
5436 _PyDateTime_DATETIME_DATASIZE);
5437 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005438 if (proto > 3 && DATE_GET_FOLD(self))
5439 /* Set the first bit of the third byte */
5440 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005441 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5442 result = PyTuple_Pack(1, basestate);
5443 else
5444 result = PyTuple_Pack(2, basestate, self->tzinfo);
5445 Py_DECREF(basestate);
5446 }
5447 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005448}
5449
5450static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005451datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005452{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005453 int proto;
5454 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005455 return NULL;
5456
5457 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005458}
5459
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005460static PyObject *
5461datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5462{
5463 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5464}
5465
Tim Petersa9bc1682003-01-11 03:39:11 +00005466static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005468 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005469
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005470 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005472 {"utcnow", (PyCFunction)datetime_utcnow,
5473 METH_NOARGS | METH_CLASS,
5474 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005476 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5477 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5478 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005480 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5481 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005482 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005484 {"strptime", (PyCFunction)datetime_strptime,
5485 METH_VARARGS | METH_CLASS,
5486 PyDoc_STR("string, format -> new datetime parsed from a string "
5487 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005489 {"combine", (PyCFunction)datetime_combine,
5490 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5491 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005493 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005495 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5496 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005498 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5499 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005501 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5502 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005504 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5505 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005507 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5508 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005509
Alexander Belopolskya4415142012-06-08 12:33:09 -04005510 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5511 PyDoc_STR("Return POSIX timestamp as float.")},
5512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005513 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5514 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005516 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5517 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005518 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005519 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005520 "defaults to 'T'.\n"
5521 "timespec specifies what components of the time to include"
5522 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5523 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005525 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5526 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005528 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5529 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005531 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5532 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005534 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5535 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005537 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5538 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005539
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005540 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005541 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005542
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005543 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5544 PyDoc_STR("__reduce__() -> (cls, state)")},
5545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005546 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005547};
5548
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005549static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005550PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5551\n\
5552The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005553instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005554
Tim Petersa9bc1682003-01-11 03:39:11 +00005555static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005556 datetime_add, /* nb_add */
5557 datetime_subtract, /* nb_subtract */
5558 0, /* nb_multiply */
5559 0, /* nb_remainder */
5560 0, /* nb_divmod */
5561 0, /* nb_power */
5562 0, /* nb_negative */
5563 0, /* nb_positive */
5564 0, /* nb_absolute */
5565 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005566};
5567
Neal Norwitz227b5332006-03-22 09:28:35 +00005568static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005569 PyVarObject_HEAD_INIT(NULL, 0)
5570 "datetime.datetime", /* tp_name */
5571 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5572 0, /* tp_itemsize */
5573 (destructor)datetime_dealloc, /* tp_dealloc */
5574 0, /* tp_print */
5575 0, /* tp_getattr */
5576 0, /* tp_setattr */
5577 0, /* tp_reserved */
5578 (reprfunc)datetime_repr, /* tp_repr */
5579 &datetime_as_number, /* tp_as_number */
5580 0, /* tp_as_sequence */
5581 0, /* tp_as_mapping */
5582 (hashfunc)datetime_hash, /* tp_hash */
5583 0, /* tp_call */
5584 (reprfunc)datetime_str, /* tp_str */
5585 PyObject_GenericGetAttr, /* tp_getattro */
5586 0, /* tp_setattro */
5587 0, /* tp_as_buffer */
5588 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5589 datetime_doc, /* tp_doc */
5590 0, /* tp_traverse */
5591 0, /* tp_clear */
5592 datetime_richcompare, /* tp_richcompare */
5593 0, /* tp_weaklistoffset */
5594 0, /* tp_iter */
5595 0, /* tp_iternext */
5596 datetime_methods, /* tp_methods */
5597 0, /* tp_members */
5598 datetime_getset, /* tp_getset */
5599 &PyDateTime_DateType, /* tp_base */
5600 0, /* tp_dict */
5601 0, /* tp_descr_get */
5602 0, /* tp_descr_set */
5603 0, /* tp_dictoffset */
5604 0, /* tp_init */
5605 datetime_alloc, /* tp_alloc */
5606 datetime_new, /* tp_new */
5607 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005608};
5609
5610/* ---------------------------------------------------------------------------
5611 * Module methods and initialization.
5612 */
5613
5614static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005615 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005616};
5617
Tim Peters9ddf40b2004-06-20 22:41:32 +00005618/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5619 * datetime.h.
5620 */
5621static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005622 &PyDateTime_DateType,
5623 &PyDateTime_DateTimeType,
5624 &PyDateTime_TimeType,
5625 &PyDateTime_DeltaType,
5626 &PyDateTime_TZInfoType,
5627 new_date_ex,
5628 new_datetime_ex,
5629 new_time_ex,
5630 new_delta_ex,
5631 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005632 date_fromtimestamp,
5633 new_datetime_ex2,
5634 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00005635};
5636
5637
Martin v. Löwis1a214512008-06-11 05:26:20 +00005638
5639static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005640 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005641 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005642 "Fast implementation of the datetime type.",
5643 -1,
5644 module_methods,
5645 NULL,
5646 NULL,
5647 NULL,
5648 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005649};
5650
Tim Peters2a799bf2002-12-16 20:18:38 +00005651PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005652PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005654 PyObject *m; /* a module object */
5655 PyObject *d; /* its dict */
5656 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005657 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005659 m = PyModule_Create(&datetimemodule);
5660 if (m == NULL)
5661 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005663 if (PyType_Ready(&PyDateTime_DateType) < 0)
5664 return NULL;
5665 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5666 return NULL;
5667 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5668 return NULL;
5669 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5670 return NULL;
5671 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5672 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005673 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5674 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005676 /* timedelta values */
5677 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005679 x = new_delta(0, 0, 1, 0);
5680 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5681 return NULL;
5682 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005684 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5685 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5686 return NULL;
5687 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005689 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5690 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5691 return NULL;
5692 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005694 /* date values */
5695 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005697 x = new_date(1, 1, 1);
5698 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5699 return NULL;
5700 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005702 x = new_date(MAXYEAR, 12, 31);
5703 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5704 return NULL;
5705 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005707 x = new_delta(1, 0, 0, 0);
5708 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5709 return NULL;
5710 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005712 /* time values */
5713 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005714
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005715 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005716 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5717 return NULL;
5718 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005719
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005720 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005721 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5722 return NULL;
5723 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005725 x = new_delta(0, 0, 1, 0);
5726 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5727 return NULL;
5728 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005730 /* datetime values */
5731 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005732
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005733 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005734 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5735 return NULL;
5736 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005737
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005738 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005739 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5740 return NULL;
5741 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005743 x = new_delta(0, 0, 1, 0);
5744 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5745 return NULL;
5746 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005747
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005748 /* timezone values */
5749 d = PyDateTime_TimeZoneType.tp_dict;
5750
5751 delta = new_delta(0, 0, 0, 0);
5752 if (delta == NULL)
5753 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005754 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005755 Py_DECREF(delta);
5756 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5757 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005758 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005759
5760 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5761 if (delta == NULL)
5762 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005763 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005764 Py_DECREF(delta);
5765 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5766 return NULL;
5767 Py_DECREF(x);
5768
5769 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5770 if (delta == NULL)
5771 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005772 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005773 Py_DECREF(delta);
5774 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5775 return NULL;
5776 Py_DECREF(x);
5777
Alexander Belopolskya4415142012-06-08 12:33:09 -04005778 /* Epoch */
5779 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005780 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005781 if (PyDateTime_Epoch == NULL)
5782 return NULL;
5783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005784 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005785 PyModule_AddIntMacro(m, MINYEAR);
5786 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005788 Py_INCREF(&PyDateTime_DateType);
5789 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005791 Py_INCREF(&PyDateTime_DateTimeType);
5792 PyModule_AddObject(m, "datetime",
5793 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005795 Py_INCREF(&PyDateTime_TimeType);
5796 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005798 Py_INCREF(&PyDateTime_DeltaType);
5799 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005801 Py_INCREF(&PyDateTime_TZInfoType);
5802 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005803
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005804 Py_INCREF(&PyDateTime_TimeZoneType);
5805 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005807 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5808 if (x == NULL)
5809 return NULL;
5810 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005812 /* A 4-year cycle has an extra leap day over what we'd get from
5813 * pasting together 4 single years.
5814 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005815 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005816 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005817
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005818 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5819 * get from pasting together 4 100-year cycles.
5820 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005821 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005822 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005824 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5825 * pasting together 25 4-year cycles.
5826 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005827 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005828 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005829
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005830 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005831 us_per_ms = PyLong_FromLong(1000);
5832 us_per_second = PyLong_FromLong(1000000);
5833 us_per_minute = PyLong_FromLong(60000000);
5834 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005835 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005836 us_per_minute == NULL || seconds_per_day == NULL)
5837 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005839 /* The rest are too big for 32-bit ints, but even
5840 * us_per_week fits in 40 bits, so doubles should be exact.
5841 */
5842 us_per_hour = PyLong_FromDouble(3600000000.0);
5843 us_per_day = PyLong_FromDouble(86400000000.0);
5844 us_per_week = PyLong_FromDouble(604800000000.0);
5845 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5846 return NULL;
5847 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005848}
Tim Petersf3615152003-01-01 21:51:37 +00005849
5850/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005851Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005852 x.n = x stripped of its timezone -- its naive time.
5853 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005854 return None
Tim Petersf3615152003-01-01 21:51:37 +00005855 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005856 return None
Tim Petersf3615152003-01-01 21:51:37 +00005857 x.s = x's standard offset, x.o - x.d
5858
5859Now some derived rules, where k is a duration (timedelta).
5860
58611. x.o = x.s + x.d
5862 This follows from the definition of x.s.
5863
Tim Petersc5dc4da2003-01-02 17:55:03 +000058642. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005865 This is actually a requirement, an assumption we need to make about
5866 sane tzinfo classes.
5867
58683. The naive UTC time corresponding to x is x.n - x.o.
5869 This is again a requirement for a sane tzinfo class.
5870
58714. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005872 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005873
Tim Petersc5dc4da2003-01-02 17:55:03 +000058745. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005875 Again follows from how arithmetic is defined.
5876
Tim Peters8bb5ad22003-01-24 02:44:45 +00005877Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005878(meaning that the various tzinfo methods exist, and don't blow up or return
5879None when called).
5880
Tim Petersa9bc1682003-01-11 03:39:11 +00005881The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005882x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005883
5884By #3, we want
5885
Tim Peters8bb5ad22003-01-24 02:44:45 +00005886 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005887
5888The algorithm starts by attaching tz to x.n, and calling that y. So
5889x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5890becomes true; in effect, we want to solve [2] for k:
5891
Tim Peters8bb5ad22003-01-24 02:44:45 +00005892 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005893
5894By #1, this is the same as
5895
Tim Peters8bb5ad22003-01-24 02:44:45 +00005896 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005897
5898By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5899Substituting that into [3],
5900
Tim Peters8bb5ad22003-01-24 02:44:45 +00005901 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5902 k - (y+k).s - (y+k).d = 0; rearranging,
5903 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5904 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005905
Tim Peters8bb5ad22003-01-24 02:44:45 +00005906On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5907approximate k by ignoring the (y+k).d term at first. Note that k can't be
5908very large, since all offset-returning methods return a duration of magnitude
5909less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5910be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005911
5912In any case, the new value is
5913
Tim Peters8bb5ad22003-01-24 02:44:45 +00005914 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005915
Tim Peters8bb5ad22003-01-24 02:44:45 +00005916It's helpful to step back at look at [4] from a higher level: it's simply
5917mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005918
5919At this point, if
5920
Tim Peters8bb5ad22003-01-24 02:44:45 +00005921 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005922
5923we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005924at the start of daylight time. Picture US Eastern for concreteness. The wall
5925time 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 +00005926sense then. The docs ask that an Eastern tzinfo class consider such a time to
5927be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5928on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005929the only spelling that makes sense on the local wall clock.
5930
Tim Petersc5dc4da2003-01-02 17:55:03 +00005931In fact, if [5] holds at this point, we do have the standard-time spelling,
5932but that takes a bit of proof. We first prove a stronger result. What's the
5933difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005934
Tim Peters8bb5ad22003-01-24 02:44:45 +00005935 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005936
Tim Petersc5dc4da2003-01-02 17:55:03 +00005937Now
5938 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005939 (y + y.s).n = by #5
5940 y.n + y.s = since y.n = x.n
5941 x.n + y.s = since z and y are have the same tzinfo member,
5942 y.s = z.s by #2
5943 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005944
Tim Petersc5dc4da2003-01-02 17:55:03 +00005945Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005946
Tim Petersc5dc4da2003-01-02 17:55:03 +00005947 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005948 x.n - ((x.n + z.s) - z.o) = expanding
5949 x.n - x.n - z.s + z.o = cancelling
5950 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005951 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005952
Tim Petersc5dc4da2003-01-02 17:55:03 +00005953So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005954
Tim Petersc5dc4da2003-01-02 17:55:03 +00005955If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005956spelling we wanted in the endcase described above. We're done. Contrarily,
5957if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005958
Tim Petersc5dc4da2003-01-02 17:55:03 +00005959If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5960add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005961local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005962
Tim Petersc5dc4da2003-01-02 17:55:03 +00005963Let
Tim Petersf3615152003-01-01 21:51:37 +00005964
Tim Peters4fede1a2003-01-04 00:26:59 +00005965 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005966
Tim Peters4fede1a2003-01-04 00:26:59 +00005967and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005968
Tim Peters8bb5ad22003-01-24 02:44:45 +00005969 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005970
Tim Peters8bb5ad22003-01-24 02:44:45 +00005971If so, we're done. If not, the tzinfo class is insane, according to the
5972assumptions we've made. This also requires a bit of proof. As before, let's
5973compute the difference between the LHS and RHS of [8] (and skipping some of
5974the justifications for the kinds of substitutions we've done several times
5975already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005976
Tim Peters8bb5ad22003-01-24 02:44:45 +00005977 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005978 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5979 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5980 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5981 - z.n + z.n - z.o + z'.o = cancel z.n
5982 - z.o + z'.o = #1 twice
5983 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5984 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005985
5986So 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 +00005987we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5988return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005989
Tim Peters8bb5ad22003-01-24 02:44:45 +00005990How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5991a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5992would have to change the result dst() returns: we start in DST, and moving
5993a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005994
Tim Peters8bb5ad22003-01-24 02:44:45 +00005995There isn't a sane case where this can happen. The closest it gets is at
5996the end of DST, where there's an hour in UTC with no spelling in a hybrid
5997tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5998that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5999UTC) because the docs insist on that, but 0:MM is taken as being in daylight
6000time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6001clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6002standard time. Since that's what the local clock *does*, we want to map both
6003UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006004in local time, but so it goes -- it's the way the local clock works.
6005
Tim Peters8bb5ad22003-01-24 02:44:45 +00006006When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6007so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6008z' = 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 +00006009(correctly) concludes that z' is not UTC-equivalent to x.
6010
6011Because we know z.d said z was in daylight time (else [5] would have held and
6012we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006013and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006014return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6015but the reasoning doesn't depend on the example -- it depends on there being
6016two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006017z' must be in standard time, and is the spelling we want in this case.
6018
6019Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6020concerned (because it takes z' as being in standard time rather than the
6021daylight time we intend here), but returning it gives the real-life "local
6022clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6023tz.
6024
6025When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6026the 1:MM standard time spelling we want.
6027
6028So how can this break? One of the assumptions must be violated. Two
6029possibilities:
6030
60311) [2] effectively says that y.s is invariant across all y belong to a given
6032 time zone. This isn't true if, for political reasons or continental drift,
6033 a region decides to change its base offset from UTC.
6034
60352) There may be versions of "double daylight" time where the tail end of
6036 the analysis gives up a step too early. I haven't thought about that
6037 enough to say.
6038
6039In any case, it's clear that the default fromutc() is strong enough to handle
6040"almost all" time zones: so long as the standard offset is invariant, it
6041doesn't matter if daylight time transition points change from year to year, or
6042if daylight time is skipped in some years; it doesn't matter how large or
6043small dst() may get within its bounds; and it doesn't even matter if some
6044perverse time zone returns a negative dst()). So a breaking case must be
6045pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006046--------------------------------------------------------------------------- */