blob: 1a63a019915543dbcaa5d929cac0763680c5c514 [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 */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040012static struct tm *localtime_r(const time_t *timep, struct tm *result)
13{
14 if (localtime_s(result, timep) == 0)
15 return result;
16 return NULL;
17}
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -040018static struct tm *gmtime_r(const time_t *timep, struct tm *result)
19{
Alexander Belopolskyabd143b2016-09-10 16:08:26 -040020 if (gmtime_s(result, timep) == 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -040021 return result;
22 return NULL;
23}
Victor Stinner09e5cf22015-03-30 00:09:18 +020024#endif
25
Tim Peters9ddf40b2004-06-20 22:41:32 +000026/* Differentiate between building the core module and building extension
27 * modules.
28 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000029#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000030#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000031#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000032#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000033#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000034
Larry Hastings61272b72014-01-07 12:41:53 -080035/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080036module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080037class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Larry Hastings61272b72014-01-07 12:41:53 -080038[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -080039/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080040
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030041#include "clinic/_datetimemodule.c.h"
42
Tim Peters2a799bf2002-12-16 20:18:38 +000043/* We require that C int be at least 32 bits, and use int virtually
44 * everywhere. In just a few cases we use a temp long, where a Python
45 * API returns a C long. In such cases, we have to ensure that the
46 * final result fits in a C int (this can be an issue on 64-bit boxes).
47 */
48#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000049# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000050#endif
51
52#define MINYEAR 1
53#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000054#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000055
56/* Nine decimal digits is easy to communicate, and leaves enough room
57 * so that two delta days can be added w/o fear of overflowing a signed
58 * 32-bit int, and with plenty of room left over to absorb any possible
59 * carries from adding seconds.
60 */
61#define MAX_DELTA_DAYS 999999999
62
63/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064#define GET_YEAR PyDateTime_GET_YEAR
65#define GET_MONTH PyDateTime_GET_MONTH
66#define GET_DAY PyDateTime_GET_DAY
67#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
68#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
69#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
70#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040071#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000072
73/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
75 ((o)->data[1] = ((v) & 0x00ff)))
76#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
77#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000078
79/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
81#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
82#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
83#define DATE_SET_MICROSECOND(o, v) \
84 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
85 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
86 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040087#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000088
89/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
91#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
92#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
93#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040094#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
96#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
97#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
98#define TIME_SET_MICROSECOND(o, v) \
99 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
100 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
101 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400102#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000103
104/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
106#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
107#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109#define SET_TD_DAYS(o, v) ((o)->days = (v))
110#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000111#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
112
Tim Petersa032d2e2003-01-11 00:15:54 +0000113/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
114 * p->hastzinfo.
115 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000116#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
117#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
118 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
119#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
120 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000121/* M is a char or int claiming to be a valid month. The macro is equivalent
122 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000124 */
125#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
126
Tim Peters2a799bf2002-12-16 20:18:38 +0000127/* Forward declarations. */
128static PyTypeObject PyDateTime_DateType;
129static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000130static PyTypeObject PyDateTime_DeltaType;
131static PyTypeObject PyDateTime_TimeType;
132static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000133static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000134
Martin v. Löwise75fc142013-11-07 18:46:53 +0100135_Py_IDENTIFIER(as_integer_ratio);
136_Py_IDENTIFIER(fromutc);
137_Py_IDENTIFIER(isoformat);
138_Py_IDENTIFIER(strftime);
139
Tim Peters2a799bf2002-12-16 20:18:38 +0000140/* ---------------------------------------------------------------------------
141 * Math utilities.
142 */
143
144/* k = i+j overflows iff k differs in sign from both inputs,
145 * iff k^i has sign bit set and k^j has sign bit set,
146 * iff (k^i)&(k^j) has sign bit set.
147 */
148#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000150
151/* Compute Python divmod(x, y), returning the quotient and storing the
152 * remainder into *r. The quotient is the floor of x/y, and that's
153 * the real point of this. C will probably truncate instead (C99
154 * requires truncation; C89 left it implementation-defined).
155 * Simplification: we *require* that y > 0 here. That's appropriate
156 * for all the uses made of it. This simplifies the code and makes
157 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
158 * overflow case).
159 */
160static int
161divmod(int x, int y, int *r)
162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 assert(y > 0);
166 quo = x / y;
167 *r = x - quo * y;
168 if (*r < 0) {
169 --quo;
170 *r += y;
171 }
172 assert(0 <= *r && *r < y);
173 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000174}
175
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000176/* Nearest integer to m / n for integers m and n. Half-integer results
177 * are rounded to even.
178 */
179static PyObject *
180divide_nearest(PyObject *m, PyObject *n)
181{
182 PyObject *result;
183 PyObject *temp;
184
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000185 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000186 if (temp == NULL)
187 return NULL;
188 result = PyTuple_GET_ITEM(temp, 0);
189 Py_INCREF(result);
190 Py_DECREF(temp);
191
192 return result;
193}
194
Tim Peters2a799bf2002-12-16 20:18:38 +0000195/* ---------------------------------------------------------------------------
196 * General calendrical helper functions
197 */
198
199/* For each month ordinal in 1..12, the number of days in that month,
200 * and the number of days before that month in the same year. These
201 * are correct for non-leap years only.
202 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200203static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 0, /* unused; this vector uses 1-based indexing */
205 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000206};
207
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200208static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 0, /* unused; this vector uses 1-based indexing */
210 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000211};
212
213/* year -> 1 if leap year, else 0. */
214static int
215is_leap(int year)
216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 /* Cast year to unsigned. The result is the same either way, but
218 * C can generate faster code for unsigned mod than for signed
219 * mod (especially for % 4 -- a good compiler should just grab
220 * the last 2 bits when the LHS is unsigned).
221 */
222 const unsigned int ayear = (unsigned int)year;
223 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000224}
225
226/* year, month -> number of days in that month in that year */
227static int
228days_in_month(int year, int month)
229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 assert(month >= 1);
231 assert(month <= 12);
232 if (month == 2 && is_leap(year))
233 return 29;
234 else
235 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000236}
237
Martin Panter46f50722016-05-26 05:35:26 +0000238/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000239static int
240days_before_month(int year, int month)
241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 assert(month >= 1);
245 assert(month <= 12);
246 days = _days_before_month[month];
247 if (month > 2 && is_leap(year))
248 ++days;
249 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000250}
251
252/* year -> number of days before January 1st of year. Remember that we
253 * start with year 1, so days_before_year(1) == 0.
254 */
255static int
256days_before_year(int year)
257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 int y = year - 1;
259 /* This is incorrect if year <= 0; we really want the floor
260 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000261 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000263 assert (year >= 1);
264 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000265}
266
267/* Number of days in 4, 100, and 400 year cycles. That these have
268 * the correct values is asserted in the module init function.
269 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270#define DI4Y 1461 /* days_before_year(5); days in 4 years */
271#define DI100Y 36524 /* days_before_year(101); days in 100 years */
272#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000273
274/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
275static void
276ord_to_ymd(int ordinal, int *year, int *month, int *day)
277{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
281 * leap years repeats exactly every 400 years. The basic strategy is
282 * to find the closest 400-year boundary at or before ordinal, then
283 * work with the offset from that boundary to ordinal. Life is much
284 * clearer if we subtract 1 from ordinal first -- then the values
285 * of ordinal at 400-year boundaries are exactly those divisible
286 * by DI400Y:
287 *
288 * D M Y n n-1
289 * -- --- ---- ---------- ----------------
290 * 31 Dec -400 -DI400Y -DI400Y -1
291 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
292 * ...
293 * 30 Dec 000 -1 -2
294 * 31 Dec 000 0 -1
295 * 1 Jan 001 1 0 400-year boundary
296 * 2 Jan 001 2 1
297 * 3 Jan 001 3 2
298 * ...
299 * 31 Dec 400 DI400Y DI400Y -1
300 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
301 */
302 assert(ordinal >= 1);
303 --ordinal;
304 n400 = ordinal / DI400Y;
305 n = ordinal % DI400Y;
306 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 /* Now n is the (non-negative) offset, in days, from January 1 of
309 * year, to the desired date. Now compute how many 100-year cycles
310 * precede n.
311 * Note that it's possible for n100 to equal 4! In that case 4 full
312 * 100-year cycles precede the desired day, which implies the
313 * desired day is December 31 at the end of a 400-year cycle.
314 */
315 n100 = n / DI100Y;
316 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 /* Now compute how many 4-year cycles precede it. */
319 n4 = n / DI4Y;
320 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 /* And now how many single years. Again n1 can be 4, and again
323 * meaning that the desired day is December 31 at the end of the
324 * 4-year cycle.
325 */
326 n1 = n / 365;
327 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 *year += n100 * 100 + n4 * 4 + n1;
330 if (n1 == 4 || n100 == 4) {
331 assert(n == 0);
332 *year -= 1;
333 *month = 12;
334 *day = 31;
335 return;
336 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 /* Now the year is correct, and n is the offset from January 1. We
339 * find the month via an estimate that's either exact or one too
340 * large.
341 */
342 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
343 assert(leapyear == is_leap(*year));
344 *month = (n + 50) >> 5;
345 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
346 if (preceding > n) {
347 /* estimate is too large */
348 *month -= 1;
349 preceding -= days_in_month(*year, *month);
350 }
351 n -= preceding;
352 assert(0 <= n);
353 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000356}
357
358/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
359static int
360ymd_to_ord(int year, int month, int day)
361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000363}
364
365/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
366static int
367weekday(int year, int month, int day)
368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000370}
371
372/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
373 * first calendar week containing a Thursday.
374 */
375static int
376iso_week1_monday(int year)
377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
379 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
380 int first_weekday = (first_day + 6) % 7;
381 /* ordinal of closest Monday at or before 1/1 */
382 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
385 week1_monday += 7;
386 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000387}
388
389/* ---------------------------------------------------------------------------
390 * Range checkers.
391 */
392
393/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
394 * If not, raise OverflowError and return -1.
395 */
396static int
397check_delta_day_range(int days)
398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
400 return 0;
401 PyErr_Format(PyExc_OverflowError,
402 "days=%d; must have magnitude <= %d",
403 days, MAX_DELTA_DAYS);
404 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000405}
406
407/* Check that date arguments are in range. Return 0 if they are. If they
408 * aren't, raise ValueError and return -1.
409 */
410static int
411check_date_args(int year, int month, int day)
412{
413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 if (year < MINYEAR || year > MAXYEAR) {
415 PyErr_SetString(PyExc_ValueError,
416 "year is out of range");
417 return -1;
418 }
419 if (month < 1 || month > 12) {
420 PyErr_SetString(PyExc_ValueError,
421 "month must be in 1..12");
422 return -1;
423 }
424 if (day < 1 || day > days_in_month(year, month)) {
425 PyErr_SetString(PyExc_ValueError,
426 "day is out of range for month");
427 return -1;
428 }
429 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000430}
431
432/* Check that time arguments are in range. Return 0 if they are. If they
433 * aren't, raise ValueError and return -1.
434 */
435static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400436check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000437{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 if (h < 0 || h > 23) {
439 PyErr_SetString(PyExc_ValueError,
440 "hour must be in 0..23");
441 return -1;
442 }
443 if (m < 0 || m > 59) {
444 PyErr_SetString(PyExc_ValueError,
445 "minute must be in 0..59");
446 return -1;
447 }
448 if (s < 0 || s > 59) {
449 PyErr_SetString(PyExc_ValueError,
450 "second must be in 0..59");
451 return -1;
452 }
453 if (us < 0 || us > 999999) {
454 PyErr_SetString(PyExc_ValueError,
455 "microsecond must be in 0..999999");
456 return -1;
457 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400458 if (fold != 0 && fold != 1) {
459 PyErr_SetString(PyExc_ValueError,
460 "fold must be either 0 or 1");
461 return -1;
462 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000464}
465
466/* ---------------------------------------------------------------------------
467 * Normalization utilities.
468 */
469
470/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
471 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
472 * at least factor, enough of *lo is converted into "hi" units so that
473 * 0 <= *lo < factor. The input values must be such that int overflow
474 * is impossible.
475 */
476static void
477normalize_pair(int *hi, int *lo, int factor)
478{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 assert(factor > 0);
480 assert(lo != hi);
481 if (*lo < 0 || *lo >= factor) {
482 const int num_hi = divmod(*lo, factor, lo);
483 const int new_hi = *hi + num_hi;
484 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
485 *hi = new_hi;
486 }
487 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000488}
489
490/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 * 0 <= *s < 24*3600
492 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000493 * The input values must be such that the internals don't overflow.
494 * The way this routine is used, we don't get close.
495 */
496static void
497normalize_d_s_us(int *d, int *s, int *us)
498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 if (*us < 0 || *us >= 1000000) {
500 normalize_pair(s, us, 1000000);
501 /* |s| can't be bigger than about
502 * |original s| + |original us|/1000000 now.
503 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 }
506 if (*s < 0 || *s >= 24*3600) {
507 normalize_pair(d, s, 24*3600);
508 /* |d| can't be bigger than about
509 * |original d| +
510 * (|original s| + |original us|/1000000) / (24*3600) now.
511 */
512 }
513 assert(0 <= *s && *s < 24*3600);
514 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000515}
516
517/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 * 1 <= *m <= 12
519 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000520 * The input values must be such that the internals don't overflow.
521 * The way this routine is used, we don't get close.
522 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000523static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000524normalize_y_m_d(int *y, int *m, int *d)
525{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000527
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000528 /* In actual use, m is always the month component extracted from a
529 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 /* Now only day can be out of bounds (year may also be out of bounds
535 * for a datetime object, but we don't care about that here).
536 * If day is out of bounds, what to do is arguable, but at least the
537 * method here is principled and explainable.
538 */
539 dim = days_in_month(*y, *m);
540 if (*d < 1 || *d > dim) {
541 /* Move day-1 days from the first of the month. First try to
542 * get off cheap if we're only one day out of range
543 * (adjustments for timezone alone can't be worse than that).
544 */
545 if (*d == 0) {
546 --*m;
547 if (*m > 0)
548 *d = days_in_month(*y, *m);
549 else {
550 --*y;
551 *m = 12;
552 *d = 31;
553 }
554 }
555 else if (*d == dim + 1) {
556 /* move forward a day */
557 ++*m;
558 *d = 1;
559 if (*m > 12) {
560 *m = 1;
561 ++*y;
562 }
563 }
564 else {
565 int ordinal = ymd_to_ord(*y, *m, 1) +
566 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000567 if (ordinal < 1 || ordinal > MAXORDINAL) {
568 goto error;
569 } else {
570 ord_to_ymd(ordinal, y, m, d);
571 return 0;
572 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 }
574 }
575 assert(*m > 0);
576 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000577 if (MINYEAR <= *y && *y <= MAXYEAR)
578 return 0;
579 error:
580 PyErr_SetString(PyExc_OverflowError,
581 "date value out of range");
582 return -1;
583
Tim Peters2a799bf2002-12-16 20:18:38 +0000584}
585
586/* Fiddle out-of-bounds months and days so that the result makes some kind
587 * of sense. The parameters are both inputs and outputs. Returns < 0 on
588 * failure, where failure means the adjusted year is out of bounds.
589 */
590static int
591normalize_date(int *year, int *month, int *day)
592{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000593 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000594}
595
596/* Force all the datetime fields into range. The parameters are both
597 * inputs and outputs. Returns < 0 on error.
598 */
599static int
600normalize_datetime(int *year, int *month, int *day,
601 int *hour, int *minute, int *second,
602 int *microsecond)
603{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 normalize_pair(second, microsecond, 1000000);
605 normalize_pair(minute, second, 60);
606 normalize_pair(hour, minute, 60);
607 normalize_pair(day, hour, 24);
608 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000609}
610
611/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000612 * Basic object allocation: tp_alloc implementations. These allocate
613 * Python objects of the right size and type, and do the Python object-
614 * initialization bit. If there's not enough memory, they return NULL after
615 * setting MemoryError. All data members remain uninitialized trash.
616 *
617 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000618 * member is needed. This is ugly, imprecise, and possibly insecure.
619 * tp_basicsize for the time and datetime types is set to the size of the
620 * struct that has room for the tzinfo member, so subclasses in Python will
621 * allocate enough space for a tzinfo member whether or not one is actually
622 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
623 * part is that PyType_GenericAlloc() (which subclasses in Python end up
624 * using) just happens today to effectively ignore the nitems argument
625 * when tp_itemsize is 0, which it is for these type objects. If that
626 * changes, perhaps the callers of tp_alloc slots in this file should
627 * be changed to force a 0 nitems argument unless the type being allocated
628 * is a base type implemented in this file (so that tp_alloc is time_alloc
629 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000630 */
631
632static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000633time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000634{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 self = (PyObject *)
638 PyObject_MALLOC(aware ?
639 sizeof(PyDateTime_Time) :
640 sizeof(_PyDateTime_BaseTime));
641 if (self == NULL)
642 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100643 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000645}
646
647static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000648datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000650 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 self = (PyObject *)
653 PyObject_MALLOC(aware ?
654 sizeof(PyDateTime_DateTime) :
655 sizeof(_PyDateTime_BaseDateTime));
656 if (self == NULL)
657 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100658 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000660}
661
662/* ---------------------------------------------------------------------------
663 * Helpers for setting object fields. These work on pointers to the
664 * appropriate base class.
665 */
666
667/* For date and datetime. */
668static void
669set_date_fields(PyDateTime_Date *self, int y, int m, int d)
670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 self->hashcode = -1;
672 SET_YEAR(self, y);
673 SET_MONTH(self, m);
674 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000675}
676
677/* ---------------------------------------------------------------------------
678 * Create various objects, mostly without range checking.
679 */
680
681/* Create a date instance with no range checking. */
682static PyObject *
683new_date_ex(int year, int month, int day, PyTypeObject *type)
684{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
688 if (self != NULL)
689 set_date_fields(self, year, month, day);
690 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000691}
692
693#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000695
696/* Create a datetime instance with no range checking. */
697static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400698new_datetime_ex2(int year, int month, int day, int hour, int minute,
699 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000700{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 PyDateTime_DateTime *self;
702 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
705 if (self != NULL) {
706 self->hastzinfo = aware;
707 set_date_fields((PyDateTime_Date *)self, year, month, day);
708 DATE_SET_HOUR(self, hour);
709 DATE_SET_MINUTE(self, minute);
710 DATE_SET_SECOND(self, second);
711 DATE_SET_MICROSECOND(self, usecond);
712 if (aware) {
713 Py_INCREF(tzinfo);
714 self->tzinfo = tzinfo;
715 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400716 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 }
718 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000719}
720
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400721static PyObject *
722new_datetime_ex(int year, int month, int day, int hour, int minute,
723 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
724{
725 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
726 tzinfo, 0, type);
727}
728
729#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
730 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000732
733/* Create a time instance with no range checking. */
734static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400735new_time_ex2(int hour, int minute, int second, int usecond,
736 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 PyDateTime_Time *self;
739 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
742 if (self != NULL) {
743 self->hastzinfo = aware;
744 self->hashcode = -1;
745 TIME_SET_HOUR(self, hour);
746 TIME_SET_MINUTE(self, minute);
747 TIME_SET_SECOND(self, second);
748 TIME_SET_MICROSECOND(self, usecond);
749 if (aware) {
750 Py_INCREF(tzinfo);
751 self->tzinfo = tzinfo;
752 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400753 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 }
755 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000756}
757
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400758static PyObject *
759new_time_ex(int hour, int minute, int second, int usecond,
760 PyObject *tzinfo, PyTypeObject *type)
761{
762 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
763}
764
765#define new_time(hh, mm, ss, us, tzinfo, fold) \
766 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000767
768/* Create a timedelta instance. Normalize the members iff normalize is
769 * true. Passing false is a speed optimization, if you know for sure
770 * that seconds and microseconds are already in their proper ranges. In any
771 * case, raises OverflowError and returns NULL if the normalized days is out
772 * of range).
773 */
774static PyObject *
775new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 if (normalize)
781 normalize_d_s_us(&days, &seconds, &microseconds);
782 assert(0 <= seconds && seconds < 24*3600);
783 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000784
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000785 if (check_delta_day_range(days) < 0)
786 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
789 if (self != NULL) {
790 self->hashcode = -1;
791 SET_TD_DAYS(self, days);
792 SET_TD_SECONDS(self, seconds);
793 SET_TD_MICROSECONDS(self, microseconds);
794 }
795 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000796}
797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798#define new_delta(d, s, us, normalize) \
799 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000800
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000801
802typedef struct
803{
804 PyObject_HEAD
805 PyObject *offset;
806 PyObject *name;
807} PyDateTime_TimeZone;
808
Victor Stinner6ced7c42011-03-21 18:15:42 +0100809/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000810static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -0400811/* The interned Epoch datetime instance */
812static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000813
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000814/* Create new timezone instance checking offset range. This
815 function does not check the name argument. Caller must assure
816 that offset is a timedelta instance and name is either NULL
817 or a unicode object. */
818static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000819create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000820{
821 PyDateTime_TimeZone *self;
822 PyTypeObject *type = &PyDateTime_TimeZoneType;
823
824 assert(offset != NULL);
825 assert(PyDelta_Check(offset));
826 assert(name == NULL || PyUnicode_Check(name));
827
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000828 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
829 if (self == NULL) {
830 return NULL;
831 }
832 Py_INCREF(offset);
833 self->offset = offset;
834 Py_XINCREF(name);
835 self->name = name;
836 return (PyObject *)self;
837}
838
839static int delta_bool(PyDateTime_Delta *self);
840
841static PyObject *
842new_timezone(PyObject *offset, PyObject *name)
843{
844 assert(offset != NULL);
845 assert(PyDelta_Check(offset));
846 assert(name == NULL || PyUnicode_Check(name));
847
848 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
849 Py_INCREF(PyDateTime_TimeZone_UTC);
850 return PyDateTime_TimeZone_UTC;
851 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000852 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
853 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400854 " representing a whole number of minutes,"
855 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000856 return NULL;
857 }
858 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
859 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
860 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
861 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400862 " timedelta(hours=24),"
863 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000864 return NULL;
865 }
866
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000867 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000868}
869
Tim Petersb0c854d2003-05-17 15:57:00 +0000870/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000871 * tzinfo helpers.
872 */
873
Tim Peters855fe882002-12-22 03:43:39 +0000874/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
875 * raise TypeError and return -1.
876 */
877static int
878check_tzinfo_subclass(PyObject *p)
879{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 if (p == Py_None || PyTZInfo_Check(p))
881 return 0;
882 PyErr_Format(PyExc_TypeError,
883 "tzinfo argument must be None or of a tzinfo subclass, "
884 "not type '%s'",
885 Py_TYPE(p)->tp_name);
886 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000887}
888
Tim Peters2a799bf2002-12-16 20:18:38 +0000889/* If self has a tzinfo member, return a BORROWED reference to it. Else
890 * return NULL, which is NOT AN ERROR. There are no error returns here,
891 * and the caller must not decref the result.
892 */
893static PyObject *
894get_tzinfo_member(PyObject *self)
895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 if (PyDateTime_Check(self) && HASTZINFO(self))
899 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
900 else if (PyTime_Check(self) && HASTZINFO(self))
901 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000904}
905
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000906/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
907 * be an instance of the tzinfo class. If the method returns None, this
908 * returns None. If the method doesn't return None or timedelta, TypeError is
909 * raised and this returns NULL. If it returns a timedelta and the value is
910 * out of range or isn't a whole number of minutes, ValueError is raised and
911 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000912 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000913static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200914call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000915{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000916 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000919 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000921
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000922 if (tzinfo == Py_None)
923 Py_RETURN_NONE;
924 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
925 if (offset == Py_None || offset == NULL)
926 return offset;
927 if (PyDelta_Check(offset)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400928 if (GET_TD_MICROSECONDS(offset) != 0) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000929 Py_DECREF(offset);
930 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400931 " representing a whole number of seconds");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000932 return NULL;
933 }
934 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
935 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
936 Py_DECREF(offset);
937 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
938 " strictly between -timedelta(hours=24) and"
939 " timedelta(hours=24).");
940 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 }
942 }
943 else {
944 PyErr_Format(PyExc_TypeError,
945 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000946 "timedelta, not '%.200s'",
947 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -0700948 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000949 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000951
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000952 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000953}
954
955/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
956 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
957 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000958 * doesn't return None or timedelta, TypeError is raised and this returns -1.
959 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
960 * # of minutes), ValueError is raised and this returns -1. Else *none is
961 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000962 */
Tim Peters855fe882002-12-22 03:43:39 +0000963static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000964call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
965{
966 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000967}
968
Tim Peters2a799bf2002-12-16 20:18:38 +0000969/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
970 * result. tzinfo must be an instance of the tzinfo class. If dst()
971 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000972 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000973 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000974 * ValueError is raised and this returns -1. Else *none is set to 0 and
975 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000976 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000977static PyObject *
978call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000979{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000980 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000981}
982
Tim Petersbad8ff02002-12-30 20:52:32 +0000983/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000984 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000985 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000986 * returns NULL. If the result is a string, we ensure it is a Unicode
987 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000988 */
989static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000990call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200993 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 assert(tzinfo != NULL);
996 assert(check_tzinfo_subclass(tzinfo) >= 0);
997 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001000 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001001
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001002 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001003
1004 if (result == NULL || result == Py_None)
1005 return result;
1006
1007 if (!PyUnicode_Check(result)) {
1008 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1009 "return None or a string, not '%s'",
1010 Py_TYPE(result)->tp_name);
1011 Py_DECREF(result);
1012 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001014
1015 return result;
Tim Peters00237032002-12-27 02:21:51 +00001016}
1017
Tim Peters2a799bf2002-12-16 20:18:38 +00001018/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1019 * stuff
1020 * ", tzinfo=" + repr(tzinfo)
1021 * before the closing ")".
1022 */
1023static PyObject *
1024append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1025{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 assert(PyUnicode_Check(repr));
1029 assert(tzinfo);
1030 if (tzinfo == Py_None)
1031 return repr;
1032 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001033 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1034 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 Py_DECREF(repr);
1036 if (temp == NULL)
1037 return NULL;
1038 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1039 Py_DECREF(temp);
1040 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001041}
1042
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001043/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1044 * stuff
1045 * ", fold=" + repr(tzinfo)
1046 * before the closing ")".
1047 */
1048static PyObject *
1049append_keyword_fold(PyObject *repr, int fold)
1050{
1051 PyObject *temp;
1052
1053 assert(PyUnicode_Check(repr));
1054 if (fold == 0)
1055 return repr;
1056 /* Get rid of the trailing ')'. */
1057 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1058 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1059 Py_DECREF(repr);
1060 if (temp == NULL)
1061 return NULL;
1062 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1063 Py_DECREF(temp);
1064 return repr;
1065}
1066
Tim Peters2a799bf2002-12-16 20:18:38 +00001067/* ---------------------------------------------------------------------------
1068 * String format helpers.
1069 */
1070
1071static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001072format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001073{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001074 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1076 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001077 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1079 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1080 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001082 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1085 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1086 GET_DAY(date), hours, minutes, seconds,
1087 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001088}
1089
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001090static PyObject *delta_negative(PyDateTime_Delta *self);
1091
Tim Peters2a799bf2002-12-16 20:18:38 +00001092/* Add an hours & minutes UTC offset string to buf. buf has no more than
1093 * buflen bytes remaining. The UTC offset is gotten by calling
1094 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1095 * *buf, and that's all. Else the returned value is checked for sanity (an
1096 * integer in range), and if that's OK it's converted to an hours & minutes
1097 * string of the form
1098 * sign HH sep MM
1099 * Returns 0 if everything is OK. If the return value from utcoffset() is
1100 * bogus, an appropriate exception is set and -1 is returned.
1101 */
1102static int
Tim Peters328fff72002-12-20 01:31:27 +00001103format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001105{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001106 PyObject *offset;
1107 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001111
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001112 offset = call_utcoffset(tzinfo, tzinfoarg);
1113 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001115 if (offset == Py_None) {
1116 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 *buf = '\0';
1118 return 0;
1119 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001120 /* Offset is normalized, so it is negative if days < 0 */
1121 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001123 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001124 if (offset == NULL)
1125 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001127 else {
1128 sign = '+';
1129 }
1130 /* Offset is not negative here. */
1131 seconds = GET_TD_SECONDS(offset);
1132 Py_DECREF(offset);
1133 minutes = divmod(seconds, 60, &seconds);
1134 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001135 if (seconds == 0)
1136 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1137 else
1138 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1139 sep, minutes, sep, seconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001141}
1142
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001143static PyObject *
1144make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 PyObject *temp;
1147 PyObject *tzinfo = get_tzinfo_member(object);
1148 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001149 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 if (Zreplacement == NULL)
1152 return NULL;
1153 if (tzinfo == Py_None || tzinfo == NULL)
1154 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 assert(tzinfoarg != NULL);
1157 temp = call_tzname(tzinfo, tzinfoarg);
1158 if (temp == NULL)
1159 goto Error;
1160 if (temp == Py_None) {
1161 Py_DECREF(temp);
1162 return Zreplacement;
1163 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 assert(PyUnicode_Check(temp));
1166 /* Since the tzname is getting stuffed into the
1167 * format, we have to double any % signs so that
1168 * strftime doesn't treat them as format codes.
1169 */
1170 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001171 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 Py_DECREF(temp);
1173 if (Zreplacement == NULL)
1174 return NULL;
1175 if (!PyUnicode_Check(Zreplacement)) {
1176 PyErr_SetString(PyExc_TypeError,
1177 "tzname.replace() did not return a string");
1178 goto Error;
1179 }
1180 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001181
1182 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 Py_DECREF(Zreplacement);
1184 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001185}
1186
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001187static PyObject *
1188make_freplacement(PyObject *object)
1189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 char freplacement[64];
1191 if (PyTime_Check(object))
1192 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1193 else if (PyDateTime_Check(object))
1194 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1195 else
1196 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001199}
1200
Tim Peters2a799bf2002-12-16 20:18:38 +00001201/* I sure don't want to reproduce the strftime code from the time module,
1202 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001203 * giving special meanings to the %z, %Z and %f format codes via a
1204 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001205 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1206 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001207 */
1208static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001209wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1215 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1216 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 const char *pin; /* pointer to next char in input format */
1219 Py_ssize_t flen; /* length of input format */
1220 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 PyObject *newfmt = NULL; /* py string, the output format */
1223 char *pnew; /* pointer to available byte in output format */
1224 size_t totalnew; /* number bytes total in output format buffer,
1225 exclusive of trailing \0 */
1226 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 const char *ptoappend; /* ptr to string to append to output buffer */
1229 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 assert(object && format && timetuple);
1232 assert(PyUnicode_Check(format));
1233 /* Convert the input format to a C string and size */
1234 pin = _PyUnicode_AsStringAndSize(format, &flen);
1235 if (!pin)
1236 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 /* Scan the input format, looking for %z/%Z/%f escapes, building
1239 * a new format. Since computing the replacements for those codes
1240 * is expensive, don't unless they're actually used.
1241 */
1242 if (flen > INT_MAX - 1) {
1243 PyErr_NoMemory();
1244 goto Done;
1245 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 totalnew = flen + 1; /* realistic if no %z/%Z */
1248 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1249 if (newfmt == NULL) goto Done;
1250 pnew = PyBytes_AsString(newfmt);
1251 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 while ((ch = *pin++) != '\0') {
1254 if (ch != '%') {
1255 ptoappend = pin - 1;
1256 ntoappend = 1;
1257 }
1258 else if ((ch = *pin++) == '\0') {
1259 /* There's a lone trailing %; doesn't make sense. */
1260 PyErr_SetString(PyExc_ValueError, "strftime format "
1261 "ends with raw %");
1262 goto Done;
1263 }
1264 /* A % has been seen and ch is the character after it. */
1265 else if (ch == 'z') {
1266 if (zreplacement == NULL) {
1267 /* format utcoffset */
1268 char buf[100];
1269 PyObject *tzinfo = get_tzinfo_member(object);
1270 zreplacement = PyBytes_FromStringAndSize("", 0);
1271 if (zreplacement == NULL) goto Done;
1272 if (tzinfo != Py_None && tzinfo != NULL) {
1273 assert(tzinfoarg != NULL);
1274 if (format_utcoffset(buf,
1275 sizeof(buf),
1276 "",
1277 tzinfo,
1278 tzinfoarg) < 0)
1279 goto Done;
1280 Py_DECREF(zreplacement);
1281 zreplacement =
1282 PyBytes_FromStringAndSize(buf,
1283 strlen(buf));
1284 if (zreplacement == NULL)
1285 goto Done;
1286 }
1287 }
1288 assert(zreplacement != NULL);
1289 ptoappend = PyBytes_AS_STRING(zreplacement);
1290 ntoappend = PyBytes_GET_SIZE(zreplacement);
1291 }
1292 else if (ch == 'Z') {
1293 /* format tzname */
1294 if (Zreplacement == NULL) {
1295 Zreplacement = make_Zreplacement(object,
1296 tzinfoarg);
1297 if (Zreplacement == NULL)
1298 goto Done;
1299 }
1300 assert(Zreplacement != NULL);
1301 assert(PyUnicode_Check(Zreplacement));
1302 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1303 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001304 if (ptoappend == NULL)
1305 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 }
1307 else if (ch == 'f') {
1308 /* format microseconds */
1309 if (freplacement == NULL) {
1310 freplacement = make_freplacement(object);
1311 if (freplacement == NULL)
1312 goto Done;
1313 }
1314 assert(freplacement != NULL);
1315 assert(PyBytes_Check(freplacement));
1316 ptoappend = PyBytes_AS_STRING(freplacement);
1317 ntoappend = PyBytes_GET_SIZE(freplacement);
1318 }
1319 else {
1320 /* percent followed by neither z nor Z */
1321 ptoappend = pin - 2;
1322 ntoappend = 2;
1323 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 /* Append the ntoappend chars starting at ptoappend to
1326 * the new format.
1327 */
1328 if (ntoappend == 0)
1329 continue;
1330 assert(ptoappend != NULL);
1331 assert(ntoappend > 0);
1332 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001333 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 PyErr_NoMemory();
1335 goto Done;
1336 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001337 totalnew <<= 1;
1338 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 pnew = PyBytes_AsString(newfmt) + usednew;
1341 }
1342 memcpy(pnew, ptoappend, ntoappend);
1343 pnew += ntoappend;
1344 usednew += ntoappend;
1345 assert(usednew <= totalnew);
1346 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1349 goto Done;
1350 {
1351 PyObject *format;
1352 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 if (time == NULL)
1355 goto Done;
1356 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1357 if (format != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001358 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1359 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 Py_DECREF(format);
1361 }
1362 Py_DECREF(time);
1363 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001364 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 Py_XDECREF(freplacement);
1366 Py_XDECREF(zreplacement);
1367 Py_XDECREF(Zreplacement);
1368 Py_XDECREF(newfmt);
1369 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001370}
1371
Tim Peters2a799bf2002-12-16 20:18:38 +00001372/* ---------------------------------------------------------------------------
1373 * Wrap functions from the time module. These aren't directly available
1374 * from C. Perhaps they should be.
1375 */
1376
1377/* Call time.time() and return its result (a Python float). */
1378static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001379time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 PyObject *result = NULL;
1382 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001385 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001386
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001387 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 Py_DECREF(time);
1389 }
1390 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001391}
1392
1393/* Build a time.struct_time. The weekday and day number are automatically
1394 * computed from the y,m,d args.
1395 */
1396static PyObject *
1397build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 PyObject *time;
1400 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 time = PyImport_ImportModuleNoBlock("time");
1403 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001404 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001405
1406 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1407 "((iiiiiiiii))",
1408 y, m, d,
1409 hh, mm, ss,
1410 weekday(y, m, d),
1411 days_before_month(y, m) + d,
1412 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 Py_DECREF(time);
1414 }
1415 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001416}
1417
1418/* ---------------------------------------------------------------------------
1419 * Miscellaneous helpers.
1420 */
1421
Mark Dickinsone94c6792009-02-02 20:36:42 +00001422/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001423 * The comparisons here all most naturally compute a cmp()-like result.
1424 * This little helper turns that into a bool result for rich comparisons.
1425 */
1426static PyObject *
1427diff_to_bool(int diff, int op)
1428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 PyObject *result;
1430 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 switch (op) {
1433 case Py_EQ: istrue = diff == 0; break;
1434 case Py_NE: istrue = diff != 0; break;
1435 case Py_LE: istrue = diff <= 0; break;
1436 case Py_GE: istrue = diff >= 0; break;
1437 case Py_LT: istrue = diff < 0; break;
1438 case Py_GT: istrue = diff > 0; break;
1439 default:
1440 assert(! "op unknown");
1441 istrue = 0; /* To shut up compiler */
1442 }
1443 result = istrue ? Py_True : Py_False;
1444 Py_INCREF(result);
1445 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001446}
1447
Tim Peters07534a62003-02-07 22:50:28 +00001448/* Raises a "can't compare" TypeError and returns NULL. */
1449static PyObject *
1450cmperror(PyObject *a, PyObject *b)
1451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 PyErr_Format(PyExc_TypeError,
1453 "can't compare %s to %s",
1454 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1455 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001456}
1457
Tim Peters2a799bf2002-12-16 20:18:38 +00001458/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001459 * Cached Python objects; these are set by the module init function.
1460 */
1461
1462/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001463static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464static PyObject *us_per_ms = NULL; /* 1000 */
1465static PyObject *us_per_second = NULL; /* 1000000 */
1466static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001467static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1468static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1469static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001470static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1471
Tim Peters2a799bf2002-12-16 20:18:38 +00001472/* ---------------------------------------------------------------------------
1473 * Class implementations.
1474 */
1475
1476/*
1477 * PyDateTime_Delta implementation.
1478 */
1479
1480/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001482 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001483 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1484 * due to ubiquitous overflow possibilities.
1485 */
1486static PyObject *
1487delta_to_microseconds(PyDateTime_Delta *self)
1488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 PyObject *x1 = NULL;
1490 PyObject *x2 = NULL;
1491 PyObject *x3 = NULL;
1492 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1495 if (x1 == NULL)
1496 goto Done;
1497 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1498 if (x2 == NULL)
1499 goto Done;
1500 Py_DECREF(x1);
1501 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 /* x2 has days in seconds */
1504 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1505 if (x1 == NULL)
1506 goto Done;
1507 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1508 if (x3 == NULL)
1509 goto Done;
1510 Py_DECREF(x1);
1511 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001512 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 /* x3 has days+seconds in seconds */
1515 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1516 if (x1 == NULL)
1517 goto Done;
1518 Py_DECREF(x3);
1519 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 /* x1 has days+seconds in us */
1522 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1523 if (x2 == NULL)
1524 goto Done;
1525 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001526
1527Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 Py_XDECREF(x1);
1529 Py_XDECREF(x2);
1530 Py_XDECREF(x3);
1531 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001532}
1533
Serhiy Storchaka95949422013-08-27 19:40:23 +03001534/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001535 */
1536static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001537microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 int us;
1540 int s;
1541 int d;
1542 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 PyObject *tuple = NULL;
1545 PyObject *num = NULL;
1546 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 tuple = PyNumber_Divmod(pyus, us_per_second);
1549 if (tuple == NULL)
1550 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 num = PyTuple_GetItem(tuple, 1); /* us */
1553 if (num == NULL)
1554 goto Done;
1555 temp = PyLong_AsLong(num);
1556 num = NULL;
1557 if (temp == -1 && PyErr_Occurred())
1558 goto Done;
1559 assert(0 <= temp && temp < 1000000);
1560 us = (int)temp;
1561 if (us < 0) {
1562 /* The divisor was positive, so this must be an error. */
1563 assert(PyErr_Occurred());
1564 goto Done;
1565 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1568 if (num == NULL)
1569 goto Done;
1570 Py_INCREF(num);
1571 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 tuple = PyNumber_Divmod(num, seconds_per_day);
1574 if (tuple == NULL)
1575 goto Done;
1576 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 num = PyTuple_GetItem(tuple, 1); /* seconds */
1579 if (num == NULL)
1580 goto Done;
1581 temp = PyLong_AsLong(num);
1582 num = NULL;
1583 if (temp == -1 && PyErr_Occurred())
1584 goto Done;
1585 assert(0 <= temp && temp < 24*3600);
1586 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 if (s < 0) {
1589 /* The divisor was positive, so this must be an error. */
1590 assert(PyErr_Occurred());
1591 goto Done;
1592 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1595 if (num == NULL)
1596 goto Done;
1597 Py_INCREF(num);
1598 temp = PyLong_AsLong(num);
1599 if (temp == -1 && PyErr_Occurred())
1600 goto Done;
1601 d = (int)temp;
1602 if ((long)d != temp) {
1603 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1604 "large to fit in a C int");
1605 goto Done;
1606 }
1607 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001608
1609Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 Py_XDECREF(tuple);
1611 Py_XDECREF(num);
1612 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001613}
1614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615#define microseconds_to_delta(pymicros) \
1616 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001617
Tim Peters2a799bf2002-12-16 20:18:38 +00001618static PyObject *
1619multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyObject *pyus_in;
1622 PyObject *pyus_out;
1623 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 pyus_in = delta_to_microseconds(delta);
1626 if (pyus_in == NULL)
1627 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1630 Py_DECREF(pyus_in);
1631 if (pyus_out == NULL)
1632 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 result = microseconds_to_delta(pyus_out);
1635 Py_DECREF(pyus_out);
1636 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001637}
1638
1639static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001640multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1641{
1642 PyObject *result = NULL;
1643 PyObject *pyus_in = NULL, *temp, *pyus_out;
1644 PyObject *ratio = NULL;
1645
1646 pyus_in = delta_to_microseconds(delta);
1647 if (pyus_in == NULL)
1648 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001649 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001650 if (ratio == NULL)
1651 goto error;
1652 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1653 Py_DECREF(pyus_in);
1654 pyus_in = NULL;
1655 if (temp == NULL)
1656 goto error;
1657 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1658 Py_DECREF(temp);
1659 if (pyus_out == NULL)
1660 goto error;
1661 result = microseconds_to_delta(pyus_out);
1662 Py_DECREF(pyus_out);
1663 error:
1664 Py_XDECREF(pyus_in);
1665 Py_XDECREF(ratio);
1666
1667 return result;
1668}
1669
1670static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001671divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 PyObject *pyus_in;
1674 PyObject *pyus_out;
1675 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 pyus_in = delta_to_microseconds(delta);
1678 if (pyus_in == NULL)
1679 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1682 Py_DECREF(pyus_in);
1683 if (pyus_out == NULL)
1684 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 result = microseconds_to_delta(pyus_out);
1687 Py_DECREF(pyus_out);
1688 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001689}
1690
1691static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001692divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1693{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 PyObject *pyus_left;
1695 PyObject *pyus_right;
1696 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 pyus_left = delta_to_microseconds(left);
1699 if (pyus_left == NULL)
1700 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 pyus_right = delta_to_microseconds(right);
1703 if (pyus_right == NULL) {
1704 Py_DECREF(pyus_left);
1705 return NULL;
1706 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1709 Py_DECREF(pyus_left);
1710 Py_DECREF(pyus_right);
1711 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001712}
1713
1714static PyObject *
1715truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 PyObject *pyus_left;
1718 PyObject *pyus_right;
1719 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001720
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001721 pyus_left = delta_to_microseconds(left);
1722 if (pyus_left == NULL)
1723 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 pyus_right = delta_to_microseconds(right);
1726 if (pyus_right == NULL) {
1727 Py_DECREF(pyus_left);
1728 return NULL;
1729 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1732 Py_DECREF(pyus_left);
1733 Py_DECREF(pyus_right);
1734 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001735}
1736
1737static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001738truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1739{
1740 PyObject *result = NULL;
1741 PyObject *pyus_in = NULL, *temp, *pyus_out;
1742 PyObject *ratio = NULL;
1743
1744 pyus_in = delta_to_microseconds(delta);
1745 if (pyus_in == NULL)
1746 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001747 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001748 if (ratio == NULL)
1749 goto error;
1750 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1751 Py_DECREF(pyus_in);
1752 pyus_in = NULL;
1753 if (temp == NULL)
1754 goto error;
1755 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1756 Py_DECREF(temp);
1757 if (pyus_out == NULL)
1758 goto error;
1759 result = microseconds_to_delta(pyus_out);
1760 Py_DECREF(pyus_out);
1761 error:
1762 Py_XDECREF(pyus_in);
1763 Py_XDECREF(ratio);
1764
1765 return result;
1766}
1767
1768static PyObject *
1769truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1770{
1771 PyObject *result;
1772 PyObject *pyus_in, *pyus_out;
1773 pyus_in = delta_to_microseconds(delta);
1774 if (pyus_in == NULL)
1775 return NULL;
1776 pyus_out = divide_nearest(pyus_in, i);
1777 Py_DECREF(pyus_in);
1778 if (pyus_out == NULL)
1779 return NULL;
1780 result = microseconds_to_delta(pyus_out);
1781 Py_DECREF(pyus_out);
1782
1783 return result;
1784}
1785
1786static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001787delta_add(PyObject *left, PyObject *right)
1788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1792 /* delta + delta */
1793 /* The C-level additions can't overflow because of the
1794 * invariant bounds.
1795 */
1796 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1797 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1798 int microseconds = GET_TD_MICROSECONDS(left) +
1799 GET_TD_MICROSECONDS(right);
1800 result = new_delta(days, seconds, microseconds, 1);
1801 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 if (result == Py_NotImplemented)
1804 Py_INCREF(result);
1805 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001806}
1807
1808static PyObject *
1809delta_negative(PyDateTime_Delta *self)
1810{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 return new_delta(-GET_TD_DAYS(self),
1812 -GET_TD_SECONDS(self),
1813 -GET_TD_MICROSECONDS(self),
1814 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001815}
1816
1817static PyObject *
1818delta_positive(PyDateTime_Delta *self)
1819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 /* Could optimize this (by returning self) if this isn't a
1821 * subclass -- but who uses unary + ? Approximately nobody.
1822 */
1823 return new_delta(GET_TD_DAYS(self),
1824 GET_TD_SECONDS(self),
1825 GET_TD_MICROSECONDS(self),
1826 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001827}
1828
1829static PyObject *
1830delta_abs(PyDateTime_Delta *self)
1831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 assert(GET_TD_MICROSECONDS(self) >= 0);
1835 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 if (GET_TD_DAYS(self) < 0)
1838 result = delta_negative(self);
1839 else
1840 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001843}
1844
1845static PyObject *
1846delta_subtract(PyObject *left, PyObject *right)
1847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1851 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001852 /* The C-level additions can't overflow because of the
1853 * invariant bounds.
1854 */
1855 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1856 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1857 int microseconds = GET_TD_MICROSECONDS(left) -
1858 GET_TD_MICROSECONDS(right);
1859 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 if (result == Py_NotImplemented)
1863 Py_INCREF(result);
1864 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001865}
1866
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001867static int
1868delta_cmp(PyObject *self, PyObject *other)
1869{
1870 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1871 if (diff == 0) {
1872 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1873 if (diff == 0)
1874 diff = GET_TD_MICROSECONDS(self) -
1875 GET_TD_MICROSECONDS(other);
1876 }
1877 return diff;
1878}
1879
Tim Peters2a799bf2002-12-16 20:18:38 +00001880static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001881delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001884 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 return diff_to_bool(diff, op);
1886 }
1887 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001888 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001890}
1891
1892static PyObject *delta_getstate(PyDateTime_Delta *self);
1893
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001894static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001895delta_hash(PyDateTime_Delta *self)
1896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 if (self->hashcode == -1) {
1898 PyObject *temp = delta_getstate(self);
1899 if (temp != NULL) {
1900 self->hashcode = PyObject_Hash(temp);
1901 Py_DECREF(temp);
1902 }
1903 }
1904 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001905}
1906
1907static PyObject *
1908delta_multiply(PyObject *left, PyObject *right)
1909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 if (PyDelta_Check(left)) {
1913 /* delta * ??? */
1914 if (PyLong_Check(right))
1915 result = multiply_int_timedelta(right,
1916 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001917 else if (PyFloat_Check(right))
1918 result = multiply_float_timedelta(right,
1919 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 }
1921 else if (PyLong_Check(left))
1922 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001923 (PyDateTime_Delta *) right);
1924 else if (PyFloat_Check(left))
1925 result = multiply_float_timedelta(left,
1926 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 if (result == Py_NotImplemented)
1929 Py_INCREF(result);
1930 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001931}
1932
1933static PyObject *
1934delta_divide(PyObject *left, PyObject *right)
1935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 if (PyDelta_Check(left)) {
1939 /* delta * ??? */
1940 if (PyLong_Check(right))
1941 result = divide_timedelta_int(
1942 (PyDateTime_Delta *)left,
1943 right);
1944 else if (PyDelta_Check(right))
1945 result = divide_timedelta_timedelta(
1946 (PyDateTime_Delta *)left,
1947 (PyDateTime_Delta *)right);
1948 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 if (result == Py_NotImplemented)
1951 Py_INCREF(result);
1952 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001953}
1954
Mark Dickinson7c186e22010-04-20 22:32:49 +00001955static PyObject *
1956delta_truedivide(PyObject *left, PyObject *right)
1957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 if (PyDelta_Check(left)) {
1961 if (PyDelta_Check(right))
1962 result = truedivide_timedelta_timedelta(
1963 (PyDateTime_Delta *)left,
1964 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001965 else if (PyFloat_Check(right))
1966 result = truedivide_timedelta_float(
1967 (PyDateTime_Delta *)left, right);
1968 else if (PyLong_Check(right))
1969 result = truedivide_timedelta_int(
1970 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 if (result == Py_NotImplemented)
1974 Py_INCREF(result);
1975 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001976}
1977
1978static PyObject *
1979delta_remainder(PyObject *left, PyObject *right)
1980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 PyObject *pyus_left;
1982 PyObject *pyus_right;
1983 PyObject *pyus_remainder;
1984 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001985
Brian Curtindfc80e32011-08-10 20:28:54 -05001986 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1987 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1990 if (pyus_left == NULL)
1991 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1994 if (pyus_right == NULL) {
1995 Py_DECREF(pyus_left);
1996 return NULL;
1997 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2000 Py_DECREF(pyus_left);
2001 Py_DECREF(pyus_right);
2002 if (pyus_remainder == NULL)
2003 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 remainder = microseconds_to_delta(pyus_remainder);
2006 Py_DECREF(pyus_remainder);
2007 if (remainder == NULL)
2008 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002011}
2012
2013static PyObject *
2014delta_divmod(PyObject *left, PyObject *right)
2015{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 PyObject *pyus_left;
2017 PyObject *pyus_right;
2018 PyObject *divmod;
2019 PyObject *delta;
2020 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002021
Brian Curtindfc80e32011-08-10 20:28:54 -05002022 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2023 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2026 if (pyus_left == NULL)
2027 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2030 if (pyus_right == NULL) {
2031 Py_DECREF(pyus_left);
2032 return NULL;
2033 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2036 Py_DECREF(pyus_left);
2037 Py_DECREF(pyus_right);
2038 if (divmod == NULL)
2039 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 assert(PyTuple_Size(divmod) == 2);
2042 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2043 if (delta == NULL) {
2044 Py_DECREF(divmod);
2045 return NULL;
2046 }
2047 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2048 Py_DECREF(delta);
2049 Py_DECREF(divmod);
2050 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002051}
2052
Tim Peters2a799bf2002-12-16 20:18:38 +00002053/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2054 * timedelta constructor. sofar is the # of microseconds accounted for
2055 * so far, and there are factor microseconds per current unit, the number
2056 * of which is given by num. num * factor is added to sofar in a
2057 * numerically careful way, and that's the result. Any fractional
2058 * microseconds left over (this can happen if num is a float type) are
2059 * added into *leftover.
2060 * Note that there are many ways this can give an error (NULL) return.
2061 */
2062static PyObject *
2063accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2064 double *leftover)
2065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 PyObject *prod;
2067 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 if (PyLong_Check(num)) {
2072 prod = PyNumber_Multiply(num, factor);
2073 if (prod == NULL)
2074 return NULL;
2075 sum = PyNumber_Add(sofar, prod);
2076 Py_DECREF(prod);
2077 return sum;
2078 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002080 if (PyFloat_Check(num)) {
2081 double dnum;
2082 double fracpart;
2083 double intpart;
2084 PyObject *x;
2085 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 /* The Plan: decompose num into an integer part and a
2088 * fractional part, num = intpart + fracpart.
2089 * Then num * factor ==
2090 * intpart * factor + fracpart * factor
2091 * and the LHS can be computed exactly in long arithmetic.
2092 * The RHS is again broken into an int part and frac part.
2093 * and the frac part is added into *leftover.
2094 */
2095 dnum = PyFloat_AsDouble(num);
2096 if (dnum == -1.0 && PyErr_Occurred())
2097 return NULL;
2098 fracpart = modf(dnum, &intpart);
2099 x = PyLong_FromDouble(intpart);
2100 if (x == NULL)
2101 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 prod = PyNumber_Multiply(x, factor);
2104 Py_DECREF(x);
2105 if (prod == NULL)
2106 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 sum = PyNumber_Add(sofar, prod);
2109 Py_DECREF(prod);
2110 if (sum == NULL)
2111 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 if (fracpart == 0.0)
2114 return sum;
2115 /* So far we've lost no information. Dealing with the
2116 * fractional part requires float arithmetic, and may
2117 * lose a little info.
2118 */
2119 assert(PyLong_Check(factor));
2120 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 dnum *= fracpart;
2123 fracpart = modf(dnum, &intpart);
2124 x = PyLong_FromDouble(intpart);
2125 if (x == NULL) {
2126 Py_DECREF(sum);
2127 return NULL;
2128 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 y = PyNumber_Add(sum, x);
2131 Py_DECREF(sum);
2132 Py_DECREF(x);
2133 *leftover += fracpart;
2134 return y;
2135 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 PyErr_Format(PyExc_TypeError,
2138 "unsupported type for timedelta %s component: %s",
2139 tag, Py_TYPE(num)->tp_name);
2140 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002141}
2142
2143static PyObject *
2144delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 /* Argument objects. */
2149 PyObject *day = NULL;
2150 PyObject *second = NULL;
2151 PyObject *us = NULL;
2152 PyObject *ms = NULL;
2153 PyObject *minute = NULL;
2154 PyObject *hour = NULL;
2155 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 PyObject *x = NULL; /* running sum of microseconds */
2158 PyObject *y = NULL; /* temp sum of microseconds */
2159 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 static char *keywords[] = {
2162 "days", "seconds", "microseconds", "milliseconds",
2163 "minutes", "hours", "weeks", NULL
2164 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2167 keywords,
2168 &day, &second, &us,
2169 &ms, &minute, &hour, &week) == 0)
2170 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 x = PyLong_FromLong(0);
2173 if (x == NULL)
2174 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176#define CLEANUP \
2177 Py_DECREF(x); \
2178 x = y; \
2179 if (x == NULL) \
2180 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002183 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 CLEANUP;
2185 }
2186 if (ms) {
2187 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2188 CLEANUP;
2189 }
2190 if (second) {
2191 y = accum("seconds", x, second, us_per_second, &leftover_us);
2192 CLEANUP;
2193 }
2194 if (minute) {
2195 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2196 CLEANUP;
2197 }
2198 if (hour) {
2199 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2200 CLEANUP;
2201 }
2202 if (day) {
2203 y = accum("days", x, day, us_per_day, &leftover_us);
2204 CLEANUP;
2205 }
2206 if (week) {
2207 y = accum("weeks", x, week, us_per_week, &leftover_us);
2208 CLEANUP;
2209 }
2210 if (leftover_us) {
2211 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002212 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002213 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002214 PyObject *temp;
2215
Victor Stinner69cc4872015-09-08 23:58:54 +02002216 whole_us = round(leftover_us);
2217 if (fabs(whole_us - leftover_us) == 0.5) {
2218 /* We're exactly halfway between two integers. In order
2219 * to do round-half-to-even, we must determine whether x
2220 * is odd. Note that x is odd when it's last bit is 1. The
2221 * code below uses bitwise and operation to check the last
2222 * bit. */
2223 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2224 if (temp == NULL) {
2225 Py_DECREF(x);
2226 goto Done;
2227 }
2228 x_is_odd = PyObject_IsTrue(temp);
2229 Py_DECREF(temp);
2230 if (x_is_odd == -1) {
2231 Py_DECREF(x);
2232 goto Done;
2233 }
2234 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2235 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002236
Victor Stinner36a5a062013-08-28 01:53:39 +02002237 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 if (temp == NULL) {
2240 Py_DECREF(x);
2241 goto Done;
2242 }
2243 y = PyNumber_Add(x, temp);
2244 Py_DECREF(temp);
2245 CLEANUP;
2246 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 self = microseconds_to_delta_ex(x, type);
2249 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002250Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002252
2253#undef CLEANUP
2254}
2255
2256static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002257delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002259 return (GET_TD_DAYS(self) != 0
2260 || GET_TD_SECONDS(self) != 0
2261 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002262}
2263
2264static PyObject *
2265delta_repr(PyDateTime_Delta *self)
2266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 if (GET_TD_MICROSECONDS(self) != 0)
2268 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2269 Py_TYPE(self)->tp_name,
2270 GET_TD_DAYS(self),
2271 GET_TD_SECONDS(self),
2272 GET_TD_MICROSECONDS(self));
2273 if (GET_TD_SECONDS(self) != 0)
2274 return PyUnicode_FromFormat("%s(%d, %d)",
2275 Py_TYPE(self)->tp_name,
2276 GET_TD_DAYS(self),
2277 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 return PyUnicode_FromFormat("%s(%d)",
2280 Py_TYPE(self)->tp_name,
2281 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002282}
2283
2284static PyObject *
2285delta_str(PyDateTime_Delta *self)
2286{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 int us = GET_TD_MICROSECONDS(self);
2288 int seconds = GET_TD_SECONDS(self);
2289 int minutes = divmod(seconds, 60, &seconds);
2290 int hours = divmod(minutes, 60, &minutes);
2291 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 if (days) {
2294 if (us)
2295 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2296 days, (days == 1 || days == -1) ? "" : "s",
2297 hours, minutes, seconds, us);
2298 else
2299 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2300 days, (days == 1 || days == -1) ? "" : "s",
2301 hours, minutes, seconds);
2302 } else {
2303 if (us)
2304 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2305 hours, minutes, seconds, us);
2306 else
2307 return PyUnicode_FromFormat("%d:%02d:%02d",
2308 hours, minutes, seconds);
2309 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002310
Tim Peters2a799bf2002-12-16 20:18:38 +00002311}
2312
Tim Peters371935f2003-02-01 01:52:50 +00002313/* Pickle support, a simple use of __reduce__. */
2314
Tim Petersb57f8f02003-02-01 02:54:15 +00002315/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002316static PyObject *
2317delta_getstate(PyDateTime_Delta *self)
2318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002319 return Py_BuildValue("iii", GET_TD_DAYS(self),
2320 GET_TD_SECONDS(self),
2321 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002322}
2323
Tim Peters2a799bf2002-12-16 20:18:38 +00002324static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002325delta_total_seconds(PyObject *self)
2326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002327 PyObject *total_seconds;
2328 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002330 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2331 if (total_microseconds == NULL)
2332 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002333
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002334 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002338}
2339
2340static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002341delta_reduce(PyDateTime_Delta* self)
2342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002343 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002344}
2345
2346#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2347
2348static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350 {"days", T_INT, OFFSET(days), READONLY,
2351 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 {"seconds", T_INT, OFFSET(seconds), READONLY,
2354 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2357 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2358 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002359};
2360
2361static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2363 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002365 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2366 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002369};
2370
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002371static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002372PyDoc_STR("Difference between two datetime values.");
2373
2374static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 delta_add, /* nb_add */
2376 delta_subtract, /* nb_subtract */
2377 delta_multiply, /* nb_multiply */
2378 delta_remainder, /* nb_remainder */
2379 delta_divmod, /* nb_divmod */
2380 0, /* nb_power */
2381 (unaryfunc)delta_negative, /* nb_negative */
2382 (unaryfunc)delta_positive, /* nb_positive */
2383 (unaryfunc)delta_abs, /* nb_absolute */
2384 (inquiry)delta_bool, /* nb_bool */
2385 0, /*nb_invert*/
2386 0, /*nb_lshift*/
2387 0, /*nb_rshift*/
2388 0, /*nb_and*/
2389 0, /*nb_xor*/
2390 0, /*nb_or*/
2391 0, /*nb_int*/
2392 0, /*nb_reserved*/
2393 0, /*nb_float*/
2394 0, /*nb_inplace_add*/
2395 0, /*nb_inplace_subtract*/
2396 0, /*nb_inplace_multiply*/
2397 0, /*nb_inplace_remainder*/
2398 0, /*nb_inplace_power*/
2399 0, /*nb_inplace_lshift*/
2400 0, /*nb_inplace_rshift*/
2401 0, /*nb_inplace_and*/
2402 0, /*nb_inplace_xor*/
2403 0, /*nb_inplace_or*/
2404 delta_divide, /* nb_floor_divide */
2405 delta_truedivide, /* nb_true_divide */
2406 0, /* nb_inplace_floor_divide */
2407 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002408};
2409
2410static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 PyVarObject_HEAD_INIT(NULL, 0)
2412 "datetime.timedelta", /* tp_name */
2413 sizeof(PyDateTime_Delta), /* tp_basicsize */
2414 0, /* tp_itemsize */
2415 0, /* tp_dealloc */
2416 0, /* tp_print */
2417 0, /* tp_getattr */
2418 0, /* tp_setattr */
2419 0, /* tp_reserved */
2420 (reprfunc)delta_repr, /* tp_repr */
2421 &delta_as_number, /* tp_as_number */
2422 0, /* tp_as_sequence */
2423 0, /* tp_as_mapping */
2424 (hashfunc)delta_hash, /* tp_hash */
2425 0, /* tp_call */
2426 (reprfunc)delta_str, /* tp_str */
2427 PyObject_GenericGetAttr, /* tp_getattro */
2428 0, /* tp_setattro */
2429 0, /* tp_as_buffer */
2430 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2431 delta_doc, /* tp_doc */
2432 0, /* tp_traverse */
2433 0, /* tp_clear */
2434 delta_richcompare, /* tp_richcompare */
2435 0, /* tp_weaklistoffset */
2436 0, /* tp_iter */
2437 0, /* tp_iternext */
2438 delta_methods, /* tp_methods */
2439 delta_members, /* tp_members */
2440 0, /* tp_getset */
2441 0, /* tp_base */
2442 0, /* tp_dict */
2443 0, /* tp_descr_get */
2444 0, /* tp_descr_set */
2445 0, /* tp_dictoffset */
2446 0, /* tp_init */
2447 0, /* tp_alloc */
2448 delta_new, /* tp_new */
2449 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002450};
2451
2452/*
2453 * PyDateTime_Date implementation.
2454 */
2455
2456/* Accessor properties. */
2457
2458static PyObject *
2459date_year(PyDateTime_Date *self, void *unused)
2460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002461 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002462}
2463
2464static PyObject *
2465date_month(PyDateTime_Date *self, void *unused)
2466{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002468}
2469
2470static PyObject *
2471date_day(PyDateTime_Date *self, void *unused)
2472{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002474}
2475
2476static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 {"year", (getter)date_year},
2478 {"month", (getter)date_month},
2479 {"day", (getter)date_day},
2480 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002481};
2482
2483/* Constructors. */
2484
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002485static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002486
Tim Peters2a799bf2002-12-16 20:18:38 +00002487static PyObject *
2488date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 PyObject *self = NULL;
2491 PyObject *state;
2492 int year;
2493 int month;
2494 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 /* Check for invocation from pickle with __getstate__ state */
2497 if (PyTuple_GET_SIZE(args) == 1 &&
2498 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2499 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2500 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2501 {
2502 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2505 if (me != NULL) {
2506 char *pdata = PyBytes_AS_STRING(state);
2507 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2508 me->hashcode = -1;
2509 }
2510 return (PyObject *)me;
2511 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002513 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2514 &year, &month, &day)) {
2515 if (check_date_args(year, month, day) < 0)
2516 return NULL;
2517 self = new_date_ex(year, month, day, type);
2518 }
2519 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002520}
2521
2522/* Return new date from localtime(t). */
2523static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002524date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002525{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002526 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002527 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002528
Victor Stinnere4a994d2015-03-30 01:10:14 +02002529 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002530 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002531
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002532 if (localtime_r(&t, &tm) == NULL) {
Victor Stinner21f58932012-03-14 00:15:40 +01002533 /* unconvertible time */
2534#ifdef EINVAL
2535 if (errno == 0)
2536 errno = EINVAL;
2537#endif
2538 PyErr_SetFromErrno(PyExc_OSError);
2539 return NULL;
2540 }
2541
2542 return PyObject_CallFunction(cls, "iii",
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002543 tm.tm_year + 1900,
2544 tm.tm_mon + 1,
2545 tm.tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002546}
2547
2548/* Return new date from current time.
2549 * We say this is equivalent to fromtimestamp(time.time()), and the
2550 * only way to be sure of that is to *call* time.time(). That's not
2551 * generally the same as calling C's time.
2552 */
2553static PyObject *
2554date_today(PyObject *cls, PyObject *dummy)
2555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 PyObject *time;
2557 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002558 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 time = time_time();
2561 if (time == NULL)
2562 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 /* Note well: today() is a class method, so this may not call
2565 * date.fromtimestamp. For example, it may call
2566 * datetime.fromtimestamp. That's why we need all the accuracy
2567 * time.time() delivers; if someone were gonzo about optimization,
2568 * date.today() could get away with plain C time().
2569 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002570 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 Py_DECREF(time);
2572 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002573}
2574
2575/* Return new date from given timestamp (Python timestamp -- a double). */
2576static PyObject *
2577date_fromtimestamp(PyObject *cls, PyObject *args)
2578{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002579 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002580 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002581
Victor Stinner5d272cc2012-03-13 13:35:55 +01002582 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2583 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002584 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002585}
2586
2587/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2588 * the ordinal is out of range.
2589 */
2590static PyObject *
2591date_fromordinal(PyObject *cls, PyObject *args)
2592{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002593 PyObject *result = NULL;
2594 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002596 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2597 int year;
2598 int month;
2599 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601 if (ordinal < 1)
2602 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2603 ">= 1");
2604 else {
2605 ord_to_ymd(ordinal, &year, &month, &day);
2606 result = PyObject_CallFunction(cls, "iii",
2607 year, month, day);
2608 }
2609 }
2610 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002611}
2612
2613/*
2614 * Date arithmetic.
2615 */
2616
2617/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2618 * instead.
2619 */
2620static PyObject *
2621add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002623 PyObject *result = NULL;
2624 int year = GET_YEAR(date);
2625 int month = GET_MONTH(date);
2626 int deltadays = GET_TD_DAYS(delta);
2627 /* C-level overflow is impossible because |deltadays| < 1e9. */
2628 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 if (normalize_date(&year, &month, &day) >= 0)
2631 result = new_date(year, month, day);
2632 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002633}
2634
2635static PyObject *
2636date_add(PyObject *left, PyObject *right)
2637{
Brian Curtindfc80e32011-08-10 20:28:54 -05002638 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2639 Py_RETURN_NOTIMPLEMENTED;
2640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 if (PyDate_Check(left)) {
2642 /* date + ??? */
2643 if (PyDelta_Check(right))
2644 /* date + delta */
2645 return add_date_timedelta((PyDateTime_Date *) left,
2646 (PyDateTime_Delta *) right,
2647 0);
2648 }
2649 else {
2650 /* ??? + date
2651 * 'right' must be one of us, or we wouldn't have been called
2652 */
2653 if (PyDelta_Check(left))
2654 /* delta + date */
2655 return add_date_timedelta((PyDateTime_Date *) right,
2656 (PyDateTime_Delta *) left,
2657 0);
2658 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002659 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002660}
2661
2662static PyObject *
2663date_subtract(PyObject *left, PyObject *right)
2664{
Brian Curtindfc80e32011-08-10 20:28:54 -05002665 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2666 Py_RETURN_NOTIMPLEMENTED;
2667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002668 if (PyDate_Check(left)) {
2669 if (PyDate_Check(right)) {
2670 /* date - date */
2671 int left_ord = ymd_to_ord(GET_YEAR(left),
2672 GET_MONTH(left),
2673 GET_DAY(left));
2674 int right_ord = ymd_to_ord(GET_YEAR(right),
2675 GET_MONTH(right),
2676 GET_DAY(right));
2677 return new_delta(left_ord - right_ord, 0, 0, 0);
2678 }
2679 if (PyDelta_Check(right)) {
2680 /* date - delta */
2681 return add_date_timedelta((PyDateTime_Date *) left,
2682 (PyDateTime_Delta *) right,
2683 1);
2684 }
2685 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002686 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002687}
2688
2689
2690/* Various ways to turn a date into a string. */
2691
2692static PyObject *
2693date_repr(PyDateTime_Date *self)
2694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002695 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2696 Py_TYPE(self)->tp_name,
2697 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002698}
2699
2700static PyObject *
2701date_isoformat(PyDateTime_Date *self)
2702{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002703 return PyUnicode_FromFormat("%04d-%02d-%02d",
2704 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002705}
2706
Tim Peterse2df5ff2003-05-02 18:39:55 +00002707/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002708static PyObject *
2709date_str(PyDateTime_Date *self)
2710{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002711 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002712}
2713
2714
2715static PyObject *
2716date_ctime(PyDateTime_Date *self)
2717{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002719}
2720
2721static PyObject *
2722date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2723{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002724 /* This method can be inherited, and needs to call the
2725 * timetuple() method appropriate to self's class.
2726 */
2727 PyObject *result;
2728 PyObject *tuple;
2729 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002730 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002731 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002733 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2734 &format))
2735 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002736
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002737 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002738 if (tuple == NULL)
2739 return NULL;
2740 result = wrap_strftime((PyObject *)self, format, tuple,
2741 (PyObject *)self);
2742 Py_DECREF(tuple);
2743 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002744}
2745
Eric Smith1ba31142007-09-11 18:06:02 +00002746static PyObject *
2747date_format(PyDateTime_Date *self, PyObject *args)
2748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002749 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002751 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2752 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002754 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002755 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002756 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002757
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002758 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002759}
2760
Tim Peters2a799bf2002-12-16 20:18:38 +00002761/* ISO methods. */
2762
2763static PyObject *
2764date_isoweekday(PyDateTime_Date *self)
2765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002766 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002768 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002769}
2770
2771static PyObject *
2772date_isocalendar(PyDateTime_Date *self)
2773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002774 int year = GET_YEAR(self);
2775 int week1_monday = iso_week1_monday(year);
2776 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2777 int week;
2778 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002780 week = divmod(today - week1_monday, 7, &day);
2781 if (week < 0) {
2782 --year;
2783 week1_monday = iso_week1_monday(year);
2784 week = divmod(today - week1_monday, 7, &day);
2785 }
2786 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2787 ++year;
2788 week = 0;
2789 }
2790 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002791}
2792
2793/* Miscellaneous methods. */
2794
Tim Peters2a799bf2002-12-16 20:18:38 +00002795static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002796date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002798 if (PyDate_Check(other)) {
2799 int diff = memcmp(((PyDateTime_Date *)self)->data,
2800 ((PyDateTime_Date *)other)->data,
2801 _PyDateTime_DATE_DATASIZE);
2802 return diff_to_bool(diff, op);
2803 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002804 else
2805 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002806}
2807
2808static PyObject *
2809date_timetuple(PyDateTime_Date *self)
2810{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002811 return build_struct_time(GET_YEAR(self),
2812 GET_MONTH(self),
2813 GET_DAY(self),
2814 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002815}
2816
Tim Peters12bf3392002-12-24 05:41:27 +00002817static PyObject *
2818date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002820 PyObject *clone;
2821 PyObject *tuple;
2822 int year = GET_YEAR(self);
2823 int month = GET_MONTH(self);
2824 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002826 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2827 &year, &month, &day))
2828 return NULL;
2829 tuple = Py_BuildValue("iii", year, month, day);
2830 if (tuple == NULL)
2831 return NULL;
2832 clone = date_new(Py_TYPE(self), tuple, NULL);
2833 Py_DECREF(tuple);
2834 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002835}
2836
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002837static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002838generic_hash(unsigned char *data, int len)
2839{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002840 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002841}
2842
2843
2844static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002845
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002846static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002847date_hash(PyDateTime_Date *self)
2848{
Benjamin Petersondec2df32016-09-09 17:46:24 -07002849 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 self->hashcode = generic_hash(
2851 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07002852 }
Guido van Rossum254348e2007-11-21 19:29:53 +00002853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002855}
2856
2857static PyObject *
2858date_toordinal(PyDateTime_Date *self)
2859{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002860 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2861 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002862}
2863
2864static PyObject *
2865date_weekday(PyDateTime_Date *self)
2866{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002867 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002869 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002870}
2871
Tim Peters371935f2003-02-01 01:52:50 +00002872/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002873
Tim Petersb57f8f02003-02-01 02:54:15 +00002874/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002875static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002876date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002877{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 PyObject* field;
2879 field = PyBytes_FromStringAndSize((char*)self->data,
2880 _PyDateTime_DATE_DATASIZE);
2881 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002882}
2883
2884static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002885date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002886{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002887 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002888}
2889
2890static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002892 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002894 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2895 METH_CLASS,
2896 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2897 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002899 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2900 METH_CLASS,
2901 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2902 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002904 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2905 PyDoc_STR("Current date or datetime: same as "
2906 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002908 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002910 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2911 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002913 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2914 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002916 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2917 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002919 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2920 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002922 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2923 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2924 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002926 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2927 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002929 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2930 PyDoc_STR("Return the day of the week represented by the date.\n"
2931 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002933 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2934 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2935 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002937 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2938 PyDoc_STR("Return the day of the week represented by the date.\n"
2939 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002941 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2942 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002944 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2945 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002947 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002948};
2949
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002950static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002951PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002952
2953static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002954 date_add, /* nb_add */
2955 date_subtract, /* nb_subtract */
2956 0, /* nb_multiply */
2957 0, /* nb_remainder */
2958 0, /* nb_divmod */
2959 0, /* nb_power */
2960 0, /* nb_negative */
2961 0, /* nb_positive */
2962 0, /* nb_absolute */
2963 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002964};
2965
2966static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002967 PyVarObject_HEAD_INIT(NULL, 0)
2968 "datetime.date", /* tp_name */
2969 sizeof(PyDateTime_Date), /* tp_basicsize */
2970 0, /* tp_itemsize */
2971 0, /* tp_dealloc */
2972 0, /* tp_print */
2973 0, /* tp_getattr */
2974 0, /* tp_setattr */
2975 0, /* tp_reserved */
2976 (reprfunc)date_repr, /* tp_repr */
2977 &date_as_number, /* tp_as_number */
2978 0, /* tp_as_sequence */
2979 0, /* tp_as_mapping */
2980 (hashfunc)date_hash, /* tp_hash */
2981 0, /* tp_call */
2982 (reprfunc)date_str, /* tp_str */
2983 PyObject_GenericGetAttr, /* tp_getattro */
2984 0, /* tp_setattro */
2985 0, /* tp_as_buffer */
2986 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2987 date_doc, /* tp_doc */
2988 0, /* tp_traverse */
2989 0, /* tp_clear */
2990 date_richcompare, /* tp_richcompare */
2991 0, /* tp_weaklistoffset */
2992 0, /* tp_iter */
2993 0, /* tp_iternext */
2994 date_methods, /* tp_methods */
2995 0, /* tp_members */
2996 date_getset, /* tp_getset */
2997 0, /* tp_base */
2998 0, /* tp_dict */
2999 0, /* tp_descr_get */
3000 0, /* tp_descr_set */
3001 0, /* tp_dictoffset */
3002 0, /* tp_init */
3003 0, /* tp_alloc */
3004 date_new, /* tp_new */
3005 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003006};
3007
3008/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003009 * PyDateTime_TZInfo implementation.
3010 */
3011
3012/* This is a pure abstract base class, so doesn't do anything beyond
3013 * raising NotImplemented exceptions. Real tzinfo classes need
3014 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003015 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003016 * be subclasses of this tzinfo class, which is easy and quick to check).
3017 *
3018 * Note: For reasons having to do with pickling of subclasses, we have
3019 * to allow tzinfo objects to be instantiated. This wasn't an issue
3020 * in the Python implementation (__init__() could raise NotImplementedError
3021 * there without ill effect), but doing so in the C implementation hit a
3022 * brick wall.
3023 */
3024
3025static PyObject *
3026tzinfo_nogo(const char* methodname)
3027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003028 PyErr_Format(PyExc_NotImplementedError,
3029 "a tzinfo subclass must implement %s()",
3030 methodname);
3031 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003032}
3033
3034/* Methods. A subclass must implement these. */
3035
Tim Peters52dcce22003-01-23 16:36:11 +00003036static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003037tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3038{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003039 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003040}
3041
Tim Peters52dcce22003-01-23 16:36:11 +00003042static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003043tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003045 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003046}
3047
Tim Peters52dcce22003-01-23 16:36:11 +00003048static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003049tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003051 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003052}
3053
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003054
3055static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3056 PyDateTime_Delta *delta,
3057 int factor);
3058static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3059static PyObject *datetime_dst(PyObject *self, PyObject *);
3060
Tim Peters52dcce22003-01-23 16:36:11 +00003061static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003062tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003063{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003064 PyObject *result = NULL;
3065 PyObject *off = NULL, *dst = NULL;
3066 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003067
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003068 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003069 PyErr_SetString(PyExc_TypeError,
3070 "fromutc: argument must be a datetime");
3071 return NULL;
3072 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003073 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003074 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3075 "is not self");
3076 return NULL;
3077 }
Tim Peters52dcce22003-01-23 16:36:11 +00003078
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003079 off = datetime_utcoffset(dt, NULL);
3080 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003081 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003082 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3084 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003085 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003086 }
Tim Peters52dcce22003-01-23 16:36:11 +00003087
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003088 dst = datetime_dst(dt, NULL);
3089 if (dst == NULL)
3090 goto Fail;
3091 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003092 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3093 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003094 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003095 }
Tim Peters52dcce22003-01-23 16:36:11 +00003096
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003097 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3098 if (delta == NULL)
3099 goto Fail;
3100 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003101 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003102 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003103
3104 Py_DECREF(dst);
3105 dst = call_dst(GET_DT_TZINFO(dt), result);
3106 if (dst == NULL)
3107 goto Fail;
3108 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003109 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003110 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003111 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003112 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003113 if (result == NULL)
3114 goto Fail;
3115 }
3116 Py_DECREF(delta);
3117 Py_DECREF(dst);
3118 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003119 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003120
3121Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3123 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003126Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003127 Py_XDECREF(off);
3128 Py_XDECREF(dst);
3129 Py_XDECREF(delta);
3130 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003131 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003132}
3133
Tim Peters2a799bf2002-12-16 20:18:38 +00003134/*
3135 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003136 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003137 */
3138
Guido van Rossum177e41a2003-01-30 22:06:23 +00003139static PyObject *
3140tzinfo_reduce(PyObject *self)
3141{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003142 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003144 _Py_IDENTIFIER(__getinitargs__);
3145 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003146
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003147 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003148 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003149 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003150 Py_DECREF(getinitargs);
3151 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003152 return NULL;
3153 }
3154 }
3155 else {
3156 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003157
3158 args = PyTuple_New(0);
3159 if (args == NULL) {
3160 return NULL;
3161 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003162 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003163
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003164 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003165 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003166 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003167 Py_DECREF(getstate);
3168 if (state == NULL) {
3169 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003170 return NULL;
3171 }
3172 }
3173 else {
3174 PyObject **dictptr;
3175 PyErr_Clear();
3176 state = Py_None;
3177 dictptr = _PyObject_GetDictPtr(self);
Victor Stinnerd1584d32016-08-23 00:11:04 +02003178 if (dictptr && *dictptr && PyDict_Size(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003179 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003180 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003181 Py_INCREF(state);
3182 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003184 if (state == Py_None) {
3185 Py_DECREF(state);
3186 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3187 }
3188 else
3189 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003190}
Tim Peters2a799bf2002-12-16 20:18:38 +00003191
3192static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003194 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3195 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003197 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003198 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3199 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003201 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3202 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003204 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003205 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003207 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3208 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003210 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003211};
3212
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003213static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003214PyDoc_STR("Abstract base class for time zone info objects.");
3215
Neal Norwitz227b5332006-03-22 09:28:35 +00003216static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 PyVarObject_HEAD_INIT(NULL, 0)
3218 "datetime.tzinfo", /* tp_name */
3219 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3220 0, /* tp_itemsize */
3221 0, /* tp_dealloc */
3222 0, /* tp_print */
3223 0, /* tp_getattr */
3224 0, /* tp_setattr */
3225 0, /* tp_reserved */
3226 0, /* tp_repr */
3227 0, /* tp_as_number */
3228 0, /* tp_as_sequence */
3229 0, /* tp_as_mapping */
3230 0, /* tp_hash */
3231 0, /* tp_call */
3232 0, /* tp_str */
3233 PyObject_GenericGetAttr, /* tp_getattro */
3234 0, /* tp_setattro */
3235 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003236 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003237 tzinfo_doc, /* tp_doc */
3238 0, /* tp_traverse */
3239 0, /* tp_clear */
3240 0, /* tp_richcompare */
3241 0, /* tp_weaklistoffset */
3242 0, /* tp_iter */
3243 0, /* tp_iternext */
3244 tzinfo_methods, /* tp_methods */
3245 0, /* tp_members */
3246 0, /* tp_getset */
3247 0, /* tp_base */
3248 0, /* tp_dict */
3249 0, /* tp_descr_get */
3250 0, /* tp_descr_set */
3251 0, /* tp_dictoffset */
3252 0, /* tp_init */
3253 0, /* tp_alloc */
3254 PyType_GenericNew, /* tp_new */
3255 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003256};
3257
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003258static char *timezone_kws[] = {"offset", "name", NULL};
3259
3260static PyObject *
3261timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3262{
3263 PyObject *offset;
3264 PyObject *name = NULL;
3265 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3266 &PyDateTime_DeltaType, &offset,
3267 &PyUnicode_Type, &name))
3268 return new_timezone(offset, name);
3269
3270 return NULL;
3271}
3272
3273static void
3274timezone_dealloc(PyDateTime_TimeZone *self)
3275{
3276 Py_CLEAR(self->offset);
3277 Py_CLEAR(self->name);
3278 Py_TYPE(self)->tp_free((PyObject *)self);
3279}
3280
3281static PyObject *
3282timezone_richcompare(PyDateTime_TimeZone *self,
3283 PyDateTime_TimeZone *other, int op)
3284{
Brian Curtindfc80e32011-08-10 20:28:54 -05003285 if (op != Py_EQ && op != Py_NE)
3286 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003287 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003288 if (op == Py_EQ)
3289 Py_RETURN_FALSE;
3290 else
3291 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003292 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003293 return delta_richcompare(self->offset, other->offset, op);
3294}
3295
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003296static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003297timezone_hash(PyDateTime_TimeZone *self)
3298{
3299 return delta_hash((PyDateTime_Delta *)self->offset);
3300}
3301
3302/* Check argument type passed to tzname, utcoffset, or dst methods.
3303 Returns 0 for good argument. Returns -1 and sets exception info
3304 otherwise.
3305 */
3306static int
3307_timezone_check_argument(PyObject *dt, const char *meth)
3308{
3309 if (dt == Py_None || PyDateTime_Check(dt))
3310 return 0;
3311 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3312 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3313 return -1;
3314}
3315
3316static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003317timezone_repr(PyDateTime_TimeZone *self)
3318{
3319 /* Note that although timezone is not subclassable, it is convenient
3320 to use Py_TYPE(self)->tp_name here. */
3321 const char *type_name = Py_TYPE(self)->tp_name;
3322
3323 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3324 return PyUnicode_FromFormat("%s.utc", type_name);
3325
3326 if (self->name == NULL)
3327 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3328
3329 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3330 self->name);
3331}
3332
3333
3334static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003335timezone_str(PyDateTime_TimeZone *self)
3336{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003337 int hours, minutes, seconds;
3338 PyObject *offset;
3339 char sign;
3340
3341 if (self->name != NULL) {
3342 Py_INCREF(self->name);
3343 return self->name;
3344 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003345 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003346 (GET_TD_DAYS(self->offset) == 0 &&
3347 GET_TD_SECONDS(self->offset) == 0 &&
3348 GET_TD_MICROSECONDS(self->offset) == 0))
3349 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003350 /* Offset is normalized, so it is negative if days < 0 */
3351 if (GET_TD_DAYS(self->offset) < 0) {
3352 sign = '-';
3353 offset = delta_negative((PyDateTime_Delta *)self->offset);
3354 if (offset == NULL)
3355 return NULL;
3356 }
3357 else {
3358 sign = '+';
3359 offset = self->offset;
3360 Py_INCREF(offset);
3361 }
3362 /* Offset is not negative here. */
3363 seconds = GET_TD_SECONDS(offset);
3364 Py_DECREF(offset);
3365 minutes = divmod(seconds, 60, &seconds);
3366 hours = divmod(minutes, 60, &minutes);
Martin Pantere26da7c2016-06-02 10:07:09 +00003367 /* XXX ignore sub-minute data, currently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003368 assert(seconds == 0);
3369 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003370}
3371
3372static PyObject *
3373timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3374{
3375 if (_timezone_check_argument(dt, "tzname") == -1)
3376 return NULL;
3377
3378 return timezone_str(self);
3379}
3380
3381static PyObject *
3382timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3383{
3384 if (_timezone_check_argument(dt, "utcoffset") == -1)
3385 return NULL;
3386
3387 Py_INCREF(self->offset);
3388 return self->offset;
3389}
3390
3391static PyObject *
3392timezone_dst(PyObject *self, PyObject *dt)
3393{
3394 if (_timezone_check_argument(dt, "dst") == -1)
3395 return NULL;
3396
3397 Py_RETURN_NONE;
3398}
3399
3400static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003401timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3402{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003403 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003404 PyErr_SetString(PyExc_TypeError,
3405 "fromutc: argument must be a datetime");
3406 return NULL;
3407 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003408 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003409 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3410 "is not self");
3411 return NULL;
3412 }
3413
3414 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3415}
3416
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003417static PyObject *
3418timezone_getinitargs(PyDateTime_TimeZone *self)
3419{
3420 if (self->name == NULL)
3421 return Py_BuildValue("(O)", self->offset);
3422 return Py_BuildValue("(OO)", self->offset, self->name);
3423}
3424
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003425static PyMethodDef timezone_methods[] = {
3426 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3427 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003428 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003429
3430 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003431 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003432
3433 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003434 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003435
3436 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3437 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3438
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003439 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3440 PyDoc_STR("pickle support")},
3441
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003442 {NULL, NULL}
3443};
3444
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003445static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003446PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3447
3448static PyTypeObject PyDateTime_TimeZoneType = {
3449 PyVarObject_HEAD_INIT(NULL, 0)
3450 "datetime.timezone", /* tp_name */
3451 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3452 0, /* tp_itemsize */
3453 (destructor)timezone_dealloc, /* tp_dealloc */
3454 0, /* tp_print */
3455 0, /* tp_getattr */
3456 0, /* tp_setattr */
3457 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003458 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003459 0, /* tp_as_number */
3460 0, /* tp_as_sequence */
3461 0, /* tp_as_mapping */
3462 (hashfunc)timezone_hash, /* tp_hash */
3463 0, /* tp_call */
3464 (reprfunc)timezone_str, /* tp_str */
3465 0, /* tp_getattro */
3466 0, /* tp_setattro */
3467 0, /* tp_as_buffer */
3468 Py_TPFLAGS_DEFAULT, /* tp_flags */
3469 timezone_doc, /* tp_doc */
3470 0, /* tp_traverse */
3471 0, /* tp_clear */
3472 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3473 0, /* tp_weaklistoffset */
3474 0, /* tp_iter */
3475 0, /* tp_iternext */
3476 timezone_methods, /* tp_methods */
3477 0, /* tp_members */
3478 0, /* tp_getset */
3479 &PyDateTime_TZInfoType, /* tp_base */
3480 0, /* tp_dict */
3481 0, /* tp_descr_get */
3482 0, /* tp_descr_set */
3483 0, /* tp_dictoffset */
3484 0, /* tp_init */
3485 0, /* tp_alloc */
3486 timezone_new, /* tp_new */
3487};
3488
Tim Peters2a799bf2002-12-16 20:18:38 +00003489/*
Tim Peters37f39822003-01-10 03:49:02 +00003490 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003491 */
3492
Tim Peters37f39822003-01-10 03:49:02 +00003493/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003494 */
3495
3496static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003497time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003499 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003500}
3501
Tim Peters37f39822003-01-10 03:49:02 +00003502static PyObject *
3503time_minute(PyDateTime_Time *self, void *unused)
3504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003505 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003506}
3507
3508/* The name time_second conflicted with some platform header file. */
3509static PyObject *
3510py_time_second(PyDateTime_Time *self, void *unused)
3511{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003512 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003513}
3514
3515static PyObject *
3516time_microsecond(PyDateTime_Time *self, void *unused)
3517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003518 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003519}
3520
3521static PyObject *
3522time_tzinfo(PyDateTime_Time *self, void *unused)
3523{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003524 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3525 Py_INCREF(result);
3526 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003527}
3528
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003529static PyObject *
3530time_fold(PyDateTime_Time *self, void *unused)
3531{
3532 return PyLong_FromLong(TIME_GET_FOLD(self));
3533}
3534
Tim Peters37f39822003-01-10 03:49:02 +00003535static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003536 {"hour", (getter)time_hour},
3537 {"minute", (getter)time_minute},
3538 {"second", (getter)py_time_second},
3539 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003540 {"tzinfo", (getter)time_tzinfo},
3541 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003542 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003543};
3544
3545/*
3546 * Constructors.
3547 */
3548
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003549static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003550 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003551
Tim Peters2a799bf2002-12-16 20:18:38 +00003552static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003553time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 PyObject *self = NULL;
3556 PyObject *state;
3557 int hour = 0;
3558 int minute = 0;
3559 int second = 0;
3560 int usecond = 0;
3561 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003562 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003564 /* Check for invocation from pickle with __getstate__ state */
3565 if (PyTuple_GET_SIZE(args) >= 1 &&
3566 PyTuple_GET_SIZE(args) <= 2 &&
3567 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3568 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003569 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003570 {
3571 PyDateTime_Time *me;
3572 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003574 if (PyTuple_GET_SIZE(args) == 2) {
3575 tzinfo = PyTuple_GET_ITEM(args, 1);
3576 if (check_tzinfo_subclass(tzinfo) < 0) {
3577 PyErr_SetString(PyExc_TypeError, "bad "
3578 "tzinfo state arg");
3579 return NULL;
3580 }
3581 }
3582 aware = (char)(tzinfo != Py_None);
3583 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3584 if (me != NULL) {
3585 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003587 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3588 me->hashcode = -1;
3589 me->hastzinfo = aware;
3590 if (aware) {
3591 Py_INCREF(tzinfo);
3592 me->tzinfo = tzinfo;
3593 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003594 if (pdata[0] & (1 << 7)) {
3595 me->data[0] -= 128;
3596 me->fold = 1;
3597 }
3598 else {
3599 me->fold = 0;
3600 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003601 }
3602 return (PyObject *)me;
3603 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003604
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003605 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003606 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003607 &tzinfo, &fold)) {
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003608 if (check_time_args(hour, minute, second, usecond, fold) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003609 return NULL;
3610 if (check_tzinfo_subclass(tzinfo) < 0)
3611 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003612 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3613 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003614 }
3615 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003616}
3617
3618/*
3619 * Destructor.
3620 */
3621
3622static void
Tim Peters37f39822003-01-10 03:49:02 +00003623time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003625 if (HASTZINFO(self)) {
3626 Py_XDECREF(self->tzinfo);
3627 }
3628 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003629}
3630
3631/*
Tim Peters855fe882002-12-22 03:43:39 +00003632 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003633 */
3634
Tim Peters2a799bf2002-12-16 20:18:38 +00003635/* These are all METH_NOARGS, so don't need to check the arglist. */
3636static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003637time_utcoffset(PyObject *self, PyObject *unused) {
3638 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003639}
3640
3641static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003642time_dst(PyObject *self, PyObject *unused) {
3643 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003644}
3645
3646static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003647time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003648 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003649}
3650
3651/*
Tim Peters37f39822003-01-10 03:49:02 +00003652 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003653 */
3654
3655static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003656time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003657{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003658 const char *type_name = Py_TYPE(self)->tp_name;
3659 int h = TIME_GET_HOUR(self);
3660 int m = TIME_GET_MINUTE(self);
3661 int s = TIME_GET_SECOND(self);
3662 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003663 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003664 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003666 if (us)
3667 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3668 type_name, h, m, s, us);
3669 else if (s)
3670 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3671 type_name, h, m, s);
3672 else
3673 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3674 if (result != NULL && HASTZINFO(self))
3675 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003676 if (result != NULL && fold)
3677 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003678 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003679}
3680
Tim Peters37f39822003-01-10 03:49:02 +00003681static PyObject *
3682time_str(PyDateTime_Time *self)
3683{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003684 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003685}
Tim Peters2a799bf2002-12-16 20:18:38 +00003686
3687static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003688time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003689{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003690 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003691 char *timespec = NULL;
3692 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003693 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003694 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003695 static char *specs[][2] = {
3696 {"hours", "%02d"},
3697 {"minutes", "%02d:%02d"},
3698 {"seconds", "%02d:%02d:%02d"},
3699 {"milliseconds", "%02d:%02d:%02d.%03d"},
3700 {"microseconds", "%02d:%02d:%02d.%06d"},
3701 };
3702 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003703
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003704 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3705 return NULL;
3706
3707 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3708 if (us == 0) {
3709 /* seconds */
3710 given_spec = 2;
3711 }
3712 else {
3713 /* microseconds */
3714 given_spec = 4;
3715 }
3716 }
3717 else {
3718 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3719 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3720 if (given_spec == 3) {
3721 /* milliseconds */
3722 us = us / 1000;
3723 }
3724 break;
3725 }
3726 }
3727 }
3728
3729 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3730 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3731 return NULL;
3732 }
3733 else {
3734 result = PyUnicode_FromFormat(specs[given_spec][1],
3735 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3736 TIME_GET_SECOND(self), us);
3737 }
Tim Peters37f39822003-01-10 03:49:02 +00003738
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003739 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003740 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003742 /* We need to append the UTC offset. */
3743 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3744 Py_None) < 0) {
3745 Py_DECREF(result);
3746 return NULL;
3747 }
3748 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3749 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003750}
3751
Tim Peters37f39822003-01-10 03:49:02 +00003752static PyObject *
3753time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3754{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003755 PyObject *result;
3756 PyObject *tuple;
3757 PyObject *format;
3758 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003760 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3761 &format))
3762 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003764 /* Python's strftime does insane things with the year part of the
3765 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003766 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003767 */
3768 tuple = Py_BuildValue("iiiiiiiii",
3769 1900, 1, 1, /* year, month, day */
3770 TIME_GET_HOUR(self),
3771 TIME_GET_MINUTE(self),
3772 TIME_GET_SECOND(self),
3773 0, 1, -1); /* weekday, daynum, dst */
3774 if (tuple == NULL)
3775 return NULL;
3776 assert(PyTuple_Size(tuple) == 9);
3777 result = wrap_strftime((PyObject *)self, format, tuple,
3778 Py_None);
3779 Py_DECREF(tuple);
3780 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003781}
Tim Peters2a799bf2002-12-16 20:18:38 +00003782
3783/*
3784 * Miscellaneous methods.
3785 */
3786
Tim Peters37f39822003-01-10 03:49:02 +00003787static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003788time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003789{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003790 PyObject *result = NULL;
3791 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003792 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003793
Brian Curtindfc80e32011-08-10 20:28:54 -05003794 if (! PyTime_Check(other))
3795 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003796
3797 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003798 diff = memcmp(((PyDateTime_Time *)self)->data,
3799 ((PyDateTime_Time *)other)->data,
3800 _PyDateTime_TIME_DATASIZE);
3801 return diff_to_bool(diff, op);
3802 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003803 offset1 = time_utcoffset(self, NULL);
3804 if (offset1 == NULL)
3805 return NULL;
3806 offset2 = time_utcoffset(other, NULL);
3807 if (offset2 == NULL)
3808 goto done;
3809 /* If they're both naive, or both aware and have the same offsets,
3810 * we get off cheap. Note that if they're both naive, offset1 ==
3811 * offset2 == Py_None at this point.
3812 */
3813 if ((offset1 == offset2) ||
3814 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3815 delta_cmp(offset1, offset2) == 0)) {
3816 diff = memcmp(((PyDateTime_Time *)self)->data,
3817 ((PyDateTime_Time *)other)->data,
3818 _PyDateTime_TIME_DATASIZE);
3819 result = diff_to_bool(diff, op);
3820 }
3821 /* The hard case: both aware with different UTC offsets */
3822 else if (offset1 != Py_None && offset2 != Py_None) {
3823 int offsecs1, offsecs2;
3824 assert(offset1 != offset2); /* else last "if" handled it */
3825 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3826 TIME_GET_MINUTE(self) * 60 +
3827 TIME_GET_SECOND(self) -
3828 GET_TD_DAYS(offset1) * 86400 -
3829 GET_TD_SECONDS(offset1);
3830 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3831 TIME_GET_MINUTE(other) * 60 +
3832 TIME_GET_SECOND(other) -
3833 GET_TD_DAYS(offset2) * 86400 -
3834 GET_TD_SECONDS(offset2);
3835 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003836 if (diff == 0)
3837 diff = TIME_GET_MICROSECOND(self) -
3838 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003839 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003840 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003841 else if (op == Py_EQ) {
3842 result = Py_False;
3843 Py_INCREF(result);
3844 }
3845 else if (op == Py_NE) {
3846 result = Py_True;
3847 Py_INCREF(result);
3848 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003849 else {
3850 PyErr_SetString(PyExc_TypeError,
3851 "can't compare offset-naive and "
3852 "offset-aware times");
3853 }
3854 done:
3855 Py_DECREF(offset1);
3856 Py_XDECREF(offset2);
3857 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003858}
3859
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003860static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003861time_hash(PyDateTime_Time *self)
3862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003863 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003864 PyObject *offset, *self0;
3865 if (DATE_GET_FOLD(self)) {
3866 self0 = new_time_ex2(DATE_GET_HOUR(self),
3867 DATE_GET_MINUTE(self),
3868 DATE_GET_SECOND(self),
3869 DATE_GET_MICROSECOND(self),
3870 HASTZINFO(self) ? self->tzinfo : Py_None,
3871 0, Py_TYPE(self));
3872 if (self0 == NULL)
3873 return -1;
3874 }
3875 else {
3876 self0 = (PyObject *)self;
3877 Py_INCREF(self0);
3878 }
3879 offset = time_utcoffset(self0, NULL);
3880 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003881
3882 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003885 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003886 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003887 self->hashcode = generic_hash(
3888 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003889 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003890 PyObject *temp1, *temp2;
3891 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003892 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003893 seconds = TIME_GET_HOUR(self) * 3600 +
3894 TIME_GET_MINUTE(self) * 60 +
3895 TIME_GET_SECOND(self);
3896 microseconds = TIME_GET_MICROSECOND(self);
3897 temp1 = new_delta(0, seconds, microseconds, 1);
3898 if (temp1 == NULL) {
3899 Py_DECREF(offset);
3900 return -1;
3901 }
3902 temp2 = delta_subtract(temp1, offset);
3903 Py_DECREF(temp1);
3904 if (temp2 == NULL) {
3905 Py_DECREF(offset);
3906 return -1;
3907 }
3908 self->hashcode = PyObject_Hash(temp2);
3909 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003910 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003911 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003912 }
3913 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003914}
Tim Peters2a799bf2002-12-16 20:18:38 +00003915
Tim Peters12bf3392002-12-24 05:41:27 +00003916static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003917time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003918{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003919 PyObject *clone;
3920 PyObject *tuple;
3921 int hh = TIME_GET_HOUR(self);
3922 int mm = TIME_GET_MINUTE(self);
3923 int ss = TIME_GET_SECOND(self);
3924 int us = TIME_GET_MICROSECOND(self);
3925 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003926 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003927
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003928 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003929 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003930 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003931 return NULL;
3932 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3933 if (tuple == NULL)
3934 return NULL;
3935 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003936 if (clone != NULL) {
3937 if (fold != 0 && fold != 1) {
3938 PyErr_SetString(PyExc_ValueError,
3939 "fold must be either 0 or 1");
3940 return NULL;
3941 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003942 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003943 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003944 Py_DECREF(tuple);
3945 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003946}
3947
Tim Peters371935f2003-02-01 01:52:50 +00003948/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003949
Tim Peters33e0f382003-01-10 02:05:14 +00003950/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003951 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3952 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003953 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003954 */
3955static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003956time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00003957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003958 PyObject *basestate;
3959 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003961 basestate = PyBytes_FromStringAndSize((char *)self->data,
3962 _PyDateTime_TIME_DATASIZE);
3963 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003964 if (proto > 3 && TIME_GET_FOLD(self))
3965 /* Set the first bit of the first byte */
3966 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003967 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3968 result = PyTuple_Pack(1, basestate);
3969 else
3970 result = PyTuple_Pack(2, basestate, self->tzinfo);
3971 Py_DECREF(basestate);
3972 }
3973 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003974}
3975
3976static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003977time_reduce(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00003978{
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003979 int proto = 0;
3980 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
3981 return NULL;
3982
3983 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00003984}
3985
Tim Peters37f39822003-01-10 03:49:02 +00003986static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003987
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003988 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
3989 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
3990 "[+HH:MM].\n\n"
3991 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003993 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3994 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003996 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3997 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003999 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4000 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004002 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4003 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004005 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4006 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004008 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4009 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004010
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004011 {"__reduce_ex__", (PyCFunction)time_reduce, METH_VARARGS,
4012 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004014 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004015};
4016
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004017static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004018PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4019\n\
4020All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004021a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004022
Neal Norwitz227b5332006-03-22 09:28:35 +00004023static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004024 PyVarObject_HEAD_INIT(NULL, 0)
4025 "datetime.time", /* tp_name */
4026 sizeof(PyDateTime_Time), /* tp_basicsize */
4027 0, /* tp_itemsize */
4028 (destructor)time_dealloc, /* tp_dealloc */
4029 0, /* tp_print */
4030 0, /* tp_getattr */
4031 0, /* tp_setattr */
4032 0, /* tp_reserved */
4033 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004034 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004035 0, /* tp_as_sequence */
4036 0, /* tp_as_mapping */
4037 (hashfunc)time_hash, /* tp_hash */
4038 0, /* tp_call */
4039 (reprfunc)time_str, /* tp_str */
4040 PyObject_GenericGetAttr, /* tp_getattro */
4041 0, /* tp_setattro */
4042 0, /* tp_as_buffer */
4043 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4044 time_doc, /* tp_doc */
4045 0, /* tp_traverse */
4046 0, /* tp_clear */
4047 time_richcompare, /* tp_richcompare */
4048 0, /* tp_weaklistoffset */
4049 0, /* tp_iter */
4050 0, /* tp_iternext */
4051 time_methods, /* tp_methods */
4052 0, /* tp_members */
4053 time_getset, /* tp_getset */
4054 0, /* tp_base */
4055 0, /* tp_dict */
4056 0, /* tp_descr_get */
4057 0, /* tp_descr_set */
4058 0, /* tp_dictoffset */
4059 0, /* tp_init */
4060 time_alloc, /* tp_alloc */
4061 time_new, /* tp_new */
4062 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004063};
4064
4065/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004066 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004067 */
4068
Tim Petersa9bc1682003-01-11 03:39:11 +00004069/* Accessor properties. Properties for day, month, and year are inherited
4070 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004071 */
4072
4073static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004074datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004076 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004077}
4078
Tim Petersa9bc1682003-01-11 03:39:11 +00004079static PyObject *
4080datetime_minute(PyDateTime_DateTime *self, void *unused)
4081{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004082 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004083}
4084
4085static PyObject *
4086datetime_second(PyDateTime_DateTime *self, void *unused)
4087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004088 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004089}
4090
4091static PyObject *
4092datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004094 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004095}
4096
4097static PyObject *
4098datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004100 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4101 Py_INCREF(result);
4102 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004103}
4104
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004105static PyObject *
4106datetime_fold(PyDateTime_DateTime *self, void *unused)
4107{
4108 return PyLong_FromLong(DATE_GET_FOLD(self));
4109}
4110
Tim Petersa9bc1682003-01-11 03:39:11 +00004111static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004112 {"hour", (getter)datetime_hour},
4113 {"minute", (getter)datetime_minute},
4114 {"second", (getter)datetime_second},
4115 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004116 {"tzinfo", (getter)datetime_tzinfo},
4117 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004118 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004119};
4120
4121/*
4122 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004123 */
4124
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004125static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004126 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004127 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004128};
4129
Tim Peters2a799bf2002-12-16 20:18:38 +00004130static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004131datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004133 PyObject *self = NULL;
4134 PyObject *state;
4135 int year;
4136 int month;
4137 int day;
4138 int hour = 0;
4139 int minute = 0;
4140 int second = 0;
4141 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004142 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004143 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004145 /* Check for invocation from pickle with __getstate__ state */
4146 if (PyTuple_GET_SIZE(args) >= 1 &&
4147 PyTuple_GET_SIZE(args) <= 2 &&
4148 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4149 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004150 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004151 {
4152 PyDateTime_DateTime *me;
4153 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004155 if (PyTuple_GET_SIZE(args) == 2) {
4156 tzinfo = PyTuple_GET_ITEM(args, 1);
4157 if (check_tzinfo_subclass(tzinfo) < 0) {
4158 PyErr_SetString(PyExc_TypeError, "bad "
4159 "tzinfo state arg");
4160 return NULL;
4161 }
4162 }
4163 aware = (char)(tzinfo != Py_None);
4164 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4165 if (me != NULL) {
4166 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004168 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4169 me->hashcode = -1;
4170 me->hastzinfo = aware;
4171 if (aware) {
4172 Py_INCREF(tzinfo);
4173 me->tzinfo = tzinfo;
4174 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004175 if (pdata[2] & (1 << 7)) {
4176 me->data[2] -= 128;
4177 me->fold = 1;
4178 }
4179 else {
4180 me->fold = 0;
4181 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004182 }
4183 return (PyObject *)me;
4184 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004185
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004186 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004187 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004188 &second, &usecond, &tzinfo, &fold)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004189 if (check_date_args(year, month, day) < 0)
4190 return NULL;
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004191 if (check_time_args(hour, minute, second, usecond, fold) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004192 return NULL;
4193 if (check_tzinfo_subclass(tzinfo) < 0)
4194 return NULL;
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 Belopolsky6d88fa52016-09-10 15:58:31 -04004202/* TM_FUNC is the shared type of localtime_r() and gmtime_r(). */
4203typedef struct tm *(*TM_FUNC)(const time_t *timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004204
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004205/* As of version 2015f max fold in IANA database is
4206 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004207static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004208/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004209static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004210
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004211static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004212utc_to_seconds(int year, int month, int day,
4213 int hour, int minute, int second)
4214{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004215 long long ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004216 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4217}
4218
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004219static long long
4220local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004221{
4222 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004223 time_t t;
4224 u -= epoch;
4225 t = u;
4226 if (t != u) {
4227 PyErr_SetString(PyExc_OverflowError,
4228 "timestamp out of range for platform time_t");
4229 return -1;
4230 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004231 /* XXX: add bounds checking */
4232 if (localtime_r(&t, &local_time) == NULL) {
4233 PyErr_SetFromErrno(PyExc_OSError);
4234 return -1;
4235 }
4236 return utc_to_seconds(local_time.tm_year + 1900,
4237 local_time.tm_mon + 1,
4238 local_time.tm_mday,
4239 local_time.tm_hour,
4240 local_time.tm_min,
4241 local_time.tm_sec);
4242}
4243
Tim Petersa9bc1682003-01-11 03:39:11 +00004244/* Internal helper.
4245 * Build datetime from a time_t and a distinct count of microseconds.
4246 * Pass localtime or gmtime for f, to control the interpretation of timet.
4247 */
4248static PyObject *
4249datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004250 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004251{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004252 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004253 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004254
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004255 if (f(&timet, &tm) == NULL) {
Victor Stinner21f58932012-03-14 00:15:40 +01004256#ifdef EINVAL
4257 if (errno == 0)
4258 errno = EINVAL;
4259#endif
4260 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004261 }
Victor Stinner21f58932012-03-14 00:15:40 +01004262
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004263 year = tm.tm_year + 1900;
4264 month = tm.tm_mon + 1;
4265 day = tm.tm_mday;
4266 hour = tm.tm_hour;
4267 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004268 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004269 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004270 * except to the extent that passing them on to the datetime
4271 * constructor would raise ValueError for a reason that
4272 * made no sense to the user.
4273 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004274 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004275
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004276 if (tzinfo == Py_None && f == localtime_r) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004277 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004278
4279 result_seconds = utc_to_seconds(year, month, day,
4280 hour, minute, second);
4281 /* Probe max_fold_seconds to detect a fold. */
4282 probe_seconds = local(epoch + timet - max_fold_seconds);
4283 if (probe_seconds == -1)
4284 return NULL;
4285 transition = result_seconds - probe_seconds - max_fold_seconds;
4286 if (transition < 0) {
4287 probe_seconds = local(epoch + timet + transition);
4288 if (probe_seconds == -1)
4289 return NULL;
4290 if (probe_seconds == result_seconds)
4291 fold = 1;
4292 }
4293 }
4294 return new_datetime_ex2(year, month, day, hour,
4295 minute, second, us, tzinfo, fold,
4296 (PyTypeObject *)cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004297}
4298
4299/* Internal helper.
4300 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4301 * to control the interpretation of the timestamp. Since a double doesn't
4302 * have enough bits to cover a datetime's full range of precision, it's
4303 * better to call datetime_from_timet_and_us provided you have a way
4304 * to get that much precision (e.g., C time() isn't good enough).
4305 */
4306static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004307datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004308 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004310 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004311 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004312
Victor Stinnere4a994d2015-03-30 01:10:14 +02004313 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004314 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004315 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004316
Victor Stinner21f58932012-03-14 00:15:40 +01004317 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004318}
4319
4320/* Internal helper.
4321 * Build most accurate possible datetime for current time. Pass localtime or
4322 * gmtime for f as appropriate.
4323 */
4324static PyObject *
4325datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4326{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004327 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004328 time_t secs;
4329 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004330
Victor Stinner1e2b6882015-09-18 13:23:02 +02004331 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004332 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004333 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004334
Victor Stinner1e2b6882015-09-18 13:23:02 +02004335 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004336}
4337
Larry Hastings61272b72014-01-07 12:41:53 -08004338/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004339
4340@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004341datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004342
4343 tz: object = None
4344 Timezone object.
4345
4346Returns new datetime object representing current time local to tz.
4347
4348If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004349[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004350
Larry Hastings31826802013-10-19 00:09:25 -07004351static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004352datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004353/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004355 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004356
Larry Hastings31826802013-10-19 00:09:25 -07004357 /* Return best possible local time -- this isn't constrained by the
4358 * precision of a timestamp.
4359 */
4360 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004361 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004362
Larry Hastings5c661892014-01-24 06:17:25 -08004363 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004364 tz == Py_None ? localtime_r : gmtime_r,
Larry Hastings31826802013-10-19 00:09:25 -07004365 tz);
4366 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004367 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004368 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004369 }
4370 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004371}
4372
Tim Petersa9bc1682003-01-11 03:39:11 +00004373/* Return best possible UTC time -- this isn't constrained by the
4374 * precision of a timestamp.
4375 */
4376static PyObject *
4377datetime_utcnow(PyObject *cls, PyObject *dummy)
4378{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004379 return datetime_best_possible(cls, gmtime_r, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004380}
4381
Tim Peters2a799bf2002-12-16 20:18:38 +00004382/* Return new local datetime from timestamp (Python timestamp -- a double). */
4383static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004384datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004386 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004387 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004388 PyObject *tzinfo = Py_None;
4389 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004390
Victor Stinner5d272cc2012-03-13 13:35:55 +01004391 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004392 keywords, &timestamp, &tzinfo))
4393 return NULL;
4394 if (check_tzinfo_subclass(tzinfo) < 0)
4395 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004397 self = datetime_from_timestamp(cls,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004398 tzinfo == Py_None ? localtime_r : gmtime_r,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004399 timestamp,
4400 tzinfo);
4401 if (self != NULL && tzinfo != Py_None) {
4402 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004403 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004404 }
4405 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004406}
4407
Tim Petersa9bc1682003-01-11 03:39:11 +00004408/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4409static PyObject *
4410datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4411{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004412 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004413 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004414
Victor Stinner5d272cc2012-03-13 13:35:55 +01004415 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004416 result = datetime_from_timestamp(cls, gmtime_r, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004417 Py_None);
4418 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004419}
4420
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004421/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004422static PyObject *
4423datetime_strptime(PyObject *cls, PyObject *args)
4424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004425 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004426 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004427 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004428
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004429 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004430 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004431
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004432 if (module == NULL) {
4433 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004434 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004435 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004436 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004437 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4438 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004439}
4440
Tim Petersa9bc1682003-01-11 03:39:11 +00004441/* Return new datetime from date/datetime and time arguments. */
4442static PyObject *
4443datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4444{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004445 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004446 PyObject *date;
4447 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004448 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004449 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004450
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004451 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004452 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004453 &PyDateTime_TimeType, &time, &tzinfo)) {
4454 if (tzinfo == NULL) {
4455 if (HASTZINFO(time))
4456 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4457 else
4458 tzinfo = Py_None;
4459 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004460 result = PyObject_CallFunction(cls, "iiiiiiiO",
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004461 GET_YEAR(date),
4462 GET_MONTH(date),
4463 GET_DAY(date),
4464 TIME_GET_HOUR(time),
4465 TIME_GET_MINUTE(time),
4466 TIME_GET_SECOND(time),
4467 TIME_GET_MICROSECOND(time),
4468 tzinfo);
4469 if (result)
4470 DATE_SET_FOLD(result, TIME_GET_FOLD(time));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004471 }
4472 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004473}
Tim Peters2a799bf2002-12-16 20:18:38 +00004474
4475/*
4476 * Destructor.
4477 */
4478
4479static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004480datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004482 if (HASTZINFO(self)) {
4483 Py_XDECREF(self->tzinfo);
4484 }
4485 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004486}
4487
4488/*
4489 * Indirect access to tzinfo methods.
4490 */
4491
Tim Peters2a799bf2002-12-16 20:18:38 +00004492/* These are all METH_NOARGS, so don't need to check the arglist. */
4493static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004494datetime_utcoffset(PyObject *self, PyObject *unused) {
4495 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004496}
4497
4498static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004499datetime_dst(PyObject *self, PyObject *unused) {
4500 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004501}
4502
4503static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004504datetime_tzname(PyObject *self, PyObject *unused) {
4505 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004506}
4507
4508/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004509 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004510 */
4511
Tim Petersa9bc1682003-01-11 03:39:11 +00004512/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4513 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004514 */
4515static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004516add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004517 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004519 /* Note that the C-level additions can't overflow, because of
4520 * invariant bounds on the member values.
4521 */
4522 int year = GET_YEAR(date);
4523 int month = GET_MONTH(date);
4524 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4525 int hour = DATE_GET_HOUR(date);
4526 int minute = DATE_GET_MINUTE(date);
4527 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4528 int microsecond = DATE_GET_MICROSECOND(date) +
4529 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004531 assert(factor == 1 || factor == -1);
4532 if (normalize_datetime(&year, &month, &day,
4533 &hour, &minute, &second, &microsecond) < 0)
4534 return NULL;
4535 else
4536 return new_datetime(year, month, day,
4537 hour, minute, second, microsecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004538 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004539}
4540
4541static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004542datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004543{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 if (PyDateTime_Check(left)) {
4545 /* datetime + ??? */
4546 if (PyDelta_Check(right))
4547 /* datetime + delta */
4548 return add_datetime_timedelta(
4549 (PyDateTime_DateTime *)left,
4550 (PyDateTime_Delta *)right,
4551 1);
4552 }
4553 else if (PyDelta_Check(left)) {
4554 /* delta + datetime */
4555 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4556 (PyDateTime_Delta *) left,
4557 1);
4558 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004559 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004560}
4561
4562static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004563datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004564{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004565 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004567 if (PyDateTime_Check(left)) {
4568 /* datetime - ??? */
4569 if (PyDateTime_Check(right)) {
4570 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004571 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004572 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004573
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004574 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4575 offset2 = offset1 = Py_None;
4576 Py_INCREF(offset1);
4577 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004578 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004579 else {
4580 offset1 = datetime_utcoffset(left, NULL);
4581 if (offset1 == NULL)
4582 return NULL;
4583 offset2 = datetime_utcoffset(right, NULL);
4584 if (offset2 == NULL) {
4585 Py_DECREF(offset1);
4586 return NULL;
4587 }
4588 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4589 PyErr_SetString(PyExc_TypeError,
4590 "can't subtract offset-naive and "
4591 "offset-aware datetimes");
4592 Py_DECREF(offset1);
4593 Py_DECREF(offset2);
4594 return NULL;
4595 }
4596 }
4597 if ((offset1 != offset2) &&
4598 delta_cmp(offset1, offset2) != 0) {
4599 offdiff = delta_subtract(offset1, offset2);
4600 if (offdiff == NULL) {
4601 Py_DECREF(offset1);
4602 Py_DECREF(offset2);
4603 return NULL;
4604 }
4605 }
4606 Py_DECREF(offset1);
4607 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004608 delta_d = ymd_to_ord(GET_YEAR(left),
4609 GET_MONTH(left),
4610 GET_DAY(left)) -
4611 ymd_to_ord(GET_YEAR(right),
4612 GET_MONTH(right),
4613 GET_DAY(right));
4614 /* These can't overflow, since the values are
4615 * normalized. At most this gives the number of
4616 * seconds in one day.
4617 */
4618 delta_s = (DATE_GET_HOUR(left) -
4619 DATE_GET_HOUR(right)) * 3600 +
4620 (DATE_GET_MINUTE(left) -
4621 DATE_GET_MINUTE(right)) * 60 +
4622 (DATE_GET_SECOND(left) -
4623 DATE_GET_SECOND(right));
4624 delta_us = DATE_GET_MICROSECOND(left) -
4625 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004626 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004627 if (result == NULL)
4628 return NULL;
4629
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004630 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004631 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004632 Py_DECREF(offdiff);
4633 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004634 }
4635 else if (PyDelta_Check(right)) {
4636 /* datetime - delta */
4637 result = add_datetime_timedelta(
4638 (PyDateTime_DateTime *)left,
4639 (PyDateTime_Delta *)right,
4640 -1);
4641 }
4642 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004644 if (result == Py_NotImplemented)
4645 Py_INCREF(result);
4646 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004647}
4648
4649/* Various ways to turn a datetime into a string. */
4650
4651static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004652datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004654 const char *type_name = Py_TYPE(self)->tp_name;
4655 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004657 if (DATE_GET_MICROSECOND(self)) {
4658 baserepr = PyUnicode_FromFormat(
4659 "%s(%d, %d, %d, %d, %d, %d, %d)",
4660 type_name,
4661 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4662 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4663 DATE_GET_SECOND(self),
4664 DATE_GET_MICROSECOND(self));
4665 }
4666 else if (DATE_GET_SECOND(self)) {
4667 baserepr = PyUnicode_FromFormat(
4668 "%s(%d, %d, %d, %d, %d, %d)",
4669 type_name,
4670 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4671 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4672 DATE_GET_SECOND(self));
4673 }
4674 else {
4675 baserepr = PyUnicode_FromFormat(
4676 "%s(%d, %d, %d, %d, %d)",
4677 type_name,
4678 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4679 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4680 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004681 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4682 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 if (baserepr == NULL || ! HASTZINFO(self))
4684 return baserepr;
4685 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004686}
4687
Tim Petersa9bc1682003-01-11 03:39:11 +00004688static PyObject *
4689datetime_str(PyDateTime_DateTime *self)
4690{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004691 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004692}
Tim Peters2a799bf2002-12-16 20:18:38 +00004693
4694static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004695datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004696{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004697 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004698 char *timespec = NULL;
4699 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004700 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004701 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004702 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004703 static char *specs[][2] = {
4704 {"hours", "%04d-%02d-%02d%c%02d"},
4705 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4706 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4707 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4708 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4709 };
4710 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004711
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004712 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004713 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004714
4715 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4716 if (us == 0) {
4717 /* seconds */
4718 given_spec = 2;
4719 }
4720 else {
4721 /* microseconds */
4722 given_spec = 4;
4723 }
4724 }
4725 else {
4726 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4727 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4728 if (given_spec == 3) {
4729 us = us / 1000;
4730 }
4731 break;
4732 }
4733 }
4734 }
4735
4736 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4737 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4738 return NULL;
4739 }
4740 else {
4741 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004742 GET_YEAR(self), GET_MONTH(self),
4743 GET_DAY(self), (int)sep,
4744 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4745 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004746 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004748 if (!result || !HASTZINFO(self))
4749 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004751 /* We need to append the UTC offset. */
4752 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4753 (PyObject *)self) < 0) {
4754 Py_DECREF(result);
4755 return NULL;
4756 }
4757 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4758 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004759}
4760
Tim Petersa9bc1682003-01-11 03:39:11 +00004761static PyObject *
4762datetime_ctime(PyDateTime_DateTime *self)
4763{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004764 return format_ctime((PyDateTime_Date *)self,
4765 DATE_GET_HOUR(self),
4766 DATE_GET_MINUTE(self),
4767 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004768}
4769
Tim Peters2a799bf2002-12-16 20:18:38 +00004770/* Miscellaneous methods. */
4771
Tim Petersa9bc1682003-01-11 03:39:11 +00004772static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004773flip_fold(PyObject *dt)
4774{
4775 return new_datetime_ex2(GET_YEAR(dt),
4776 GET_MONTH(dt),
4777 GET_DAY(dt),
4778 DATE_GET_HOUR(dt),
4779 DATE_GET_MINUTE(dt),
4780 DATE_GET_SECOND(dt),
4781 DATE_GET_MICROSECOND(dt),
4782 HASTZINFO(dt) ?
4783 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4784 !DATE_GET_FOLD(dt),
4785 Py_TYPE(dt));
4786}
4787
4788static PyObject *
4789get_flip_fold_offset(PyObject *dt)
4790{
4791 PyObject *result, *flip_dt;
4792
4793 flip_dt = flip_fold(dt);
4794 if (flip_dt == NULL)
4795 return NULL;
4796 result = datetime_utcoffset(flip_dt, NULL);
4797 Py_DECREF(flip_dt);
4798 return result;
4799}
4800
4801/* PEP 495 exception: Whenever one or both of the operands in
4802 * inter-zone comparison is such that its utcoffset() depends
4803 * on the value of its fold fold attribute, the result is False.
4804 *
4805 * Return 1 if exception applies, 0 if not, and -1 on error.
4806 */
4807static int
4808pep495_eq_exception(PyObject *self, PyObject *other,
4809 PyObject *offset_self, PyObject *offset_other)
4810{
4811 int result = 0;
4812 PyObject *flip_offset;
4813
4814 flip_offset = get_flip_fold_offset(self);
4815 if (flip_offset == NULL)
4816 return -1;
4817 if (flip_offset != offset_self &&
4818 delta_cmp(flip_offset, offset_self))
4819 {
4820 result = 1;
4821 goto done;
4822 }
4823 Py_DECREF(flip_offset);
4824
4825 flip_offset = get_flip_fold_offset(other);
4826 if (flip_offset == NULL)
4827 return -1;
4828 if (flip_offset != offset_other &&
4829 delta_cmp(flip_offset, offset_other))
4830 result = 1;
4831 done:
4832 Py_DECREF(flip_offset);
4833 return result;
4834}
4835
4836static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004837datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004838{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004839 PyObject *result = NULL;
4840 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004841 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004843 if (! PyDateTime_Check(other)) {
4844 if (PyDate_Check(other)) {
4845 /* Prevent invocation of date_richcompare. We want to
4846 return NotImplemented here to give the other object
4847 a chance. But since DateTime is a subclass of
4848 Date, if the other object is a Date, it would
4849 compute an ordering based on the date part alone,
4850 and we don't want that. So force unequal or
4851 uncomparable here in that case. */
4852 if (op == Py_EQ)
4853 Py_RETURN_FALSE;
4854 if (op == Py_NE)
4855 Py_RETURN_TRUE;
4856 return cmperror(self, other);
4857 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004858 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004859 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004860
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004861 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004862 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4863 ((PyDateTime_DateTime *)other)->data,
4864 _PyDateTime_DATETIME_DATASIZE);
4865 return diff_to_bool(diff, op);
4866 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004867 offset1 = datetime_utcoffset(self, NULL);
4868 if (offset1 == NULL)
4869 return NULL;
4870 offset2 = datetime_utcoffset(other, NULL);
4871 if (offset2 == NULL)
4872 goto done;
4873 /* If they're both naive, or both aware and have the same offsets,
4874 * we get off cheap. Note that if they're both naive, offset1 ==
4875 * offset2 == Py_None at this point.
4876 */
4877 if ((offset1 == offset2) ||
4878 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4879 delta_cmp(offset1, offset2) == 0)) {
4880 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4881 ((PyDateTime_DateTime *)other)->data,
4882 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004883 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4884 int ex = pep495_eq_exception(self, other, offset1, offset2);
4885 if (ex == -1)
4886 goto done;
4887 if (ex)
4888 diff = 1;
4889 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004890 result = diff_to_bool(diff, op);
4891 }
4892 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004893 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004894
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004895 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004896 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4897 other);
4898 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004899 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004900 diff = GET_TD_DAYS(delta);
4901 if (diff == 0)
4902 diff = GET_TD_SECONDS(delta) |
4903 GET_TD_MICROSECONDS(delta);
4904 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004905 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4906 int ex = pep495_eq_exception(self, other, offset1, offset2);
4907 if (ex == -1)
4908 goto done;
4909 if (ex)
4910 diff = 1;
4911 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004912 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004913 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004914 else if (op == Py_EQ) {
4915 result = Py_False;
4916 Py_INCREF(result);
4917 }
4918 else if (op == Py_NE) {
4919 result = Py_True;
4920 Py_INCREF(result);
4921 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004922 else {
4923 PyErr_SetString(PyExc_TypeError,
4924 "can't compare offset-naive and "
4925 "offset-aware datetimes");
4926 }
4927 done:
4928 Py_DECREF(offset1);
4929 Py_XDECREF(offset2);
4930 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004931}
4932
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004933static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004934datetime_hash(PyDateTime_DateTime *self)
4935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004936 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004937 PyObject *offset, *self0;
4938 if (DATE_GET_FOLD(self)) {
4939 self0 = new_datetime_ex2(GET_YEAR(self),
4940 GET_MONTH(self),
4941 GET_DAY(self),
4942 DATE_GET_HOUR(self),
4943 DATE_GET_MINUTE(self),
4944 DATE_GET_SECOND(self),
4945 DATE_GET_MICROSECOND(self),
4946 HASTZINFO(self) ? self->tzinfo : Py_None,
4947 0, Py_TYPE(self));
4948 if (self0 == NULL)
4949 return -1;
4950 }
4951 else {
4952 self0 = (PyObject *)self;
4953 Py_INCREF(self0);
4954 }
4955 offset = datetime_utcoffset(self0, NULL);
4956 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004957
4958 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004959 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004961 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004962 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004963 self->hashcode = generic_hash(
4964 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004965 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004966 PyObject *temp1, *temp2;
4967 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004969 assert(HASTZINFO(self));
4970 days = ymd_to_ord(GET_YEAR(self),
4971 GET_MONTH(self),
4972 GET_DAY(self));
4973 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004974 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004975 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004976 temp1 = new_delta(days, seconds,
4977 DATE_GET_MICROSECOND(self),
4978 1);
4979 if (temp1 == NULL) {
4980 Py_DECREF(offset);
4981 return -1;
4982 }
4983 temp2 = delta_subtract(temp1, offset);
4984 Py_DECREF(temp1);
4985 if (temp2 == NULL) {
4986 Py_DECREF(offset);
4987 return -1;
4988 }
4989 self->hashcode = PyObject_Hash(temp2);
4990 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004991 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004992 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004993 }
4994 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004995}
Tim Peters2a799bf2002-12-16 20:18:38 +00004996
4997static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004998datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004999{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005000 PyObject *clone;
5001 PyObject *tuple;
5002 int y = GET_YEAR(self);
5003 int m = GET_MONTH(self);
5004 int d = GET_DAY(self);
5005 int hh = DATE_GET_HOUR(self);
5006 int mm = DATE_GET_MINUTE(self);
5007 int ss = DATE_GET_SECOND(self);
5008 int us = DATE_GET_MICROSECOND(self);
5009 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005010 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005011
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005012 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005013 datetime_kws,
5014 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005015 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005016 return NULL;
5017 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5018 if (tuple == NULL)
5019 return NULL;
5020 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005021
5022 if (clone != NULL) {
5023 if (fold != 0 && fold != 1) {
5024 PyErr_SetString(PyExc_ValueError,
5025 "fold must be either 0 or 1");
5026 return NULL;
5027 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005028 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005029 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005030 Py_DECREF(tuple);
5031 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005032}
5033
5034static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005035local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005036{
5037 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005038 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005039 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005040 PyObject *nameo = NULL;
5041 const char *zone = NULL;
5042
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005043 if (localtime_r(&timestamp, &local_time_tm) == NULL) {
5044#ifdef EINVAL
5045 if (errno == 0)
5046 errno = EINVAL;
5047#endif
5048 PyErr_SetFromErrno(PyExc_OSError);
5049 return NULL;
5050 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005051#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005052 zone = local_time_tm.tm_zone;
5053 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005054#else /* HAVE_STRUCT_TM_TM_ZONE */
5055 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005056 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005057 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005058 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005059 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005060 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005061 local_time = new_datetime(local_time_tm.tm_year + 1900,
5062 local_time_tm.tm_mon + 1,
5063 local_time_tm.tm_mday,
5064 local_time_tm.tm_hour,
5065 local_time_tm.tm_min,
5066 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005067 if (local_time == NULL) {
5068 return NULL;
5069 }
Alexander Belopolsky130bbe52016-09-10 16:51:17 -04005070 if (gmtime_r(&timestamp, &utc_time_tm) == NULL) {
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005071#ifdef EINVAL
5072 if (errno == 0)
5073 errno = EINVAL;
5074#endif
5075 PyErr_SetFromErrno(PyExc_OSError);
5076 return NULL;
5077 }
5078 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5079 utc_time_tm.tm_mon + 1,
5080 utc_time_tm.tm_mday,
5081 utc_time_tm.tm_hour,
5082 utc_time_tm.tm_min,
5083 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005084 if (utc_time == NULL) {
5085 Py_DECREF(local_time);
5086 return NULL;
5087 }
5088 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005089 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005090 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005091 }
5092#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005093 if (delta == NULL) {
5094 return NULL;
5095 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005096 if (zone != NULL) {
5097 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5098 if (nameo == NULL)
5099 goto error;
5100 }
5101 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005102 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005103 error:
5104 Py_DECREF(delta);
5105 return result;
5106}
5107
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005108static PyObject *
5109local_timezone(PyDateTime_DateTime *utc_time)
5110{
5111 time_t timestamp;
5112 PyObject *delta;
5113 PyObject *one_second;
5114 PyObject *seconds;
5115
5116 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5117 if (delta == NULL)
5118 return NULL;
5119 one_second = new_delta(0, 1, 0, 0);
5120 if (one_second == NULL) {
5121 Py_DECREF(delta);
5122 return NULL;
5123 }
5124 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5125 (PyDateTime_Delta *)one_second);
5126 Py_DECREF(one_second);
5127 Py_DECREF(delta);
5128 if (seconds == NULL)
5129 return NULL;
5130 timestamp = _PyLong_AsTime_t(seconds);
5131 Py_DECREF(seconds);
5132 if (timestamp == -1 && PyErr_Occurred())
5133 return NULL;
5134 return local_timezone_from_timestamp(timestamp);
5135}
5136
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005137static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005138local_to_seconds(int year, int month, int day,
5139 int hour, int minute, int second, int fold);
5140
5141static PyObject *
5142local_timezone_from_local(PyDateTime_DateTime *local_dt)
5143{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005144 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005145 time_t timestamp;
5146 seconds = local_to_seconds(GET_YEAR(local_dt),
5147 GET_MONTH(local_dt),
5148 GET_DAY(local_dt),
5149 DATE_GET_HOUR(local_dt),
5150 DATE_GET_MINUTE(local_dt),
5151 DATE_GET_SECOND(local_dt),
5152 DATE_GET_FOLD(local_dt));
5153 if (seconds == -1)
5154 return NULL;
5155 /* XXX: add bounds check */
5156 timestamp = seconds - epoch;
5157 return local_timezone_from_timestamp(timestamp);
5158}
5159
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005160static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005161datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005162{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005163 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005164 PyObject *offset;
5165 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005166 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005167 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005168 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005169
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005170 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005171 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005172 return NULL;
5173
5174 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005175 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005176
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005177 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5178 self_tzinfo = local_timezone_from_local(self);
5179 if (self_tzinfo == NULL)
5180 return NULL;
5181 } else {
5182 self_tzinfo = self->tzinfo;
5183 Py_INCREF(self_tzinfo);
5184 }
Tim Peters521fc152002-12-31 17:36:56 +00005185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005186 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005187 if (self_tzinfo == tzinfo) {
5188 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005189 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005190 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005191 }
Tim Peters521fc152002-12-31 17:36:56 +00005192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005193 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005194 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5195 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005196 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005197 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005198 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005199 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5200 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005201 Py_DECREF(offset);
5202 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005203 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005204
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005205 /* Make sure result is aware and UTC. */
5206 if (!HASTZINFO(result)) {
5207 temp = (PyObject *)result;
5208 result = (PyDateTime_DateTime *)
5209 new_datetime_ex2(GET_YEAR(result),
5210 GET_MONTH(result),
5211 GET_DAY(result),
5212 DATE_GET_HOUR(result),
5213 DATE_GET_MINUTE(result),
5214 DATE_GET_SECOND(result),
5215 DATE_GET_MICROSECOND(result),
5216 PyDateTime_TimeZone_UTC,
5217 DATE_GET_FOLD(result),
5218 Py_TYPE(result));
5219 Py_DECREF(temp);
5220 if (result == NULL)
5221 return NULL;
5222 }
5223 else {
5224 /* Result is already aware - just replace tzinfo. */
5225 temp = result->tzinfo;
5226 result->tzinfo = PyDateTime_TimeZone_UTC;
5227 Py_INCREF(result->tzinfo);
5228 Py_DECREF(temp);
5229 }
5230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005231 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005232 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005233 if (tzinfo == Py_None) {
5234 tzinfo = local_timezone(result);
5235 if (tzinfo == NULL) {
5236 Py_DECREF(result);
5237 return NULL;
5238 }
5239 }
5240 else
5241 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005242 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005243 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005244
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005245 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005246 result = (PyDateTime_DateTime *)
5247 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005248 Py_DECREF(temp);
5249
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005250 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005251}
5252
5253static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005254datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005256 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005258 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005259 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005260
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005261 dst = call_dst(self->tzinfo, (PyObject *)self);
5262 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005263 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005264
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005265 if (dst != Py_None)
5266 dstflag = delta_bool((PyDateTime_Delta *)dst);
5267 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005268 }
5269 return build_struct_time(GET_YEAR(self),
5270 GET_MONTH(self),
5271 GET_DAY(self),
5272 DATE_GET_HOUR(self),
5273 DATE_GET_MINUTE(self),
5274 DATE_GET_SECOND(self),
5275 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005276}
5277
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005278static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005279local_to_seconds(int year, int month, int day,
5280 int hour, int minute, int second, int fold)
5281{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005282 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005283 t = utc_to_seconds(year, month, day, hour, minute, second);
5284 /* Our goal is to solve t = local(u) for u. */
5285 lt = local(t);
5286 if (lt == -1)
5287 return -1;
5288 a = lt - t;
5289 u1 = t - a;
5290 t1 = local(u1);
5291 if (t1 == -1)
5292 return -1;
5293 if (t1 == t) {
5294 /* We found one solution, but it may not be the one we need.
5295 * Look for an earlier solution (if `fold` is 0), or a
5296 * later one (if `fold` is 1). */
5297 if (fold)
5298 u2 = u1 + max_fold_seconds;
5299 else
5300 u2 = u1 - max_fold_seconds;
5301 lt = local(u2);
5302 if (lt == -1)
5303 return -1;
5304 b = lt - u2;
5305 if (a == b)
5306 return u1;
5307 }
5308 else {
5309 b = t1 - u1;
5310 assert(a != b);
5311 }
5312 u2 = t - b;
5313 t2 = local(u2);
5314 if (t2 == -1)
5315 return -1;
5316 if (t2 == t)
5317 return u2;
5318 if (t1 == t)
5319 return u1;
5320 /* We have found both offsets a and b, but neither t - a nor t - b is
5321 * a solution. This means t is in the gap. */
5322 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5323}
5324
5325/* date(1970,1,1).toordinal() == 719163 */
5326#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5327
Tim Peters2a799bf2002-12-16 20:18:38 +00005328static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005329datetime_timestamp(PyDateTime_DateTime *self)
5330{
5331 PyObject *result;
5332
5333 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5334 PyObject *delta;
5335 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5336 if (delta == NULL)
5337 return NULL;
5338 result = delta_total_seconds(delta);
5339 Py_DECREF(delta);
5340 }
5341 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005342 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005343 seconds = local_to_seconds(GET_YEAR(self),
5344 GET_MONTH(self),
5345 GET_DAY(self),
5346 DATE_GET_HOUR(self),
5347 DATE_GET_MINUTE(self),
5348 DATE_GET_SECOND(self),
5349 DATE_GET_FOLD(self));
5350 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005351 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005352 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5353 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005354 }
5355 return result;
5356}
5357
5358static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005359datetime_getdate(PyDateTime_DateTime *self)
5360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005361 return new_date(GET_YEAR(self),
5362 GET_MONTH(self),
5363 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005364}
5365
5366static PyObject *
5367datetime_gettime(PyDateTime_DateTime *self)
5368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005369 return new_time(DATE_GET_HOUR(self),
5370 DATE_GET_MINUTE(self),
5371 DATE_GET_SECOND(self),
5372 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005373 Py_None,
5374 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005375}
5376
5377static PyObject *
5378datetime_gettimetz(PyDateTime_DateTime *self)
5379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005380 return new_time(DATE_GET_HOUR(self),
5381 DATE_GET_MINUTE(self),
5382 DATE_GET_SECOND(self),
5383 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005384 GET_DT_TZINFO(self),
5385 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005386}
5387
5388static PyObject *
5389datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005390{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005391 int y, m, d, hh, mm, ss;
5392 PyObject *tzinfo;
5393 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005394
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005395 tzinfo = GET_DT_TZINFO(self);
5396 if (tzinfo == Py_None) {
5397 utcself = self;
5398 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005399 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005400 else {
5401 PyObject *offset;
5402 offset = call_utcoffset(tzinfo, (PyObject *)self);
5403 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005404 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005405 if (offset == Py_None) {
5406 Py_DECREF(offset);
5407 utcself = self;
5408 Py_INCREF(utcself);
5409 }
5410 else {
5411 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5412 (PyDateTime_Delta *)offset, -1);
5413 Py_DECREF(offset);
5414 if (utcself == NULL)
5415 return NULL;
5416 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005417 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005418 y = GET_YEAR(utcself);
5419 m = GET_MONTH(utcself);
5420 d = GET_DAY(utcself);
5421 hh = DATE_GET_HOUR(utcself);
5422 mm = DATE_GET_MINUTE(utcself);
5423 ss = DATE_GET_SECOND(utcself);
5424
5425 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005426 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005427}
5428
Tim Peters371935f2003-02-01 01:52:50 +00005429/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005430
Tim Petersa9bc1682003-01-11 03:39:11 +00005431/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005432 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5433 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005434 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005435 */
5436static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005437datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005438{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005439 PyObject *basestate;
5440 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005442 basestate = PyBytes_FromStringAndSize((char *)self->data,
5443 _PyDateTime_DATETIME_DATASIZE);
5444 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005445 if (proto > 3 && DATE_GET_FOLD(self))
5446 /* Set the first bit of the third byte */
5447 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005448 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5449 result = PyTuple_Pack(1, basestate);
5450 else
5451 result = PyTuple_Pack(2, basestate, self->tzinfo);
5452 Py_DECREF(basestate);
5453 }
5454 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005455}
5456
5457static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005458datetime_reduce(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005459{
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005460 int proto = 0;
5461 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
5462 return NULL;
5463
5464 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005465}
5466
Tim Petersa9bc1682003-01-11 03:39:11 +00005467static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005469 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005470
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005471 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005473 {"utcnow", (PyCFunction)datetime_utcnow,
5474 METH_NOARGS | METH_CLASS,
5475 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005477 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5478 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5479 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005481 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5482 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005483 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005485 {"strptime", (PyCFunction)datetime_strptime,
5486 METH_VARARGS | METH_CLASS,
5487 PyDoc_STR("string, format -> new datetime parsed from a string "
5488 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005490 {"combine", (PyCFunction)datetime_combine,
5491 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5492 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005494 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005496 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5497 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005499 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5500 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005502 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5503 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005505 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5506 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005508 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5509 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005510
Alexander Belopolskya4415142012-06-08 12:33:09 -04005511 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5512 PyDoc_STR("Return POSIX timestamp as float.")},
5513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005514 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5515 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005517 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5518 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005519 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005520 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005521 "defaults to 'T'.\n"
5522 "timespec specifies what components of the time to include"
5523 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5524 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005526 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5527 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005529 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5530 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005532 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5533 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005535 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5536 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005538 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5539 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005540
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005541 {"__reduce_ex__", (PyCFunction)datetime_reduce, METH_VARARGS,
5542 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005544 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005545};
5546
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005547static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005548PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5549\n\
5550The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005551instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005552
Tim Petersa9bc1682003-01-11 03:39:11 +00005553static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005554 datetime_add, /* nb_add */
5555 datetime_subtract, /* nb_subtract */
5556 0, /* nb_multiply */
5557 0, /* nb_remainder */
5558 0, /* nb_divmod */
5559 0, /* nb_power */
5560 0, /* nb_negative */
5561 0, /* nb_positive */
5562 0, /* nb_absolute */
5563 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005564};
5565
Neal Norwitz227b5332006-03-22 09:28:35 +00005566static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005567 PyVarObject_HEAD_INIT(NULL, 0)
5568 "datetime.datetime", /* tp_name */
5569 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5570 0, /* tp_itemsize */
5571 (destructor)datetime_dealloc, /* tp_dealloc */
5572 0, /* tp_print */
5573 0, /* tp_getattr */
5574 0, /* tp_setattr */
5575 0, /* tp_reserved */
5576 (reprfunc)datetime_repr, /* tp_repr */
5577 &datetime_as_number, /* tp_as_number */
5578 0, /* tp_as_sequence */
5579 0, /* tp_as_mapping */
5580 (hashfunc)datetime_hash, /* tp_hash */
5581 0, /* tp_call */
5582 (reprfunc)datetime_str, /* tp_str */
5583 PyObject_GenericGetAttr, /* tp_getattro */
5584 0, /* tp_setattro */
5585 0, /* tp_as_buffer */
5586 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5587 datetime_doc, /* tp_doc */
5588 0, /* tp_traverse */
5589 0, /* tp_clear */
5590 datetime_richcompare, /* tp_richcompare */
5591 0, /* tp_weaklistoffset */
5592 0, /* tp_iter */
5593 0, /* tp_iternext */
5594 datetime_methods, /* tp_methods */
5595 0, /* tp_members */
5596 datetime_getset, /* tp_getset */
5597 &PyDateTime_DateType, /* tp_base */
5598 0, /* tp_dict */
5599 0, /* tp_descr_get */
5600 0, /* tp_descr_set */
5601 0, /* tp_dictoffset */
5602 0, /* tp_init */
5603 datetime_alloc, /* tp_alloc */
5604 datetime_new, /* tp_new */
5605 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005606};
5607
5608/* ---------------------------------------------------------------------------
5609 * Module methods and initialization.
5610 */
5611
5612static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005613 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005614};
5615
Tim Peters9ddf40b2004-06-20 22:41:32 +00005616/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5617 * datetime.h.
5618 */
5619static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005620 &PyDateTime_DateType,
5621 &PyDateTime_DateTimeType,
5622 &PyDateTime_TimeType,
5623 &PyDateTime_DeltaType,
5624 &PyDateTime_TZInfoType,
5625 new_date_ex,
5626 new_datetime_ex,
5627 new_time_ex,
5628 new_delta_ex,
5629 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005630 date_fromtimestamp,
5631 new_datetime_ex2,
5632 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00005633};
5634
5635
Martin v. Löwis1a214512008-06-11 05:26:20 +00005636
5637static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005638 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005639 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005640 "Fast implementation of the datetime type.",
5641 -1,
5642 module_methods,
5643 NULL,
5644 NULL,
5645 NULL,
5646 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005647};
5648
Tim Peters2a799bf2002-12-16 20:18:38 +00005649PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005650PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005652 PyObject *m; /* a module object */
5653 PyObject *d; /* its dict */
5654 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005655 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005657 m = PyModule_Create(&datetimemodule);
5658 if (m == NULL)
5659 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005661 if (PyType_Ready(&PyDateTime_DateType) < 0)
5662 return NULL;
5663 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5664 return NULL;
5665 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5666 return NULL;
5667 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5668 return NULL;
5669 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5670 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005671 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5672 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005674 /* timedelta values */
5675 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005677 x = new_delta(0, 0, 1, 0);
5678 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5679 return NULL;
5680 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005682 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5683 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5684 return NULL;
5685 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005687 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5688 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5689 return NULL;
5690 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005692 /* date values */
5693 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005695 x = new_date(1, 1, 1);
5696 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5697 return NULL;
5698 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005700 x = new_date(MAXYEAR, 12, 31);
5701 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5702 return NULL;
5703 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005705 x = new_delta(1, 0, 0, 0);
5706 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5707 return NULL;
5708 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005710 /* time values */
5711 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005712
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005713 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005714 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5715 return NULL;
5716 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005717
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005718 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005719 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5720 return NULL;
5721 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005723 x = new_delta(0, 0, 1, 0);
5724 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5725 return NULL;
5726 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005728 /* datetime values */
5729 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005730
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005731 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005732 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5733 return NULL;
5734 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005735
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005736 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005737 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5738 return NULL;
5739 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005741 x = new_delta(0, 0, 1, 0);
5742 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5743 return NULL;
5744 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005745
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005746 /* timezone values */
5747 d = PyDateTime_TimeZoneType.tp_dict;
5748
5749 delta = new_delta(0, 0, 0, 0);
5750 if (delta == NULL)
5751 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005752 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005753 Py_DECREF(delta);
5754 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5755 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005756 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005757
5758 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5759 if (delta == NULL)
5760 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005761 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005762 Py_DECREF(delta);
5763 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5764 return NULL;
5765 Py_DECREF(x);
5766
5767 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5768 if (delta == NULL)
5769 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005770 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005771 Py_DECREF(delta);
5772 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5773 return NULL;
5774 Py_DECREF(x);
5775
Alexander Belopolskya4415142012-06-08 12:33:09 -04005776 /* Epoch */
5777 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005778 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005779 if (PyDateTime_Epoch == NULL)
5780 return NULL;
5781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005782 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005783 PyModule_AddIntMacro(m, MINYEAR);
5784 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005786 Py_INCREF(&PyDateTime_DateType);
5787 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005789 Py_INCREF(&PyDateTime_DateTimeType);
5790 PyModule_AddObject(m, "datetime",
5791 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005793 Py_INCREF(&PyDateTime_TimeType);
5794 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005796 Py_INCREF(&PyDateTime_DeltaType);
5797 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005799 Py_INCREF(&PyDateTime_TZInfoType);
5800 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005801
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005802 Py_INCREF(&PyDateTime_TimeZoneType);
5803 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005805 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5806 if (x == NULL)
5807 return NULL;
5808 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005810 /* A 4-year cycle has an extra leap day over what we'd get from
5811 * pasting together 4 single years.
5812 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005813 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005814 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005816 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5817 * get from pasting together 4 100-year cycles.
5818 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005819 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005820 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005822 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5823 * pasting together 25 4-year cycles.
5824 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005825 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005826 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005827
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005828 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005829 us_per_ms = PyLong_FromLong(1000);
5830 us_per_second = PyLong_FromLong(1000000);
5831 us_per_minute = PyLong_FromLong(60000000);
5832 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005833 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005834 us_per_minute == NULL || seconds_per_day == NULL)
5835 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005837 /* The rest are too big for 32-bit ints, but even
5838 * us_per_week fits in 40 bits, so doubles should be exact.
5839 */
5840 us_per_hour = PyLong_FromDouble(3600000000.0);
5841 us_per_day = PyLong_FromDouble(86400000000.0);
5842 us_per_week = PyLong_FromDouble(604800000000.0);
5843 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5844 return NULL;
5845 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005846}
Tim Petersf3615152003-01-01 21:51:37 +00005847
5848/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005849Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005850 x.n = x stripped of its timezone -- its naive time.
5851 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005852 return None
Tim Petersf3615152003-01-01 21:51:37 +00005853 x.d = x.dst(), 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.s = x's standard offset, x.o - x.d
5856
5857Now some derived rules, where k is a duration (timedelta).
5858
58591. x.o = x.s + x.d
5860 This follows from the definition of x.s.
5861
Tim Petersc5dc4da2003-01-02 17:55:03 +000058622. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005863 This is actually a requirement, an assumption we need to make about
5864 sane tzinfo classes.
5865
58663. The naive UTC time corresponding to x is x.n - x.o.
5867 This is again a requirement for a sane tzinfo class.
5868
58694. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005870 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005871
Tim Petersc5dc4da2003-01-02 17:55:03 +000058725. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005873 Again follows from how arithmetic is defined.
5874
Tim Peters8bb5ad22003-01-24 02:44:45 +00005875Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005876(meaning that the various tzinfo methods exist, and don't blow up or return
5877None when called).
5878
Tim Petersa9bc1682003-01-11 03:39:11 +00005879The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005880x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005881
5882By #3, we want
5883
Tim Peters8bb5ad22003-01-24 02:44:45 +00005884 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005885
5886The algorithm starts by attaching tz to x.n, and calling that y. So
5887x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5888becomes true; in effect, we want to solve [2] for k:
5889
Tim Peters8bb5ad22003-01-24 02:44:45 +00005890 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005891
5892By #1, this is the same as
5893
Tim Peters8bb5ad22003-01-24 02:44:45 +00005894 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005895
5896By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5897Substituting that into [3],
5898
Tim Peters8bb5ad22003-01-24 02:44:45 +00005899 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5900 k - (y+k).s - (y+k).d = 0; rearranging,
5901 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5902 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005903
Tim Peters8bb5ad22003-01-24 02:44:45 +00005904On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5905approximate k by ignoring the (y+k).d term at first. Note that k can't be
5906very large, since all offset-returning methods return a duration of magnitude
5907less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5908be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005909
5910In any case, the new value is
5911
Tim Peters8bb5ad22003-01-24 02:44:45 +00005912 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005913
Tim Peters8bb5ad22003-01-24 02:44:45 +00005914It's helpful to step back at look at [4] from a higher level: it's simply
5915mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005916
5917At this point, if
5918
Tim Peters8bb5ad22003-01-24 02:44:45 +00005919 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005920
5921we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005922at the start of daylight time. Picture US Eastern for concreteness. The wall
5923time 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 +00005924sense then. The docs ask that an Eastern tzinfo class consider such a time to
5925be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5926on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005927the only spelling that makes sense on the local wall clock.
5928
Tim Petersc5dc4da2003-01-02 17:55:03 +00005929In fact, if [5] holds at this point, we do have the standard-time spelling,
5930but that takes a bit of proof. We first prove a stronger result. What's the
5931difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005932
Tim Peters8bb5ad22003-01-24 02:44:45 +00005933 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005934
Tim Petersc5dc4da2003-01-02 17:55:03 +00005935Now
5936 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005937 (y + y.s).n = by #5
5938 y.n + y.s = since y.n = x.n
5939 x.n + y.s = since z and y are have the same tzinfo member,
5940 y.s = z.s by #2
5941 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005942
Tim Petersc5dc4da2003-01-02 17:55:03 +00005943Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005944
Tim Petersc5dc4da2003-01-02 17:55:03 +00005945 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005946 x.n - ((x.n + z.s) - z.o) = expanding
5947 x.n - x.n - z.s + z.o = cancelling
5948 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005949 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005950
Tim Petersc5dc4da2003-01-02 17:55:03 +00005951So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005952
Tim Petersc5dc4da2003-01-02 17:55:03 +00005953If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005954spelling we wanted in the endcase described above. We're done. Contrarily,
5955if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005956
Tim Petersc5dc4da2003-01-02 17:55:03 +00005957If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5958add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005959local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005960
Tim Petersc5dc4da2003-01-02 17:55:03 +00005961Let
Tim Petersf3615152003-01-01 21:51:37 +00005962
Tim Peters4fede1a2003-01-04 00:26:59 +00005963 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005964
Tim Peters4fede1a2003-01-04 00:26:59 +00005965and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005966
Tim Peters8bb5ad22003-01-24 02:44:45 +00005967 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005968
Tim Peters8bb5ad22003-01-24 02:44:45 +00005969If so, we're done. If not, the tzinfo class is insane, according to the
5970assumptions we've made. This also requires a bit of proof. As before, let's
5971compute the difference between the LHS and RHS of [8] (and skipping some of
5972the justifications for the kinds of substitutions we've done several times
5973already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005974
Tim Peters8bb5ad22003-01-24 02:44:45 +00005975 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005976 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5977 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5978 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5979 - z.n + z.n - z.o + z'.o = cancel z.n
5980 - z.o + z'.o = #1 twice
5981 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5982 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005983
5984So 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 +00005985we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5986return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005987
Tim Peters8bb5ad22003-01-24 02:44:45 +00005988How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5989a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5990would have to change the result dst() returns: we start in DST, and moving
5991a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005992
Tim Peters8bb5ad22003-01-24 02:44:45 +00005993There isn't a sane case where this can happen. The closest it gets is at
5994the end of DST, where there's an hour in UTC with no spelling in a hybrid
5995tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5996that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5997UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5998time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5999clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6000standard time. Since that's what the local clock *does*, we want to map both
6001UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00006002in local time, but so it goes -- it's the way the local clock works.
6003
Tim Peters8bb5ad22003-01-24 02:44:45 +00006004When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6005so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6006z' = 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 +00006007(correctly) concludes that z' is not UTC-equivalent to x.
6008
6009Because we know z.d said z was in daylight time (else [5] would have held and
6010we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006011and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006012return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6013but the reasoning doesn't depend on the example -- it depends on there being
6014two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006015z' must be in standard time, and is the spelling we want in this case.
6016
6017Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6018concerned (because it takes z' as being in standard time rather than the
6019daylight time we intend here), but returning it gives the real-life "local
6020clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6021tz.
6022
6023When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6024the 1:MM standard time spelling we want.
6025
6026So how can this break? One of the assumptions must be violated. Two
6027possibilities:
6028
60291) [2] effectively says that y.s is invariant across all y belong to a given
6030 time zone. This isn't true if, for political reasons or continental drift,
6031 a region decides to change its base offset from UTC.
6032
60332) There may be versions of "double daylight" time where the tail end of
6034 the analysis gives up a step too early. I haven't thought about that
6035 enough to say.
6036
6037In any case, it's clear that the default fromutc() is strong enough to handle
6038"almost all" time zones: so long as the standard offset is invariant, it
6039doesn't matter if daylight time transition points change from year to year, or
6040if daylight time is skipped in some years; it doesn't matter how large or
6041small dst() may get within its bounds; and it doesn't even matter if some
6042perverse time zone returns a negative dst()). So a breaking case must be
6043pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006044--------------------------------------------------------------------------- */