blob: 261c4bc6e707ae7265c1c25ba21738639da02a67 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
Tim Peters2a799bf2002-12-16 20:18:38 +00006#include "structmember.h"
7
8#include <time.h>
9
Victor Stinner09e5cf22015-03-30 00:09:18 +020010#ifdef MS_WINDOWS
11# include <winsock2.h> /* struct timeval */
12#endif
13
Tim Peters9ddf40b2004-06-20 22:41:32 +000014/* Differentiate between building the core module and building extension
15 * modules.
16 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000017#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000018#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000019#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000020#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000021#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000022
Larry Hastings61272b72014-01-07 12:41:53 -080023/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080024module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080025class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Larry Hastings61272b72014-01-07 12:41:53 -080026[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -080027/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080028
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030029#include "clinic/_datetimemodule.c.h"
30
Tim Peters2a799bf2002-12-16 20:18:38 +000031/* We require that C int be at least 32 bits, and use int virtually
32 * everywhere. In just a few cases we use a temp long, where a Python
33 * API returns a C long. In such cases, we have to ensure that the
34 * final result fits in a C int (this can be an issue on 64-bit boxes).
35 */
36#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000037# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000038#endif
39
40#define MINYEAR 1
41#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000042#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000043
44/* Nine decimal digits is easy to communicate, and leaves enough room
45 * so that two delta days can be added w/o fear of overflowing a signed
46 * 32-bit int, and with plenty of room left over to absorb any possible
47 * carries from adding seconds.
48 */
49#define MAX_DELTA_DAYS 999999999
50
51/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define GET_YEAR PyDateTime_GET_YEAR
53#define GET_MONTH PyDateTime_GET_MONTH
54#define GET_DAY PyDateTime_GET_DAY
55#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
56#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
57#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
58#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000059
60/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
62 ((o)->data[1] = ((v) & 0x00ff)))
63#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
64#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000065
66/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
68#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
69#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
70#define DATE_SET_MICROSECOND(o, v) \
71 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
72 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
73 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000074
75/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
77#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
78#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
79#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
80#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
81#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
82#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
83#define TIME_SET_MICROSECOND(o, v) \
84 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
85 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
86 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000087
88/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
90#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
91#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093#define SET_TD_DAYS(o, v) ((o)->days = (v))
94#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000095#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
96
Tim Petersa032d2e2003-01-11 00:15:54 +000097/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
98 * p->hastzinfo.
99 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000100#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
101#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
102 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
103#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
104 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000105/* M is a char or int claiming to be a valid month. The macro is equivalent
106 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000108 */
109#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
110
Tim Peters2a799bf2002-12-16 20:18:38 +0000111/* Forward declarations. */
112static PyTypeObject PyDateTime_DateType;
113static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000114static PyTypeObject PyDateTime_DeltaType;
115static PyTypeObject PyDateTime_TimeType;
116static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000117static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000118
Martin v. Löwise75fc142013-11-07 18:46:53 +0100119_Py_IDENTIFIER(as_integer_ratio);
120_Py_IDENTIFIER(fromutc);
121_Py_IDENTIFIER(isoformat);
122_Py_IDENTIFIER(strftime);
123
Tim Peters2a799bf2002-12-16 20:18:38 +0000124/* ---------------------------------------------------------------------------
125 * Math utilities.
126 */
127
128/* k = i+j overflows iff k differs in sign from both inputs,
129 * iff k^i has sign bit set and k^j has sign bit set,
130 * iff (k^i)&(k^j) has sign bit set.
131 */
132#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000134
135/* Compute Python divmod(x, y), returning the quotient and storing the
136 * remainder into *r. The quotient is the floor of x/y, and that's
137 * the real point of this. C will probably truncate instead (C99
138 * requires truncation; C89 left it implementation-defined).
139 * Simplification: we *require* that y > 0 here. That's appropriate
140 * for all the uses made of it. This simplifies the code and makes
141 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
142 * overflow case).
143 */
144static int
145divmod(int x, int y, int *r)
146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 assert(y > 0);
150 quo = x / y;
151 *r = x - quo * y;
152 if (*r < 0) {
153 --quo;
154 *r += y;
155 }
156 assert(0 <= *r && *r < y);
157 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000158}
159
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000160/* Nearest integer to m / n for integers m and n. Half-integer results
161 * are rounded to even.
162 */
163static PyObject *
164divide_nearest(PyObject *m, PyObject *n)
165{
166 PyObject *result;
167 PyObject *temp;
168
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000169 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000170 if (temp == NULL)
171 return NULL;
172 result = PyTuple_GET_ITEM(temp, 0);
173 Py_INCREF(result);
174 Py_DECREF(temp);
175
176 return result;
177}
178
Tim Peters2a799bf2002-12-16 20:18:38 +0000179/* ---------------------------------------------------------------------------
180 * General calendrical helper functions
181 */
182
183/* For each month ordinal in 1..12, the number of days in that month,
184 * and the number of days before that month in the same year. These
185 * are correct for non-leap years only.
186 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200187static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 0, /* unused; this vector uses 1-based indexing */
189 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000190};
191
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200192static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 0, /* unused; this vector uses 1-based indexing */
194 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000195};
196
197/* year -> 1 if leap year, else 0. */
198static int
199is_leap(int year)
200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 /* Cast year to unsigned. The result is the same either way, but
202 * C can generate faster code for unsigned mod than for signed
203 * mod (especially for % 4 -- a good compiler should just grab
204 * the last 2 bits when the LHS is unsigned).
205 */
206 const unsigned int ayear = (unsigned int)year;
207 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000208}
209
210/* year, month -> number of days in that month in that year */
211static int
212days_in_month(int year, int month)
213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 assert(month >= 1);
215 assert(month <= 12);
216 if (month == 2 && is_leap(year))
217 return 29;
218 else
219 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000220}
221
222/* year, month -> number of days in year preceeding first day of month */
223static int
224days_before_month(int year, int month)
225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 assert(month >= 1);
229 assert(month <= 12);
230 days = _days_before_month[month];
231 if (month > 2 && is_leap(year))
232 ++days;
233 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000234}
235
236/* year -> number of days before January 1st of year. Remember that we
237 * start with year 1, so days_before_year(1) == 0.
238 */
239static int
240days_before_year(int year)
241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 int y = year - 1;
243 /* This is incorrect if year <= 0; we really want the floor
244 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000245 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000247 assert (year >= 1);
248 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000249}
250
251/* Number of days in 4, 100, and 400 year cycles. That these have
252 * the correct values is asserted in the module init function.
253 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254#define DI4Y 1461 /* days_before_year(5); days in 4 years */
255#define DI100Y 36524 /* days_before_year(101); days in 100 years */
256#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000257
258/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
259static void
260ord_to_ymd(int ordinal, int *year, int *month, int *day)
261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
265 * leap years repeats exactly every 400 years. The basic strategy is
266 * to find the closest 400-year boundary at or before ordinal, then
267 * work with the offset from that boundary to ordinal. Life is much
268 * clearer if we subtract 1 from ordinal first -- then the values
269 * of ordinal at 400-year boundaries are exactly those divisible
270 * by DI400Y:
271 *
272 * D M Y n n-1
273 * -- --- ---- ---------- ----------------
274 * 31 Dec -400 -DI400Y -DI400Y -1
275 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
276 * ...
277 * 30 Dec 000 -1 -2
278 * 31 Dec 000 0 -1
279 * 1 Jan 001 1 0 400-year boundary
280 * 2 Jan 001 2 1
281 * 3 Jan 001 3 2
282 * ...
283 * 31 Dec 400 DI400Y DI400Y -1
284 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
285 */
286 assert(ordinal >= 1);
287 --ordinal;
288 n400 = ordinal / DI400Y;
289 n = ordinal % DI400Y;
290 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 /* Now n is the (non-negative) offset, in days, from January 1 of
293 * year, to the desired date. Now compute how many 100-year cycles
294 * precede n.
295 * Note that it's possible for n100 to equal 4! In that case 4 full
296 * 100-year cycles precede the desired day, which implies the
297 * desired day is December 31 at the end of a 400-year cycle.
298 */
299 n100 = n / DI100Y;
300 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 /* Now compute how many 4-year cycles precede it. */
303 n4 = n / DI4Y;
304 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 /* And now how many single years. Again n1 can be 4, and again
307 * meaning that the desired day is December 31 at the end of the
308 * 4-year cycle.
309 */
310 n1 = n / 365;
311 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 *year += n100 * 100 + n4 * 4 + n1;
314 if (n1 == 4 || n100 == 4) {
315 assert(n == 0);
316 *year -= 1;
317 *month = 12;
318 *day = 31;
319 return;
320 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 /* Now the year is correct, and n is the offset from January 1. We
323 * find the month via an estimate that's either exact or one too
324 * large.
325 */
326 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
327 assert(leapyear == is_leap(*year));
328 *month = (n + 50) >> 5;
329 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
330 if (preceding > n) {
331 /* estimate is too large */
332 *month -= 1;
333 preceding -= days_in_month(*year, *month);
334 }
335 n -= preceding;
336 assert(0 <= n);
337 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000340}
341
342/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
343static int
344ymd_to_ord(int year, int month, int day)
345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000347}
348
349/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
350static int
351weekday(int year, int month, int day)
352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000354}
355
356/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
357 * first calendar week containing a Thursday.
358 */
359static int
360iso_week1_monday(int year)
361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
363 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
364 int first_weekday = (first_day + 6) % 7;
365 /* ordinal of closest Monday at or before 1/1 */
366 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
369 week1_monday += 7;
370 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000371}
372
373/* ---------------------------------------------------------------------------
374 * Range checkers.
375 */
376
377/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
378 * If not, raise OverflowError and return -1.
379 */
380static int
381check_delta_day_range(int days)
382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000383 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
384 return 0;
385 PyErr_Format(PyExc_OverflowError,
386 "days=%d; must have magnitude <= %d",
387 days, MAX_DELTA_DAYS);
388 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000389}
390
391/* Check that date arguments are in range. Return 0 if they are. If they
392 * aren't, raise ValueError and return -1.
393 */
394static int
395check_date_args(int year, int month, int day)
396{
397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 if (year < MINYEAR || year > MAXYEAR) {
399 PyErr_SetString(PyExc_ValueError,
400 "year is out of range");
401 return -1;
402 }
403 if (month < 1 || month > 12) {
404 PyErr_SetString(PyExc_ValueError,
405 "month must be in 1..12");
406 return -1;
407 }
408 if (day < 1 || day > days_in_month(year, month)) {
409 PyErr_SetString(PyExc_ValueError,
410 "day is out of range for month");
411 return -1;
412 }
413 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000414}
415
416/* Check that time arguments are in range. Return 0 if they are. If they
417 * aren't, raise ValueError and return -1.
418 */
419static int
420check_time_args(int h, int m, int s, int us)
421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 if (h < 0 || h > 23) {
423 PyErr_SetString(PyExc_ValueError,
424 "hour must be in 0..23");
425 return -1;
426 }
427 if (m < 0 || m > 59) {
428 PyErr_SetString(PyExc_ValueError,
429 "minute must be in 0..59");
430 return -1;
431 }
432 if (s < 0 || s > 59) {
433 PyErr_SetString(PyExc_ValueError,
434 "second must be in 0..59");
435 return -1;
436 }
437 if (us < 0 || us > 999999) {
438 PyErr_SetString(PyExc_ValueError,
439 "microsecond must be in 0..999999");
440 return -1;
441 }
442 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000443}
444
445/* ---------------------------------------------------------------------------
446 * Normalization utilities.
447 */
448
449/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
450 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
451 * at least factor, enough of *lo is converted into "hi" units so that
452 * 0 <= *lo < factor. The input values must be such that int overflow
453 * is impossible.
454 */
455static void
456normalize_pair(int *hi, int *lo, int factor)
457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 assert(factor > 0);
459 assert(lo != hi);
460 if (*lo < 0 || *lo >= factor) {
461 const int num_hi = divmod(*lo, factor, lo);
462 const int new_hi = *hi + num_hi;
463 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
464 *hi = new_hi;
465 }
466 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000467}
468
469/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 * 0 <= *s < 24*3600
471 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000472 * The input values must be such that the internals don't overflow.
473 * The way this routine is used, we don't get close.
474 */
475static void
476normalize_d_s_us(int *d, int *s, int *us)
477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 if (*us < 0 || *us >= 1000000) {
479 normalize_pair(s, us, 1000000);
480 /* |s| can't be bigger than about
481 * |original s| + |original us|/1000000 now.
482 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 }
485 if (*s < 0 || *s >= 24*3600) {
486 normalize_pair(d, s, 24*3600);
487 /* |d| can't be bigger than about
488 * |original d| +
489 * (|original s| + |original us|/1000000) / (24*3600) now.
490 */
491 }
492 assert(0 <= *s && *s < 24*3600);
493 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000494}
495
496/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 * 1 <= *m <= 12
498 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000499 * The input values must be such that the internals don't overflow.
500 * The way this routine is used, we don't get close.
501 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000502static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000503normalize_y_m_d(int *y, int *m, int *d)
504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000506
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000507 /* In actual use, m is always the month component extracted from a
508 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 /* Now only day can be out of bounds (year may also be out of bounds
514 * for a datetime object, but we don't care about that here).
515 * If day is out of bounds, what to do is arguable, but at least the
516 * method here is principled and explainable.
517 */
518 dim = days_in_month(*y, *m);
519 if (*d < 1 || *d > dim) {
520 /* Move day-1 days from the first of the month. First try to
521 * get off cheap if we're only one day out of range
522 * (adjustments for timezone alone can't be worse than that).
523 */
524 if (*d == 0) {
525 --*m;
526 if (*m > 0)
527 *d = days_in_month(*y, *m);
528 else {
529 --*y;
530 *m = 12;
531 *d = 31;
532 }
533 }
534 else if (*d == dim + 1) {
535 /* move forward a day */
536 ++*m;
537 *d = 1;
538 if (*m > 12) {
539 *m = 1;
540 ++*y;
541 }
542 }
543 else {
544 int ordinal = ymd_to_ord(*y, *m, 1) +
545 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000546 if (ordinal < 1 || ordinal > MAXORDINAL) {
547 goto error;
548 } else {
549 ord_to_ymd(ordinal, y, m, d);
550 return 0;
551 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 }
553 }
554 assert(*m > 0);
555 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000556 if (MINYEAR <= *y && *y <= MAXYEAR)
557 return 0;
558 error:
559 PyErr_SetString(PyExc_OverflowError,
560 "date value out of range");
561 return -1;
562
Tim Peters2a799bf2002-12-16 20:18:38 +0000563}
564
565/* Fiddle out-of-bounds months and days so that the result makes some kind
566 * of sense. The parameters are both inputs and outputs. Returns < 0 on
567 * failure, where failure means the adjusted year is out of bounds.
568 */
569static int
570normalize_date(int *year, int *month, int *day)
571{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000572 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000573}
574
575/* Force all the datetime fields into range. The parameters are both
576 * inputs and outputs. Returns < 0 on error.
577 */
578static int
579normalize_datetime(int *year, int *month, int *day,
580 int *hour, int *minute, int *second,
581 int *microsecond)
582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 normalize_pair(second, microsecond, 1000000);
584 normalize_pair(minute, second, 60);
585 normalize_pair(hour, minute, 60);
586 normalize_pair(day, hour, 24);
587 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000588}
589
590/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000591 * Basic object allocation: tp_alloc implementations. These allocate
592 * Python objects of the right size and type, and do the Python object-
593 * initialization bit. If there's not enough memory, they return NULL after
594 * setting MemoryError. All data members remain uninitialized trash.
595 *
596 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000597 * member is needed. This is ugly, imprecise, and possibly insecure.
598 * tp_basicsize for the time and datetime types is set to the size of the
599 * struct that has room for the tzinfo member, so subclasses in Python will
600 * allocate enough space for a tzinfo member whether or not one is actually
601 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
602 * part is that PyType_GenericAlloc() (which subclasses in Python end up
603 * using) just happens today to effectively ignore the nitems argument
604 * when tp_itemsize is 0, which it is for these type objects. If that
605 * changes, perhaps the callers of tp_alloc slots in this file should
606 * be changed to force a 0 nitems argument unless the type being allocated
607 * is a base type implemented in this file (so that tp_alloc is time_alloc
608 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000609 */
610
611static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000612time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 self = (PyObject *)
617 PyObject_MALLOC(aware ?
618 sizeof(PyDateTime_Time) :
619 sizeof(_PyDateTime_BaseTime));
620 if (self == NULL)
621 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100622 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000624}
625
626static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000627datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 self = (PyObject *)
632 PyObject_MALLOC(aware ?
633 sizeof(PyDateTime_DateTime) :
634 sizeof(_PyDateTime_BaseDateTime));
635 if (self == NULL)
636 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100637 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000639}
640
641/* ---------------------------------------------------------------------------
642 * Helpers for setting object fields. These work on pointers to the
643 * appropriate base class.
644 */
645
646/* For date and datetime. */
647static void
648set_date_fields(PyDateTime_Date *self, int y, int m, int d)
649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000650 self->hashcode = -1;
651 SET_YEAR(self, y);
652 SET_MONTH(self, m);
653 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000654}
655
656/* ---------------------------------------------------------------------------
657 * Create various objects, mostly without range checking.
658 */
659
660/* Create a date instance with no range checking. */
661static PyObject *
662new_date_ex(int year, int month, int day, PyTypeObject *type)
663{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
667 if (self != NULL)
668 set_date_fields(self, year, month, day);
669 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000670}
671
672#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000674
675/* Create a datetime instance with no range checking. */
676static PyObject *
677new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 PyDateTime_DateTime *self;
681 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
684 if (self != NULL) {
685 self->hastzinfo = aware;
686 set_date_fields((PyDateTime_Date *)self, year, month, day);
687 DATE_SET_HOUR(self, hour);
688 DATE_SET_MINUTE(self, minute);
689 DATE_SET_SECOND(self, second);
690 DATE_SET_MICROSECOND(self, usecond);
691 if (aware) {
692 Py_INCREF(tzinfo);
693 self->tzinfo = tzinfo;
694 }
695 }
696 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000697}
698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
700 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
701 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000702
703/* Create a time instance with no range checking. */
704static PyObject *
705new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 PyDateTime_Time *self;
709 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
712 if (self != NULL) {
713 self->hastzinfo = aware;
714 self->hashcode = -1;
715 TIME_SET_HOUR(self, hour);
716 TIME_SET_MINUTE(self, minute);
717 TIME_SET_SECOND(self, second);
718 TIME_SET_MICROSECOND(self, usecond);
719 if (aware) {
720 Py_INCREF(tzinfo);
721 self->tzinfo = tzinfo;
722 }
723 }
724 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000725}
726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727#define new_time(hh, mm, ss, us, tzinfo) \
728 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000729
730/* Create a timedelta instance. Normalize the members iff normalize is
731 * true. Passing false is a speed optimization, if you know for sure
732 * that seconds and microseconds are already in their proper ranges. In any
733 * case, raises OverflowError and returns NULL if the normalized days is out
734 * of range).
735 */
736static PyObject *
737new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 if (normalize)
743 normalize_d_s_us(&days, &seconds, &microseconds);
744 assert(0 <= seconds && seconds < 24*3600);
745 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000746
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 if (check_delta_day_range(days) < 0)
748 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
751 if (self != NULL) {
752 self->hashcode = -1;
753 SET_TD_DAYS(self, days);
754 SET_TD_SECONDS(self, seconds);
755 SET_TD_MICROSECONDS(self, microseconds);
756 }
757 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000758}
759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760#define new_delta(d, s, us, normalize) \
761 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000762
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000763
764typedef struct
765{
766 PyObject_HEAD
767 PyObject *offset;
768 PyObject *name;
769} PyDateTime_TimeZone;
770
Victor Stinner6ced7c42011-03-21 18:15:42 +0100771/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000772static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -0400773/* The interned Epoch datetime instance */
774static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000775
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000776/* Create new timezone instance checking offset range. This
777 function does not check the name argument. Caller must assure
778 that offset is a timedelta instance and name is either NULL
779 or a unicode object. */
780static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000781create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000782{
783 PyDateTime_TimeZone *self;
784 PyTypeObject *type = &PyDateTime_TimeZoneType;
785
786 assert(offset != NULL);
787 assert(PyDelta_Check(offset));
788 assert(name == NULL || PyUnicode_Check(name));
789
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000790 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
791 if (self == NULL) {
792 return NULL;
793 }
794 Py_INCREF(offset);
795 self->offset = offset;
796 Py_XINCREF(name);
797 self->name = name;
798 return (PyObject *)self;
799}
800
801static int delta_bool(PyDateTime_Delta *self);
802
803static PyObject *
804new_timezone(PyObject *offset, PyObject *name)
805{
806 assert(offset != NULL);
807 assert(PyDelta_Check(offset));
808 assert(name == NULL || PyUnicode_Check(name));
809
810 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
811 Py_INCREF(PyDateTime_TimeZone_UTC);
812 return PyDateTime_TimeZone_UTC;
813 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000814 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
815 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400816 " representing a whole number of minutes,"
817 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000818 return NULL;
819 }
820 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
821 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
822 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
823 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400824 " timedelta(hours=24),"
825 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000826 return NULL;
827 }
828
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000829 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000830}
831
Tim Petersb0c854d2003-05-17 15:57:00 +0000832/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000833 * tzinfo helpers.
834 */
835
Tim Peters855fe882002-12-22 03:43:39 +0000836/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
837 * raise TypeError and return -1.
838 */
839static int
840check_tzinfo_subclass(PyObject *p)
841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 if (p == Py_None || PyTZInfo_Check(p))
843 return 0;
844 PyErr_Format(PyExc_TypeError,
845 "tzinfo argument must be None or of a tzinfo subclass, "
846 "not type '%s'",
847 Py_TYPE(p)->tp_name);
848 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000849}
850
Tim Peters2a799bf2002-12-16 20:18:38 +0000851/* If self has a tzinfo member, return a BORROWED reference to it. Else
852 * return NULL, which is NOT AN ERROR. There are no error returns here,
853 * and the caller must not decref the result.
854 */
855static PyObject *
856get_tzinfo_member(PyObject *self)
857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 if (PyDateTime_Check(self) && HASTZINFO(self))
861 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
862 else if (PyTime_Check(self) && HASTZINFO(self))
863 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000866}
867
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000868/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
869 * be an instance of the tzinfo class. If the method returns None, this
870 * returns None. If the method doesn't return None or timedelta, TypeError is
871 * raised and this returns NULL. If it returns a timedelta and the value is
872 * out of range or isn't a whole number of minutes, ValueError is raised and
873 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000874 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000875static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200876call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000877{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000878 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000881 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000883
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000884 if (tzinfo == Py_None)
885 Py_RETURN_NONE;
886 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
887 if (offset == Py_None || offset == NULL)
888 return offset;
889 if (PyDelta_Check(offset)) {
890 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
891 Py_DECREF(offset);
892 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
893 " representing a whole number of minutes");
894 return NULL;
895 }
896 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
897 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
898 Py_DECREF(offset);
899 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
900 " strictly between -timedelta(hours=24) and"
901 " timedelta(hours=24).");
902 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 }
904 }
905 else {
906 PyErr_Format(PyExc_TypeError,
907 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000908 "timedelta, not '%.200s'",
909 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -0700910 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000911 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000913
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000914 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000915}
916
917/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
918 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
919 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000920 * doesn't return None or timedelta, TypeError is raised and this returns -1.
921 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
922 * # of minutes), ValueError is raised and this returns -1. Else *none is
923 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000924 */
Tim Peters855fe882002-12-22 03:43:39 +0000925static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000926call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
927{
928 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000929}
930
Tim Peters2a799bf2002-12-16 20:18:38 +0000931/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
932 * result. tzinfo must be an instance of the tzinfo class. If dst()
933 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000934 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000935 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000936 * ValueError is raised and this returns -1. Else *none is set to 0 and
937 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000938 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000939static PyObject *
940call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000941{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000942 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000943}
944
Tim Petersbad8ff02002-12-30 20:52:32 +0000945/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000946 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000947 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000948 * returns NULL. If the result is a string, we ensure it is a Unicode
949 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000950 */
951static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000952call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200955 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 assert(tzinfo != NULL);
958 assert(check_tzinfo_subclass(tzinfo) >= 0);
959 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000962 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000963
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200964 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000965
966 if (result == NULL || result == Py_None)
967 return result;
968
969 if (!PyUnicode_Check(result)) {
970 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
971 "return None or a string, not '%s'",
972 Py_TYPE(result)->tp_name);
973 Py_DECREF(result);
974 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000976
977 return result;
Tim Peters00237032002-12-27 02:21:51 +0000978}
979
Tim Peters2a799bf2002-12-16 20:18:38 +0000980/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
981 * stuff
982 * ", tzinfo=" + repr(tzinfo)
983 * before the closing ")".
984 */
985static PyObject *
986append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 assert(PyUnicode_Check(repr));
991 assert(tzinfo);
992 if (tzinfo == Py_None)
993 return repr;
994 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200995 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
996 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 Py_DECREF(repr);
998 if (temp == NULL)
999 return NULL;
1000 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1001 Py_DECREF(temp);
1002 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001003}
1004
1005/* ---------------------------------------------------------------------------
1006 * String format helpers.
1007 */
1008
1009static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001010format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001011{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001012 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1014 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001015 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1017 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1018 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1023 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1024 GET_DAY(date), hours, minutes, seconds,
1025 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001026}
1027
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001028static PyObject *delta_negative(PyDateTime_Delta *self);
1029
Tim Peters2a799bf2002-12-16 20:18:38 +00001030/* Add an hours & minutes UTC offset string to buf. buf has no more than
1031 * buflen bytes remaining. The UTC offset is gotten by calling
1032 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1033 * *buf, and that's all. Else the returned value is checked for sanity (an
1034 * integer in range), and if that's OK it's converted to an hours & minutes
1035 * string of the form
1036 * sign HH sep MM
1037 * Returns 0 if everything is OK. If the return value from utcoffset() is
1038 * bogus, an appropriate exception is set and -1 is returned.
1039 */
1040static int
Tim Peters328fff72002-12-20 01:31:27 +00001041format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001043{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001044 PyObject *offset;
1045 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001049
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001050 offset = call_utcoffset(tzinfo, tzinfoarg);
1051 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001053 if (offset == Py_None) {
1054 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 *buf = '\0';
1056 return 0;
1057 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001058 /* Offset is normalized, so it is negative if days < 0 */
1059 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001061 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001062 if (offset == NULL)
1063 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001065 else {
1066 sign = '+';
1067 }
1068 /* Offset is not negative here. */
1069 seconds = GET_TD_SECONDS(offset);
1070 Py_DECREF(offset);
1071 minutes = divmod(seconds, 60, &seconds);
1072 hours = divmod(minutes, 60, &minutes);
1073 assert(seconds == 0);
1074 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001078}
1079
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001080static PyObject *
1081make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 PyObject *temp;
1084 PyObject *tzinfo = get_tzinfo_member(object);
1085 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001086 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 if (Zreplacement == NULL)
1089 return NULL;
1090 if (tzinfo == Py_None || tzinfo == NULL)
1091 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 assert(tzinfoarg != NULL);
1094 temp = call_tzname(tzinfo, tzinfoarg);
1095 if (temp == NULL)
1096 goto Error;
1097 if (temp == Py_None) {
1098 Py_DECREF(temp);
1099 return Zreplacement;
1100 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 assert(PyUnicode_Check(temp));
1103 /* Since the tzname is getting stuffed into the
1104 * format, we have to double any % signs so that
1105 * strftime doesn't treat them as format codes.
1106 */
1107 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001108 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 Py_DECREF(temp);
1110 if (Zreplacement == NULL)
1111 return NULL;
1112 if (!PyUnicode_Check(Zreplacement)) {
1113 PyErr_SetString(PyExc_TypeError,
1114 "tzname.replace() did not return a string");
1115 goto Error;
1116 }
1117 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001118
1119 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 Py_DECREF(Zreplacement);
1121 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001122}
1123
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001124static PyObject *
1125make_freplacement(PyObject *object)
1126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 char freplacement[64];
1128 if (PyTime_Check(object))
1129 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1130 else if (PyDateTime_Check(object))
1131 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1132 else
1133 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001136}
1137
Tim Peters2a799bf2002-12-16 20:18:38 +00001138/* I sure don't want to reproduce the strftime code from the time module,
1139 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001140 * giving special meanings to the %z, %Z and %f format codes via a
1141 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001142 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1143 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001144 */
1145static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001146wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1152 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1153 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 const char *pin; /* pointer to next char in input format */
1156 Py_ssize_t flen; /* length of input format */
1157 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 PyObject *newfmt = NULL; /* py string, the output format */
1160 char *pnew; /* pointer to available byte in output format */
1161 size_t totalnew; /* number bytes total in output format buffer,
1162 exclusive of trailing \0 */
1163 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 const char *ptoappend; /* ptr to string to append to output buffer */
1166 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 assert(object && format && timetuple);
1169 assert(PyUnicode_Check(format));
1170 /* Convert the input format to a C string and size */
1171 pin = _PyUnicode_AsStringAndSize(format, &flen);
1172 if (!pin)
1173 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 /* Scan the input format, looking for %z/%Z/%f escapes, building
1176 * a new format. Since computing the replacements for those codes
1177 * is expensive, don't unless they're actually used.
1178 */
1179 if (flen > INT_MAX - 1) {
1180 PyErr_NoMemory();
1181 goto Done;
1182 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 totalnew = flen + 1; /* realistic if no %z/%Z */
1185 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1186 if (newfmt == NULL) goto Done;
1187 pnew = PyBytes_AsString(newfmt);
1188 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 while ((ch = *pin++) != '\0') {
1191 if (ch != '%') {
1192 ptoappend = pin - 1;
1193 ntoappend = 1;
1194 }
1195 else if ((ch = *pin++) == '\0') {
1196 /* There's a lone trailing %; doesn't make sense. */
1197 PyErr_SetString(PyExc_ValueError, "strftime format "
1198 "ends with raw %");
1199 goto Done;
1200 }
1201 /* A % has been seen and ch is the character after it. */
1202 else if (ch == 'z') {
1203 if (zreplacement == NULL) {
1204 /* format utcoffset */
1205 char buf[100];
1206 PyObject *tzinfo = get_tzinfo_member(object);
1207 zreplacement = PyBytes_FromStringAndSize("", 0);
1208 if (zreplacement == NULL) goto Done;
1209 if (tzinfo != Py_None && tzinfo != NULL) {
1210 assert(tzinfoarg != NULL);
1211 if (format_utcoffset(buf,
1212 sizeof(buf),
1213 "",
1214 tzinfo,
1215 tzinfoarg) < 0)
1216 goto Done;
1217 Py_DECREF(zreplacement);
1218 zreplacement =
1219 PyBytes_FromStringAndSize(buf,
1220 strlen(buf));
1221 if (zreplacement == NULL)
1222 goto Done;
1223 }
1224 }
1225 assert(zreplacement != NULL);
1226 ptoappend = PyBytes_AS_STRING(zreplacement);
1227 ntoappend = PyBytes_GET_SIZE(zreplacement);
1228 }
1229 else if (ch == 'Z') {
1230 /* format tzname */
1231 if (Zreplacement == NULL) {
1232 Zreplacement = make_Zreplacement(object,
1233 tzinfoarg);
1234 if (Zreplacement == NULL)
1235 goto Done;
1236 }
1237 assert(Zreplacement != NULL);
1238 assert(PyUnicode_Check(Zreplacement));
1239 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1240 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001241 if (ptoappend == NULL)
1242 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 }
1244 else if (ch == 'f') {
1245 /* format microseconds */
1246 if (freplacement == NULL) {
1247 freplacement = make_freplacement(object);
1248 if (freplacement == NULL)
1249 goto Done;
1250 }
1251 assert(freplacement != NULL);
1252 assert(PyBytes_Check(freplacement));
1253 ptoappend = PyBytes_AS_STRING(freplacement);
1254 ntoappend = PyBytes_GET_SIZE(freplacement);
1255 }
1256 else {
1257 /* percent followed by neither z nor Z */
1258 ptoappend = pin - 2;
1259 ntoappend = 2;
1260 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 /* Append the ntoappend chars starting at ptoappend to
1263 * the new format.
1264 */
1265 if (ntoappend == 0)
1266 continue;
1267 assert(ptoappend != NULL);
1268 assert(ntoappend > 0);
1269 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001270 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 PyErr_NoMemory();
1272 goto Done;
1273 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001274 totalnew <<= 1;
1275 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 pnew = PyBytes_AsString(newfmt) + usednew;
1278 }
1279 memcpy(pnew, ptoappend, ntoappend);
1280 pnew += ntoappend;
1281 usednew += ntoappend;
1282 assert(usednew <= totalnew);
1283 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1286 goto Done;
1287 {
1288 PyObject *format;
1289 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 if (time == NULL)
1292 goto Done;
1293 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1294 if (format != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001295 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1296 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 Py_DECREF(format);
1298 }
1299 Py_DECREF(time);
1300 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001301 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 Py_XDECREF(freplacement);
1303 Py_XDECREF(zreplacement);
1304 Py_XDECREF(Zreplacement);
1305 Py_XDECREF(newfmt);
1306 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001307}
1308
Tim Peters2a799bf2002-12-16 20:18:38 +00001309/* ---------------------------------------------------------------------------
1310 * Wrap functions from the time module. These aren't directly available
1311 * from C. Perhaps they should be.
1312 */
1313
1314/* Call time.time() and return its result (a Python float). */
1315static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001316time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 PyObject *result = NULL;
1319 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001322 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001323
1324 result = _PyObject_CallMethodId(time, &PyId_time, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 Py_DECREF(time);
1326 }
1327 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001328}
1329
1330/* Build a time.struct_time. The weekday and day number are automatically
1331 * computed from the y,m,d args.
1332 */
1333static PyObject *
1334build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 PyObject *time;
1337 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 time = PyImport_ImportModuleNoBlock("time");
1340 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001341 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001342
1343 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1344 "((iiiiiiiii))",
1345 y, m, d,
1346 hh, mm, ss,
1347 weekday(y, m, d),
1348 days_before_month(y, m) + d,
1349 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 Py_DECREF(time);
1351 }
1352 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001353}
1354
1355/* ---------------------------------------------------------------------------
1356 * Miscellaneous helpers.
1357 */
1358
Mark Dickinsone94c6792009-02-02 20:36:42 +00001359/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001360 * The comparisons here all most naturally compute a cmp()-like result.
1361 * This little helper turns that into a bool result for rich comparisons.
1362 */
1363static PyObject *
1364diff_to_bool(int diff, int op)
1365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 PyObject *result;
1367 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 switch (op) {
1370 case Py_EQ: istrue = diff == 0; break;
1371 case Py_NE: istrue = diff != 0; break;
1372 case Py_LE: istrue = diff <= 0; break;
1373 case Py_GE: istrue = diff >= 0; break;
1374 case Py_LT: istrue = diff < 0; break;
1375 case Py_GT: istrue = diff > 0; break;
1376 default:
1377 assert(! "op unknown");
1378 istrue = 0; /* To shut up compiler */
1379 }
1380 result = istrue ? Py_True : Py_False;
1381 Py_INCREF(result);
1382 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001383}
1384
Tim Peters07534a62003-02-07 22:50:28 +00001385/* Raises a "can't compare" TypeError and returns NULL. */
1386static PyObject *
1387cmperror(PyObject *a, PyObject *b)
1388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 PyErr_Format(PyExc_TypeError,
1390 "can't compare %s to %s",
1391 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1392 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001393}
1394
Tim Peters2a799bf2002-12-16 20:18:38 +00001395/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001396 * Cached Python objects; these are set by the module init function.
1397 */
1398
1399/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001400static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401static PyObject *us_per_ms = NULL; /* 1000 */
1402static PyObject *us_per_second = NULL; /* 1000000 */
1403static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001404static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1405static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1406static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001407static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1408
Tim Peters2a799bf2002-12-16 20:18:38 +00001409/* ---------------------------------------------------------------------------
1410 * Class implementations.
1411 */
1412
1413/*
1414 * PyDateTime_Delta implementation.
1415 */
1416
1417/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001419 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001420 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1421 * due to ubiquitous overflow possibilities.
1422 */
1423static PyObject *
1424delta_to_microseconds(PyDateTime_Delta *self)
1425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 PyObject *x1 = NULL;
1427 PyObject *x2 = NULL;
1428 PyObject *x3 = NULL;
1429 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1432 if (x1 == NULL)
1433 goto Done;
1434 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1435 if (x2 == NULL)
1436 goto Done;
1437 Py_DECREF(x1);
1438 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 /* x2 has days in seconds */
1441 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1442 if (x1 == NULL)
1443 goto Done;
1444 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1445 if (x3 == NULL)
1446 goto Done;
1447 Py_DECREF(x1);
1448 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001449 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 /* x3 has days+seconds in seconds */
1452 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1453 if (x1 == NULL)
1454 goto Done;
1455 Py_DECREF(x3);
1456 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 /* x1 has days+seconds in us */
1459 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1460 if (x2 == NULL)
1461 goto Done;
1462 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001463
1464Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 Py_XDECREF(x1);
1466 Py_XDECREF(x2);
1467 Py_XDECREF(x3);
1468 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001469}
1470
Serhiy Storchaka95949422013-08-27 19:40:23 +03001471/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001472 */
1473static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001474microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 int us;
1477 int s;
1478 int d;
1479 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 PyObject *tuple = NULL;
1482 PyObject *num = NULL;
1483 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 tuple = PyNumber_Divmod(pyus, us_per_second);
1486 if (tuple == NULL)
1487 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 num = PyTuple_GetItem(tuple, 1); /* us */
1490 if (num == NULL)
1491 goto Done;
1492 temp = PyLong_AsLong(num);
1493 num = NULL;
1494 if (temp == -1 && PyErr_Occurred())
1495 goto Done;
1496 assert(0 <= temp && temp < 1000000);
1497 us = (int)temp;
1498 if (us < 0) {
1499 /* The divisor was positive, so this must be an error. */
1500 assert(PyErr_Occurred());
1501 goto Done;
1502 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1505 if (num == NULL)
1506 goto Done;
1507 Py_INCREF(num);
1508 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 tuple = PyNumber_Divmod(num, seconds_per_day);
1511 if (tuple == NULL)
1512 goto Done;
1513 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 num = PyTuple_GetItem(tuple, 1); /* seconds */
1516 if (num == NULL)
1517 goto Done;
1518 temp = PyLong_AsLong(num);
1519 num = NULL;
1520 if (temp == -1 && PyErr_Occurred())
1521 goto Done;
1522 assert(0 <= temp && temp < 24*3600);
1523 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 if (s < 0) {
1526 /* The divisor was positive, so this must be an error. */
1527 assert(PyErr_Occurred());
1528 goto Done;
1529 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1532 if (num == NULL)
1533 goto Done;
1534 Py_INCREF(num);
1535 temp = PyLong_AsLong(num);
1536 if (temp == -1 && PyErr_Occurred())
1537 goto Done;
1538 d = (int)temp;
1539 if ((long)d != temp) {
1540 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1541 "large to fit in a C int");
1542 goto Done;
1543 }
1544 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001545
1546Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 Py_XDECREF(tuple);
1548 Py_XDECREF(num);
1549 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001550}
1551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552#define microseconds_to_delta(pymicros) \
1553 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001554
Tim Peters2a799bf2002-12-16 20:18:38 +00001555static PyObject *
1556multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 PyObject *pyus_in;
1559 PyObject *pyus_out;
1560 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 pyus_in = delta_to_microseconds(delta);
1563 if (pyus_in == NULL)
1564 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1567 Py_DECREF(pyus_in);
1568 if (pyus_out == NULL)
1569 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 result = microseconds_to_delta(pyus_out);
1572 Py_DECREF(pyus_out);
1573 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001574}
1575
1576static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001577multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1578{
1579 PyObject *result = NULL;
1580 PyObject *pyus_in = NULL, *temp, *pyus_out;
1581 PyObject *ratio = NULL;
1582
1583 pyus_in = delta_to_microseconds(delta);
1584 if (pyus_in == NULL)
1585 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001586 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001587 if (ratio == NULL)
1588 goto error;
1589 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1590 Py_DECREF(pyus_in);
1591 pyus_in = NULL;
1592 if (temp == NULL)
1593 goto error;
1594 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1595 Py_DECREF(temp);
1596 if (pyus_out == NULL)
1597 goto error;
1598 result = microseconds_to_delta(pyus_out);
1599 Py_DECREF(pyus_out);
1600 error:
1601 Py_XDECREF(pyus_in);
1602 Py_XDECREF(ratio);
1603
1604 return result;
1605}
1606
1607static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001608divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 PyObject *pyus_in;
1611 PyObject *pyus_out;
1612 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 pyus_in = delta_to_microseconds(delta);
1615 if (pyus_in == NULL)
1616 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1619 Py_DECREF(pyus_in);
1620 if (pyus_out == NULL)
1621 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 result = microseconds_to_delta(pyus_out);
1624 Py_DECREF(pyus_out);
1625 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001626}
1627
1628static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001629divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 PyObject *pyus_left;
1632 PyObject *pyus_right;
1633 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 pyus_left = delta_to_microseconds(left);
1636 if (pyus_left == NULL)
1637 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 pyus_right = delta_to_microseconds(right);
1640 if (pyus_right == NULL) {
1641 Py_DECREF(pyus_left);
1642 return NULL;
1643 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1646 Py_DECREF(pyus_left);
1647 Py_DECREF(pyus_right);
1648 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001649}
1650
1651static PyObject *
1652truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 PyObject *pyus_left;
1655 PyObject *pyus_right;
1656 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 pyus_left = delta_to_microseconds(left);
1659 if (pyus_left == NULL)
1660 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 pyus_right = delta_to_microseconds(right);
1663 if (pyus_right == NULL) {
1664 Py_DECREF(pyus_left);
1665 return NULL;
1666 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1669 Py_DECREF(pyus_left);
1670 Py_DECREF(pyus_right);
1671 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001672}
1673
1674static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001675truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1676{
1677 PyObject *result = NULL;
1678 PyObject *pyus_in = NULL, *temp, *pyus_out;
1679 PyObject *ratio = NULL;
1680
1681 pyus_in = delta_to_microseconds(delta);
1682 if (pyus_in == NULL)
1683 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001684 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001685 if (ratio == NULL)
1686 goto error;
1687 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1688 Py_DECREF(pyus_in);
1689 pyus_in = NULL;
1690 if (temp == NULL)
1691 goto error;
1692 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1693 Py_DECREF(temp);
1694 if (pyus_out == NULL)
1695 goto error;
1696 result = microseconds_to_delta(pyus_out);
1697 Py_DECREF(pyus_out);
1698 error:
1699 Py_XDECREF(pyus_in);
1700 Py_XDECREF(ratio);
1701
1702 return result;
1703}
1704
1705static PyObject *
1706truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1707{
1708 PyObject *result;
1709 PyObject *pyus_in, *pyus_out;
1710 pyus_in = delta_to_microseconds(delta);
1711 if (pyus_in == NULL)
1712 return NULL;
1713 pyus_out = divide_nearest(pyus_in, i);
1714 Py_DECREF(pyus_in);
1715 if (pyus_out == NULL)
1716 return NULL;
1717 result = microseconds_to_delta(pyus_out);
1718 Py_DECREF(pyus_out);
1719
1720 return result;
1721}
1722
1723static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001724delta_add(PyObject *left, PyObject *right)
1725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1729 /* delta + delta */
1730 /* The C-level additions can't overflow because of the
1731 * invariant bounds.
1732 */
1733 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1734 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1735 int microseconds = GET_TD_MICROSECONDS(left) +
1736 GET_TD_MICROSECONDS(right);
1737 result = new_delta(days, seconds, microseconds, 1);
1738 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 if (result == Py_NotImplemented)
1741 Py_INCREF(result);
1742 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001743}
1744
1745static PyObject *
1746delta_negative(PyDateTime_Delta *self)
1747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 return new_delta(-GET_TD_DAYS(self),
1749 -GET_TD_SECONDS(self),
1750 -GET_TD_MICROSECONDS(self),
1751 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001752}
1753
1754static PyObject *
1755delta_positive(PyDateTime_Delta *self)
1756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 /* Could optimize this (by returning self) if this isn't a
1758 * subclass -- but who uses unary + ? Approximately nobody.
1759 */
1760 return new_delta(GET_TD_DAYS(self),
1761 GET_TD_SECONDS(self),
1762 GET_TD_MICROSECONDS(self),
1763 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001764}
1765
1766static PyObject *
1767delta_abs(PyDateTime_Delta *self)
1768{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 assert(GET_TD_MICROSECONDS(self) >= 0);
1772 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 if (GET_TD_DAYS(self) < 0)
1775 result = delta_negative(self);
1776 else
1777 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001780}
1781
1782static PyObject *
1783delta_subtract(PyObject *left, PyObject *right)
1784{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1788 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001789 /* The C-level additions can't overflow because of the
1790 * invariant bounds.
1791 */
1792 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1793 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1794 int microseconds = GET_TD_MICROSECONDS(left) -
1795 GET_TD_MICROSECONDS(right);
1796 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 if (result == Py_NotImplemented)
1800 Py_INCREF(result);
1801 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001802}
1803
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001804static int
1805delta_cmp(PyObject *self, PyObject *other)
1806{
1807 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1808 if (diff == 0) {
1809 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1810 if (diff == 0)
1811 diff = GET_TD_MICROSECONDS(self) -
1812 GET_TD_MICROSECONDS(other);
1813 }
1814 return diff;
1815}
1816
Tim Peters2a799bf2002-12-16 20:18:38 +00001817static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001818delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001821 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 return diff_to_bool(diff, op);
1823 }
1824 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001825 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001827}
1828
1829static PyObject *delta_getstate(PyDateTime_Delta *self);
1830
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001831static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001832delta_hash(PyDateTime_Delta *self)
1833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 if (self->hashcode == -1) {
1835 PyObject *temp = delta_getstate(self);
1836 if (temp != NULL) {
1837 self->hashcode = PyObject_Hash(temp);
1838 Py_DECREF(temp);
1839 }
1840 }
1841 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001842}
1843
1844static PyObject *
1845delta_multiply(PyObject *left, PyObject *right)
1846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 if (PyDelta_Check(left)) {
1850 /* delta * ??? */
1851 if (PyLong_Check(right))
1852 result = multiply_int_timedelta(right,
1853 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001854 else if (PyFloat_Check(right))
1855 result = multiply_float_timedelta(right,
1856 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 }
1858 else if (PyLong_Check(left))
1859 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001860 (PyDateTime_Delta *) right);
1861 else if (PyFloat_Check(left))
1862 result = multiply_float_timedelta(left,
1863 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 if (result == Py_NotImplemented)
1866 Py_INCREF(result);
1867 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001868}
1869
1870static PyObject *
1871delta_divide(PyObject *left, PyObject *right)
1872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 if (PyDelta_Check(left)) {
1876 /* delta * ??? */
1877 if (PyLong_Check(right))
1878 result = divide_timedelta_int(
1879 (PyDateTime_Delta *)left,
1880 right);
1881 else if (PyDelta_Check(right))
1882 result = divide_timedelta_timedelta(
1883 (PyDateTime_Delta *)left,
1884 (PyDateTime_Delta *)right);
1885 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 if (result == Py_NotImplemented)
1888 Py_INCREF(result);
1889 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001890}
1891
Mark Dickinson7c186e22010-04-20 22:32:49 +00001892static PyObject *
1893delta_truedivide(PyObject *left, PyObject *right)
1894{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 if (PyDelta_Check(left)) {
1898 if (PyDelta_Check(right))
1899 result = truedivide_timedelta_timedelta(
1900 (PyDateTime_Delta *)left,
1901 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001902 else if (PyFloat_Check(right))
1903 result = truedivide_timedelta_float(
1904 (PyDateTime_Delta *)left, right);
1905 else if (PyLong_Check(right))
1906 result = truedivide_timedelta_int(
1907 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 if (result == Py_NotImplemented)
1911 Py_INCREF(result);
1912 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001913}
1914
1915static PyObject *
1916delta_remainder(PyObject *left, PyObject *right)
1917{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 PyObject *pyus_left;
1919 PyObject *pyus_right;
1920 PyObject *pyus_remainder;
1921 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001922
Brian Curtindfc80e32011-08-10 20:28:54 -05001923 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1924 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1927 if (pyus_left == NULL)
1928 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1931 if (pyus_right == NULL) {
1932 Py_DECREF(pyus_left);
1933 return NULL;
1934 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1937 Py_DECREF(pyus_left);
1938 Py_DECREF(pyus_right);
1939 if (pyus_remainder == NULL)
1940 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 remainder = microseconds_to_delta(pyus_remainder);
1943 Py_DECREF(pyus_remainder);
1944 if (remainder == NULL)
1945 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001948}
1949
1950static PyObject *
1951delta_divmod(PyObject *left, PyObject *right)
1952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 PyObject *pyus_left;
1954 PyObject *pyus_right;
1955 PyObject *divmod;
1956 PyObject *delta;
1957 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001958
Brian Curtindfc80e32011-08-10 20:28:54 -05001959 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1960 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1963 if (pyus_left == NULL)
1964 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1967 if (pyus_right == NULL) {
1968 Py_DECREF(pyus_left);
1969 return NULL;
1970 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1973 Py_DECREF(pyus_left);
1974 Py_DECREF(pyus_right);
1975 if (divmod == NULL)
1976 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 assert(PyTuple_Size(divmod) == 2);
1979 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1980 if (delta == NULL) {
1981 Py_DECREF(divmod);
1982 return NULL;
1983 }
1984 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1985 Py_DECREF(delta);
1986 Py_DECREF(divmod);
1987 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001988}
1989
Tim Peters2a799bf2002-12-16 20:18:38 +00001990/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1991 * timedelta constructor. sofar is the # of microseconds accounted for
1992 * so far, and there are factor microseconds per current unit, the number
1993 * of which is given by num. num * factor is added to sofar in a
1994 * numerically careful way, and that's the result. Any fractional
1995 * microseconds left over (this can happen if num is a float type) are
1996 * added into *leftover.
1997 * Note that there are many ways this can give an error (NULL) return.
1998 */
1999static PyObject *
2000accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2001 double *leftover)
2002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 PyObject *prod;
2004 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 if (PyLong_Check(num)) {
2009 prod = PyNumber_Multiply(num, factor);
2010 if (prod == NULL)
2011 return NULL;
2012 sum = PyNumber_Add(sofar, prod);
2013 Py_DECREF(prod);
2014 return sum;
2015 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 if (PyFloat_Check(num)) {
2018 double dnum;
2019 double fracpart;
2020 double intpart;
2021 PyObject *x;
2022 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 /* The Plan: decompose num into an integer part and a
2025 * fractional part, num = intpart + fracpart.
2026 * Then num * factor ==
2027 * intpart * factor + fracpart * factor
2028 * and the LHS can be computed exactly in long arithmetic.
2029 * The RHS is again broken into an int part and frac part.
2030 * and the frac part is added into *leftover.
2031 */
2032 dnum = PyFloat_AsDouble(num);
2033 if (dnum == -1.0 && PyErr_Occurred())
2034 return NULL;
2035 fracpart = modf(dnum, &intpart);
2036 x = PyLong_FromDouble(intpart);
2037 if (x == NULL)
2038 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 prod = PyNumber_Multiply(x, factor);
2041 Py_DECREF(x);
2042 if (prod == NULL)
2043 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 sum = PyNumber_Add(sofar, prod);
2046 Py_DECREF(prod);
2047 if (sum == NULL)
2048 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 if (fracpart == 0.0)
2051 return sum;
2052 /* So far we've lost no information. Dealing with the
2053 * fractional part requires float arithmetic, and may
2054 * lose a little info.
2055 */
2056 assert(PyLong_Check(factor));
2057 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 dnum *= fracpart;
2060 fracpart = modf(dnum, &intpart);
2061 x = PyLong_FromDouble(intpart);
2062 if (x == NULL) {
2063 Py_DECREF(sum);
2064 return NULL;
2065 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 y = PyNumber_Add(sum, x);
2068 Py_DECREF(sum);
2069 Py_DECREF(x);
2070 *leftover += fracpart;
2071 return y;
2072 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 PyErr_Format(PyExc_TypeError,
2075 "unsupported type for timedelta %s component: %s",
2076 tag, Py_TYPE(num)->tp_name);
2077 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002078}
2079
2080static PyObject *
2081delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 /* Argument objects. */
2086 PyObject *day = NULL;
2087 PyObject *second = NULL;
2088 PyObject *us = NULL;
2089 PyObject *ms = NULL;
2090 PyObject *minute = NULL;
2091 PyObject *hour = NULL;
2092 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 PyObject *x = NULL; /* running sum of microseconds */
2095 PyObject *y = NULL; /* temp sum of microseconds */
2096 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 static char *keywords[] = {
2099 "days", "seconds", "microseconds", "milliseconds",
2100 "minutes", "hours", "weeks", NULL
2101 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2104 keywords,
2105 &day, &second, &us,
2106 &ms, &minute, &hour, &week) == 0)
2107 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 x = PyLong_FromLong(0);
2110 if (x == NULL)
2111 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113#define CLEANUP \
2114 Py_DECREF(x); \
2115 x = y; \
2116 if (x == NULL) \
2117 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002120 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 CLEANUP;
2122 }
2123 if (ms) {
2124 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2125 CLEANUP;
2126 }
2127 if (second) {
2128 y = accum("seconds", x, second, us_per_second, &leftover_us);
2129 CLEANUP;
2130 }
2131 if (minute) {
2132 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2133 CLEANUP;
2134 }
2135 if (hour) {
2136 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2137 CLEANUP;
2138 }
2139 if (day) {
2140 y = accum("days", x, day, us_per_day, &leftover_us);
2141 CLEANUP;
2142 }
2143 if (week) {
2144 y = accum("weeks", x, week, us_per_week, &leftover_us);
2145 CLEANUP;
2146 }
2147 if (leftover_us) {
2148 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002149 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002150 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002151 PyObject *temp;
2152
Victor Stinner69cc4872015-09-08 23:58:54 +02002153 whole_us = round(leftover_us);
2154 if (fabs(whole_us - leftover_us) == 0.5) {
2155 /* We're exactly halfway between two integers. In order
2156 * to do round-half-to-even, we must determine whether x
2157 * is odd. Note that x is odd when it's last bit is 1. The
2158 * code below uses bitwise and operation to check the last
2159 * bit. */
2160 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2161 if (temp == NULL) {
2162 Py_DECREF(x);
2163 goto Done;
2164 }
2165 x_is_odd = PyObject_IsTrue(temp);
2166 Py_DECREF(temp);
2167 if (x_is_odd == -1) {
2168 Py_DECREF(x);
2169 goto Done;
2170 }
2171 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2172 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002173
Victor Stinner36a5a062013-08-28 01:53:39 +02002174 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 if (temp == NULL) {
2177 Py_DECREF(x);
2178 goto Done;
2179 }
2180 y = PyNumber_Add(x, temp);
2181 Py_DECREF(temp);
2182 CLEANUP;
2183 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 self = microseconds_to_delta_ex(x, type);
2186 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002187Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002189
2190#undef CLEANUP
2191}
2192
2193static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002194delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 return (GET_TD_DAYS(self) != 0
2197 || GET_TD_SECONDS(self) != 0
2198 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002199}
2200
2201static PyObject *
2202delta_repr(PyDateTime_Delta *self)
2203{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 if (GET_TD_MICROSECONDS(self) != 0)
2205 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2206 Py_TYPE(self)->tp_name,
2207 GET_TD_DAYS(self),
2208 GET_TD_SECONDS(self),
2209 GET_TD_MICROSECONDS(self));
2210 if (GET_TD_SECONDS(self) != 0)
2211 return PyUnicode_FromFormat("%s(%d, %d)",
2212 Py_TYPE(self)->tp_name,
2213 GET_TD_DAYS(self),
2214 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002216 return PyUnicode_FromFormat("%s(%d)",
2217 Py_TYPE(self)->tp_name,
2218 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002219}
2220
2221static PyObject *
2222delta_str(PyDateTime_Delta *self)
2223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 int us = GET_TD_MICROSECONDS(self);
2225 int seconds = GET_TD_SECONDS(self);
2226 int minutes = divmod(seconds, 60, &seconds);
2227 int hours = divmod(minutes, 60, &minutes);
2228 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002230 if (days) {
2231 if (us)
2232 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2233 days, (days == 1 || days == -1) ? "" : "s",
2234 hours, minutes, seconds, us);
2235 else
2236 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2237 days, (days == 1 || days == -1) ? "" : "s",
2238 hours, minutes, seconds);
2239 } else {
2240 if (us)
2241 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2242 hours, minutes, seconds, us);
2243 else
2244 return PyUnicode_FromFormat("%d:%02d:%02d",
2245 hours, minutes, seconds);
2246 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002247
Tim Peters2a799bf2002-12-16 20:18:38 +00002248}
2249
Tim Peters371935f2003-02-01 01:52:50 +00002250/* Pickle support, a simple use of __reduce__. */
2251
Tim Petersb57f8f02003-02-01 02:54:15 +00002252/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002253static PyObject *
2254delta_getstate(PyDateTime_Delta *self)
2255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 return Py_BuildValue("iii", GET_TD_DAYS(self),
2257 GET_TD_SECONDS(self),
2258 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002259}
2260
Tim Peters2a799bf2002-12-16 20:18:38 +00002261static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002262delta_total_seconds(PyObject *self)
2263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 PyObject *total_seconds;
2265 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2268 if (total_microseconds == NULL)
2269 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002270
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002271 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002275}
2276
2277static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002278delta_reduce(PyDateTime_Delta* self)
2279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002281}
2282
2283#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2284
2285static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 {"days", T_INT, OFFSET(days), READONLY,
2288 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 {"seconds", T_INT, OFFSET(seconds), READONLY,
2291 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2294 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2295 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002296};
2297
2298static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2300 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2303 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002306};
2307
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002308static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002309PyDoc_STR("Difference between two datetime values.");
2310
2311static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 delta_add, /* nb_add */
2313 delta_subtract, /* nb_subtract */
2314 delta_multiply, /* nb_multiply */
2315 delta_remainder, /* nb_remainder */
2316 delta_divmod, /* nb_divmod */
2317 0, /* nb_power */
2318 (unaryfunc)delta_negative, /* nb_negative */
2319 (unaryfunc)delta_positive, /* nb_positive */
2320 (unaryfunc)delta_abs, /* nb_absolute */
2321 (inquiry)delta_bool, /* nb_bool */
2322 0, /*nb_invert*/
2323 0, /*nb_lshift*/
2324 0, /*nb_rshift*/
2325 0, /*nb_and*/
2326 0, /*nb_xor*/
2327 0, /*nb_or*/
2328 0, /*nb_int*/
2329 0, /*nb_reserved*/
2330 0, /*nb_float*/
2331 0, /*nb_inplace_add*/
2332 0, /*nb_inplace_subtract*/
2333 0, /*nb_inplace_multiply*/
2334 0, /*nb_inplace_remainder*/
2335 0, /*nb_inplace_power*/
2336 0, /*nb_inplace_lshift*/
2337 0, /*nb_inplace_rshift*/
2338 0, /*nb_inplace_and*/
2339 0, /*nb_inplace_xor*/
2340 0, /*nb_inplace_or*/
2341 delta_divide, /* nb_floor_divide */
2342 delta_truedivide, /* nb_true_divide */
2343 0, /* nb_inplace_floor_divide */
2344 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002345};
2346
2347static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 PyVarObject_HEAD_INIT(NULL, 0)
2349 "datetime.timedelta", /* tp_name */
2350 sizeof(PyDateTime_Delta), /* tp_basicsize */
2351 0, /* tp_itemsize */
2352 0, /* tp_dealloc */
2353 0, /* tp_print */
2354 0, /* tp_getattr */
2355 0, /* tp_setattr */
2356 0, /* tp_reserved */
2357 (reprfunc)delta_repr, /* tp_repr */
2358 &delta_as_number, /* tp_as_number */
2359 0, /* tp_as_sequence */
2360 0, /* tp_as_mapping */
2361 (hashfunc)delta_hash, /* tp_hash */
2362 0, /* tp_call */
2363 (reprfunc)delta_str, /* tp_str */
2364 PyObject_GenericGetAttr, /* tp_getattro */
2365 0, /* tp_setattro */
2366 0, /* tp_as_buffer */
2367 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2368 delta_doc, /* tp_doc */
2369 0, /* tp_traverse */
2370 0, /* tp_clear */
2371 delta_richcompare, /* tp_richcompare */
2372 0, /* tp_weaklistoffset */
2373 0, /* tp_iter */
2374 0, /* tp_iternext */
2375 delta_methods, /* tp_methods */
2376 delta_members, /* tp_members */
2377 0, /* tp_getset */
2378 0, /* tp_base */
2379 0, /* tp_dict */
2380 0, /* tp_descr_get */
2381 0, /* tp_descr_set */
2382 0, /* tp_dictoffset */
2383 0, /* tp_init */
2384 0, /* tp_alloc */
2385 delta_new, /* tp_new */
2386 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002387};
2388
2389/*
2390 * PyDateTime_Date implementation.
2391 */
2392
2393/* Accessor properties. */
2394
2395static PyObject *
2396date_year(PyDateTime_Date *self, void *unused)
2397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002399}
2400
2401static PyObject *
2402date_month(PyDateTime_Date *self, void *unused)
2403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002405}
2406
2407static PyObject *
2408date_day(PyDateTime_Date *self, void *unused)
2409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002411}
2412
2413static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 {"year", (getter)date_year},
2415 {"month", (getter)date_month},
2416 {"day", (getter)date_day},
2417 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002418};
2419
2420/* Constructors. */
2421
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002422static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002423
Tim Peters2a799bf2002-12-16 20:18:38 +00002424static PyObject *
2425date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 PyObject *self = NULL;
2428 PyObject *state;
2429 int year;
2430 int month;
2431 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 /* Check for invocation from pickle with __getstate__ state */
2434 if (PyTuple_GET_SIZE(args) == 1 &&
2435 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2436 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2437 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2438 {
2439 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002441 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2442 if (me != NULL) {
2443 char *pdata = PyBytes_AS_STRING(state);
2444 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2445 me->hashcode = -1;
2446 }
2447 return (PyObject *)me;
2448 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2451 &year, &month, &day)) {
2452 if (check_date_args(year, month, day) < 0)
2453 return NULL;
2454 self = new_date_ex(year, month, day, type);
2455 }
2456 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002457}
2458
2459/* Return new date from localtime(t). */
2460static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002461date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 struct tm *tm;
2464 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002465
Victor Stinnere4a994d2015-03-30 01:10:14 +02002466 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 tm = localtime(&t);
Victor Stinner21f58932012-03-14 00:15:40 +01002470 if (tm == NULL) {
2471 /* unconvertible time */
2472#ifdef EINVAL
2473 if (errno == 0)
2474 errno = EINVAL;
2475#endif
2476 PyErr_SetFromErrno(PyExc_OSError);
2477 return NULL;
2478 }
2479
2480 return PyObject_CallFunction(cls, "iii",
2481 tm->tm_year + 1900,
2482 tm->tm_mon + 1,
2483 tm->tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002484}
2485
2486/* Return new date from current time.
2487 * We say this is equivalent to fromtimestamp(time.time()), and the
2488 * only way to be sure of that is to *call* time.time(). That's not
2489 * generally the same as calling C's time.
2490 */
2491static PyObject *
2492date_today(PyObject *cls, PyObject *dummy)
2493{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002494 PyObject *time;
2495 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002496 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 time = time_time();
2499 if (time == NULL)
2500 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 /* Note well: today() is a class method, so this may not call
2503 * date.fromtimestamp. For example, it may call
2504 * datetime.fromtimestamp. That's why we need all the accuracy
2505 * time.time() delivers; if someone were gonzo about optimization,
2506 * date.today() could get away with plain C time().
2507 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002508 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 Py_DECREF(time);
2510 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002511}
2512
2513/* Return new date from given timestamp (Python timestamp -- a double). */
2514static PyObject *
2515date_fromtimestamp(PyObject *cls, PyObject *args)
2516{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002517 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002518 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002519
Victor Stinner5d272cc2012-03-13 13:35:55 +01002520 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2521 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002523}
2524
2525/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2526 * the ordinal is out of range.
2527 */
2528static PyObject *
2529date_fromordinal(PyObject *cls, PyObject *args)
2530{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002531 PyObject *result = NULL;
2532 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002534 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2535 int year;
2536 int month;
2537 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 if (ordinal < 1)
2540 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2541 ">= 1");
2542 else {
2543 ord_to_ymd(ordinal, &year, &month, &day);
2544 result = PyObject_CallFunction(cls, "iii",
2545 year, month, day);
2546 }
2547 }
2548 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002549}
2550
2551/*
2552 * Date arithmetic.
2553 */
2554
2555/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2556 * instead.
2557 */
2558static PyObject *
2559add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2560{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 PyObject *result = NULL;
2562 int year = GET_YEAR(date);
2563 int month = GET_MONTH(date);
2564 int deltadays = GET_TD_DAYS(delta);
2565 /* C-level overflow is impossible because |deltadays| < 1e9. */
2566 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002568 if (normalize_date(&year, &month, &day) >= 0)
2569 result = new_date(year, month, day);
2570 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002571}
2572
2573static PyObject *
2574date_add(PyObject *left, PyObject *right)
2575{
Brian Curtindfc80e32011-08-10 20:28:54 -05002576 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2577 Py_RETURN_NOTIMPLEMENTED;
2578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002579 if (PyDate_Check(left)) {
2580 /* date + ??? */
2581 if (PyDelta_Check(right))
2582 /* date + delta */
2583 return add_date_timedelta((PyDateTime_Date *) left,
2584 (PyDateTime_Delta *) right,
2585 0);
2586 }
2587 else {
2588 /* ??? + date
2589 * 'right' must be one of us, or we wouldn't have been called
2590 */
2591 if (PyDelta_Check(left))
2592 /* delta + date */
2593 return add_date_timedelta((PyDateTime_Date *) right,
2594 (PyDateTime_Delta *) left,
2595 0);
2596 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002597 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002598}
2599
2600static PyObject *
2601date_subtract(PyObject *left, PyObject *right)
2602{
Brian Curtindfc80e32011-08-10 20:28:54 -05002603 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2604 Py_RETURN_NOTIMPLEMENTED;
2605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606 if (PyDate_Check(left)) {
2607 if (PyDate_Check(right)) {
2608 /* date - date */
2609 int left_ord = ymd_to_ord(GET_YEAR(left),
2610 GET_MONTH(left),
2611 GET_DAY(left));
2612 int right_ord = ymd_to_ord(GET_YEAR(right),
2613 GET_MONTH(right),
2614 GET_DAY(right));
2615 return new_delta(left_ord - right_ord, 0, 0, 0);
2616 }
2617 if (PyDelta_Check(right)) {
2618 /* date - delta */
2619 return add_date_timedelta((PyDateTime_Date *) left,
2620 (PyDateTime_Delta *) right,
2621 1);
2622 }
2623 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002624 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002625}
2626
2627
2628/* Various ways to turn a date into a string. */
2629
2630static PyObject *
2631date_repr(PyDateTime_Date *self)
2632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2634 Py_TYPE(self)->tp_name,
2635 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002636}
2637
2638static PyObject *
2639date_isoformat(PyDateTime_Date *self)
2640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 return PyUnicode_FromFormat("%04d-%02d-%02d",
2642 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002643}
2644
Tim Peterse2df5ff2003-05-02 18:39:55 +00002645/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002646static PyObject *
2647date_str(PyDateTime_Date *self)
2648{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002649 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002650}
2651
2652
2653static PyObject *
2654date_ctime(PyDateTime_Date *self)
2655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002656 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002657}
2658
2659static PyObject *
2660date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 /* This method can be inherited, and needs to call the
2663 * timetuple() method appropriate to self's class.
2664 */
2665 PyObject *result;
2666 PyObject *tuple;
2667 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002668 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002669 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2672 &format))
2673 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002674
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002675 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002676 if (tuple == NULL)
2677 return NULL;
2678 result = wrap_strftime((PyObject *)self, format, tuple,
2679 (PyObject *)self);
2680 Py_DECREF(tuple);
2681 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002682}
2683
Eric Smith1ba31142007-09-11 18:06:02 +00002684static PyObject *
2685date_format(PyDateTime_Date *self, PyObject *args)
2686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002687 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002689 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2690 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002692 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002693 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002694 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002695
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002696 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002697}
2698
Tim Peters2a799bf2002-12-16 20:18:38 +00002699/* ISO methods. */
2700
2701static PyObject *
2702date_isoweekday(PyDateTime_Date *self)
2703{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002704 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002706 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002707}
2708
2709static PyObject *
2710date_isocalendar(PyDateTime_Date *self)
2711{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002712 int year = GET_YEAR(self);
2713 int week1_monday = iso_week1_monday(year);
2714 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2715 int week;
2716 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 week = divmod(today - week1_monday, 7, &day);
2719 if (week < 0) {
2720 --year;
2721 week1_monday = iso_week1_monday(year);
2722 week = divmod(today - week1_monday, 7, &day);
2723 }
2724 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2725 ++year;
2726 week = 0;
2727 }
2728 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002729}
2730
2731/* Miscellaneous methods. */
2732
Tim Peters2a799bf2002-12-16 20:18:38 +00002733static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002734date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002736 if (PyDate_Check(other)) {
2737 int diff = memcmp(((PyDateTime_Date *)self)->data,
2738 ((PyDateTime_Date *)other)->data,
2739 _PyDateTime_DATE_DATASIZE);
2740 return diff_to_bool(diff, op);
2741 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002742 else
2743 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002744}
2745
2746static PyObject *
2747date_timetuple(PyDateTime_Date *self)
2748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002749 return build_struct_time(GET_YEAR(self),
2750 GET_MONTH(self),
2751 GET_DAY(self),
2752 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002753}
2754
Tim Peters12bf3392002-12-24 05:41:27 +00002755static PyObject *
2756date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002758 PyObject *clone;
2759 PyObject *tuple;
2760 int year = GET_YEAR(self);
2761 int month = GET_MONTH(self);
2762 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002764 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2765 &year, &month, &day))
2766 return NULL;
2767 tuple = Py_BuildValue("iii", year, month, day);
2768 if (tuple == NULL)
2769 return NULL;
2770 clone = date_new(Py_TYPE(self), tuple, NULL);
2771 Py_DECREF(tuple);
2772 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002773}
2774
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002775static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002776generic_hash(unsigned char *data, int len)
2777{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002778 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002779}
2780
2781
2782static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002783
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002784static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002785date_hash(PyDateTime_Date *self)
2786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002787 if (self->hashcode == -1)
2788 self->hashcode = generic_hash(
2789 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002791 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002792}
2793
2794static PyObject *
2795date_toordinal(PyDateTime_Date *self)
2796{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002797 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2798 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002799}
2800
2801static PyObject *
2802date_weekday(PyDateTime_Date *self)
2803{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002804 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002806 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002807}
2808
Tim Peters371935f2003-02-01 01:52:50 +00002809/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002810
Tim Petersb57f8f02003-02-01 02:54:15 +00002811/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002812static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002813date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 PyObject* field;
2816 field = PyBytes_FromStringAndSize((char*)self->data,
2817 _PyDateTime_DATE_DATASIZE);
2818 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002819}
2820
2821static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002822date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002824 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002825}
2826
2827static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002829 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2832 METH_CLASS,
2833 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2834 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2837 METH_CLASS,
2838 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2839 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002841 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2842 PyDoc_STR("Current date or datetime: same as "
2843 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2848 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2851 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2854 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2857 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002859 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2860 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2861 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002863 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2864 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002866 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2867 PyDoc_STR("Return the day of the week represented by the date.\n"
2868 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002870 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2871 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2872 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002874 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2875 PyDoc_STR("Return the day of the week represented by the date.\n"
2876 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2879 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002881 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2882 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002885};
2886
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002887static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002888PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002889
2890static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002891 date_add, /* nb_add */
2892 date_subtract, /* nb_subtract */
2893 0, /* nb_multiply */
2894 0, /* nb_remainder */
2895 0, /* nb_divmod */
2896 0, /* nb_power */
2897 0, /* nb_negative */
2898 0, /* nb_positive */
2899 0, /* nb_absolute */
2900 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002901};
2902
2903static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002904 PyVarObject_HEAD_INIT(NULL, 0)
2905 "datetime.date", /* tp_name */
2906 sizeof(PyDateTime_Date), /* tp_basicsize */
2907 0, /* tp_itemsize */
2908 0, /* tp_dealloc */
2909 0, /* tp_print */
2910 0, /* tp_getattr */
2911 0, /* tp_setattr */
2912 0, /* tp_reserved */
2913 (reprfunc)date_repr, /* tp_repr */
2914 &date_as_number, /* tp_as_number */
2915 0, /* tp_as_sequence */
2916 0, /* tp_as_mapping */
2917 (hashfunc)date_hash, /* tp_hash */
2918 0, /* tp_call */
2919 (reprfunc)date_str, /* tp_str */
2920 PyObject_GenericGetAttr, /* tp_getattro */
2921 0, /* tp_setattro */
2922 0, /* tp_as_buffer */
2923 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2924 date_doc, /* tp_doc */
2925 0, /* tp_traverse */
2926 0, /* tp_clear */
2927 date_richcompare, /* tp_richcompare */
2928 0, /* tp_weaklistoffset */
2929 0, /* tp_iter */
2930 0, /* tp_iternext */
2931 date_methods, /* tp_methods */
2932 0, /* tp_members */
2933 date_getset, /* tp_getset */
2934 0, /* tp_base */
2935 0, /* tp_dict */
2936 0, /* tp_descr_get */
2937 0, /* tp_descr_set */
2938 0, /* tp_dictoffset */
2939 0, /* tp_init */
2940 0, /* tp_alloc */
2941 date_new, /* tp_new */
2942 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002943};
2944
2945/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002946 * PyDateTime_TZInfo implementation.
2947 */
2948
2949/* This is a pure abstract base class, so doesn't do anything beyond
2950 * raising NotImplemented exceptions. Real tzinfo classes need
2951 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002952 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002953 * be subclasses of this tzinfo class, which is easy and quick to check).
2954 *
2955 * Note: For reasons having to do with pickling of subclasses, we have
2956 * to allow tzinfo objects to be instantiated. This wasn't an issue
2957 * in the Python implementation (__init__() could raise NotImplementedError
2958 * there without ill effect), but doing so in the C implementation hit a
2959 * brick wall.
2960 */
2961
2962static PyObject *
2963tzinfo_nogo(const char* methodname)
2964{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002965 PyErr_Format(PyExc_NotImplementedError,
2966 "a tzinfo subclass must implement %s()",
2967 methodname);
2968 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002969}
2970
2971/* Methods. A subclass must implement these. */
2972
Tim Peters52dcce22003-01-23 16:36:11 +00002973static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002974tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002976 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002977}
2978
Tim Peters52dcce22003-01-23 16:36:11 +00002979static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002980tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002982 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002983}
2984
Tim Peters52dcce22003-01-23 16:36:11 +00002985static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002986tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002988 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002989}
2990
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002991
2992static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2993 PyDateTime_Delta *delta,
2994 int factor);
2995static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2996static PyObject *datetime_dst(PyObject *self, PyObject *);
2997
Tim Peters52dcce22003-01-23 16:36:11 +00002998static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002999tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003000{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003001 PyObject *result = NULL;
3002 PyObject *off = NULL, *dst = NULL;
3003 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003004
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003005 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003006 PyErr_SetString(PyExc_TypeError,
3007 "fromutc: argument must be a datetime");
3008 return NULL;
3009 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003010 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003011 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3012 "is not self");
3013 return NULL;
3014 }
Tim Peters52dcce22003-01-23 16:36:11 +00003015
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003016 off = datetime_utcoffset(dt, NULL);
3017 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003018 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003019 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003020 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3021 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003022 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003023 }
Tim Peters52dcce22003-01-23 16:36:11 +00003024
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003025 dst = datetime_dst(dt, NULL);
3026 if (dst == NULL)
3027 goto Fail;
3028 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003029 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3030 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003031 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003032 }
Tim Peters52dcce22003-01-23 16:36:11 +00003033
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003034 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3035 if (delta == NULL)
3036 goto Fail;
3037 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003039 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003040
3041 Py_DECREF(dst);
3042 dst = call_dst(GET_DT_TZINFO(dt), result);
3043 if (dst == NULL)
3044 goto Fail;
3045 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003046 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003047 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003048 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003049 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003050 if (result == NULL)
3051 goto Fail;
3052 }
3053 Py_DECREF(delta);
3054 Py_DECREF(dst);
3055 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003056 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003057
3058Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003059 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3060 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003063Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003064 Py_XDECREF(off);
3065 Py_XDECREF(dst);
3066 Py_XDECREF(delta);
3067 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003068 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003069}
3070
Tim Peters2a799bf2002-12-16 20:18:38 +00003071/*
3072 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003073 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003074 */
3075
Guido van Rossum177e41a2003-01-30 22:06:23 +00003076static PyObject *
3077tzinfo_reduce(PyObject *self)
3078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003079 PyObject *args, *state, *tmp;
3080 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003081 _Py_IDENTIFIER(__getinitargs__);
3082 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003084 tmp = PyTuple_New(0);
3085 if (tmp == NULL)
3086 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003087
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003088 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003089 if (getinitargs != NULL) {
3090 args = PyObject_CallObject(getinitargs, tmp);
3091 Py_DECREF(getinitargs);
3092 if (args == NULL) {
3093 Py_DECREF(tmp);
3094 return NULL;
3095 }
3096 }
3097 else {
3098 PyErr_Clear();
3099 args = tmp;
3100 Py_INCREF(args);
3101 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003102
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003103 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003104 if (getstate != NULL) {
3105 state = PyObject_CallObject(getstate, tmp);
3106 Py_DECREF(getstate);
3107 if (state == NULL) {
3108 Py_DECREF(args);
3109 Py_DECREF(tmp);
3110 return NULL;
3111 }
3112 }
3113 else {
3114 PyObject **dictptr;
3115 PyErr_Clear();
3116 state = Py_None;
3117 dictptr = _PyObject_GetDictPtr(self);
3118 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3119 state = *dictptr;
3120 Py_INCREF(state);
3121 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003123 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 if (state == Py_None) {
3126 Py_DECREF(state);
3127 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3128 }
3129 else
3130 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003131}
Tim Peters2a799bf2002-12-16 20:18:38 +00003132
3133static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003135 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3136 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003138 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003139 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3140 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003142 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3143 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003145 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003146 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003148 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3149 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003151 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003152};
3153
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003154static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003155PyDoc_STR("Abstract base class for time zone info objects.");
3156
Neal Norwitz227b5332006-03-22 09:28:35 +00003157static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003158 PyVarObject_HEAD_INIT(NULL, 0)
3159 "datetime.tzinfo", /* tp_name */
3160 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3161 0, /* tp_itemsize */
3162 0, /* tp_dealloc */
3163 0, /* tp_print */
3164 0, /* tp_getattr */
3165 0, /* tp_setattr */
3166 0, /* tp_reserved */
3167 0, /* tp_repr */
3168 0, /* tp_as_number */
3169 0, /* tp_as_sequence */
3170 0, /* tp_as_mapping */
3171 0, /* tp_hash */
3172 0, /* tp_call */
3173 0, /* tp_str */
3174 PyObject_GenericGetAttr, /* tp_getattro */
3175 0, /* tp_setattro */
3176 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003177 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003178 tzinfo_doc, /* tp_doc */
3179 0, /* tp_traverse */
3180 0, /* tp_clear */
3181 0, /* tp_richcompare */
3182 0, /* tp_weaklistoffset */
3183 0, /* tp_iter */
3184 0, /* tp_iternext */
3185 tzinfo_methods, /* tp_methods */
3186 0, /* tp_members */
3187 0, /* tp_getset */
3188 0, /* tp_base */
3189 0, /* tp_dict */
3190 0, /* tp_descr_get */
3191 0, /* tp_descr_set */
3192 0, /* tp_dictoffset */
3193 0, /* tp_init */
3194 0, /* tp_alloc */
3195 PyType_GenericNew, /* tp_new */
3196 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003197};
3198
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003199static char *timezone_kws[] = {"offset", "name", NULL};
3200
3201static PyObject *
3202timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3203{
3204 PyObject *offset;
3205 PyObject *name = NULL;
3206 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3207 &PyDateTime_DeltaType, &offset,
3208 &PyUnicode_Type, &name))
3209 return new_timezone(offset, name);
3210
3211 return NULL;
3212}
3213
3214static void
3215timezone_dealloc(PyDateTime_TimeZone *self)
3216{
3217 Py_CLEAR(self->offset);
3218 Py_CLEAR(self->name);
3219 Py_TYPE(self)->tp_free((PyObject *)self);
3220}
3221
3222static PyObject *
3223timezone_richcompare(PyDateTime_TimeZone *self,
3224 PyDateTime_TimeZone *other, int op)
3225{
Brian Curtindfc80e32011-08-10 20:28:54 -05003226 if (op != Py_EQ && op != Py_NE)
3227 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003228 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003229 if (op == Py_EQ)
3230 Py_RETURN_FALSE;
3231 else
3232 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003233 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003234 return delta_richcompare(self->offset, other->offset, op);
3235}
3236
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003237static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003238timezone_hash(PyDateTime_TimeZone *self)
3239{
3240 return delta_hash((PyDateTime_Delta *)self->offset);
3241}
3242
3243/* Check argument type passed to tzname, utcoffset, or dst methods.
3244 Returns 0 for good argument. Returns -1 and sets exception info
3245 otherwise.
3246 */
3247static int
3248_timezone_check_argument(PyObject *dt, const char *meth)
3249{
3250 if (dt == Py_None || PyDateTime_Check(dt))
3251 return 0;
3252 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3253 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3254 return -1;
3255}
3256
3257static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003258timezone_repr(PyDateTime_TimeZone *self)
3259{
3260 /* Note that although timezone is not subclassable, it is convenient
3261 to use Py_TYPE(self)->tp_name here. */
3262 const char *type_name = Py_TYPE(self)->tp_name;
3263
3264 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3265 return PyUnicode_FromFormat("%s.utc", type_name);
3266
3267 if (self->name == NULL)
3268 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3269
3270 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3271 self->name);
3272}
3273
3274
3275static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003276timezone_str(PyDateTime_TimeZone *self)
3277{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003278 int hours, minutes, seconds;
3279 PyObject *offset;
3280 char sign;
3281
3282 if (self->name != NULL) {
3283 Py_INCREF(self->name);
3284 return self->name;
3285 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003286 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003287 (GET_TD_DAYS(self->offset) == 0 &&
3288 GET_TD_SECONDS(self->offset) == 0 &&
3289 GET_TD_MICROSECONDS(self->offset) == 0))
3290 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003291 /* Offset is normalized, so it is negative if days < 0 */
3292 if (GET_TD_DAYS(self->offset) < 0) {
3293 sign = '-';
3294 offset = delta_negative((PyDateTime_Delta *)self->offset);
3295 if (offset == NULL)
3296 return NULL;
3297 }
3298 else {
3299 sign = '+';
3300 offset = self->offset;
3301 Py_INCREF(offset);
3302 }
3303 /* Offset is not negative here. */
3304 seconds = GET_TD_SECONDS(offset);
3305 Py_DECREF(offset);
3306 minutes = divmod(seconds, 60, &seconds);
3307 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003308 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003309 assert(seconds == 0);
3310 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003311}
3312
3313static PyObject *
3314timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3315{
3316 if (_timezone_check_argument(dt, "tzname") == -1)
3317 return NULL;
3318
3319 return timezone_str(self);
3320}
3321
3322static PyObject *
3323timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3324{
3325 if (_timezone_check_argument(dt, "utcoffset") == -1)
3326 return NULL;
3327
3328 Py_INCREF(self->offset);
3329 return self->offset;
3330}
3331
3332static PyObject *
3333timezone_dst(PyObject *self, PyObject *dt)
3334{
3335 if (_timezone_check_argument(dt, "dst") == -1)
3336 return NULL;
3337
3338 Py_RETURN_NONE;
3339}
3340
3341static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003342timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3343{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003344 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003345 PyErr_SetString(PyExc_TypeError,
3346 "fromutc: argument must be a datetime");
3347 return NULL;
3348 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003349 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003350 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3351 "is not self");
3352 return NULL;
3353 }
3354
3355 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3356}
3357
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003358static PyObject *
3359timezone_getinitargs(PyDateTime_TimeZone *self)
3360{
3361 if (self->name == NULL)
3362 return Py_BuildValue("(O)", self->offset);
3363 return Py_BuildValue("(OO)", self->offset, self->name);
3364}
3365
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003366static PyMethodDef timezone_methods[] = {
3367 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3368 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003369 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003370
3371 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003372 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003373
3374 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003375 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003376
3377 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3378 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3379
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003380 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3381 PyDoc_STR("pickle support")},
3382
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003383 {NULL, NULL}
3384};
3385
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003386static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003387PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3388
3389static PyTypeObject PyDateTime_TimeZoneType = {
3390 PyVarObject_HEAD_INIT(NULL, 0)
3391 "datetime.timezone", /* tp_name */
3392 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3393 0, /* tp_itemsize */
3394 (destructor)timezone_dealloc, /* tp_dealloc */
3395 0, /* tp_print */
3396 0, /* tp_getattr */
3397 0, /* tp_setattr */
3398 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003399 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003400 0, /* tp_as_number */
3401 0, /* tp_as_sequence */
3402 0, /* tp_as_mapping */
3403 (hashfunc)timezone_hash, /* tp_hash */
3404 0, /* tp_call */
3405 (reprfunc)timezone_str, /* tp_str */
3406 0, /* tp_getattro */
3407 0, /* tp_setattro */
3408 0, /* tp_as_buffer */
3409 Py_TPFLAGS_DEFAULT, /* tp_flags */
3410 timezone_doc, /* tp_doc */
3411 0, /* tp_traverse */
3412 0, /* tp_clear */
3413 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3414 0, /* tp_weaklistoffset */
3415 0, /* tp_iter */
3416 0, /* tp_iternext */
3417 timezone_methods, /* tp_methods */
3418 0, /* tp_members */
3419 0, /* tp_getset */
3420 &PyDateTime_TZInfoType, /* tp_base */
3421 0, /* tp_dict */
3422 0, /* tp_descr_get */
3423 0, /* tp_descr_set */
3424 0, /* tp_dictoffset */
3425 0, /* tp_init */
3426 0, /* tp_alloc */
3427 timezone_new, /* tp_new */
3428};
3429
Tim Peters2a799bf2002-12-16 20:18:38 +00003430/*
Tim Peters37f39822003-01-10 03:49:02 +00003431 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003432 */
3433
Tim Peters37f39822003-01-10 03:49:02 +00003434/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003435 */
3436
3437static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003438time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003440 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003441}
3442
Tim Peters37f39822003-01-10 03:49:02 +00003443static PyObject *
3444time_minute(PyDateTime_Time *self, void *unused)
3445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003446 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003447}
3448
3449/* The name time_second conflicted with some platform header file. */
3450static PyObject *
3451py_time_second(PyDateTime_Time *self, void *unused)
3452{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003453 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003454}
3455
3456static PyObject *
3457time_microsecond(PyDateTime_Time *self, void *unused)
3458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003459 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003460}
3461
3462static PyObject *
3463time_tzinfo(PyDateTime_Time *self, void *unused)
3464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003465 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3466 Py_INCREF(result);
3467 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003468}
3469
3470static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003471 {"hour", (getter)time_hour},
3472 {"minute", (getter)time_minute},
3473 {"second", (getter)py_time_second},
3474 {"microsecond", (getter)time_microsecond},
3475 {"tzinfo", (getter)time_tzinfo},
3476 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003477};
3478
3479/*
3480 * Constructors.
3481 */
3482
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003483static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003484 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003485
Tim Peters2a799bf2002-12-16 20:18:38 +00003486static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003487time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 PyObject *self = NULL;
3490 PyObject *state;
3491 int hour = 0;
3492 int minute = 0;
3493 int second = 0;
3494 int usecond = 0;
3495 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003497 /* Check for invocation from pickle with __getstate__ state */
3498 if (PyTuple_GET_SIZE(args) >= 1 &&
3499 PyTuple_GET_SIZE(args) <= 2 &&
3500 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3501 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3502 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3503 {
3504 PyDateTime_Time *me;
3505 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003507 if (PyTuple_GET_SIZE(args) == 2) {
3508 tzinfo = PyTuple_GET_ITEM(args, 1);
3509 if (check_tzinfo_subclass(tzinfo) < 0) {
3510 PyErr_SetString(PyExc_TypeError, "bad "
3511 "tzinfo state arg");
3512 return NULL;
3513 }
3514 }
3515 aware = (char)(tzinfo != Py_None);
3516 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3517 if (me != NULL) {
3518 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003520 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3521 me->hashcode = -1;
3522 me->hastzinfo = aware;
3523 if (aware) {
3524 Py_INCREF(tzinfo);
3525 me->tzinfo = tzinfo;
3526 }
3527 }
3528 return (PyObject *)me;
3529 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003531 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3532 &hour, &minute, &second, &usecond,
3533 &tzinfo)) {
3534 if (check_time_args(hour, minute, second, usecond) < 0)
3535 return NULL;
3536 if (check_tzinfo_subclass(tzinfo) < 0)
3537 return NULL;
3538 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3539 type);
3540 }
3541 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003542}
3543
3544/*
3545 * Destructor.
3546 */
3547
3548static void
Tim Peters37f39822003-01-10 03:49:02 +00003549time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003550{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003551 if (HASTZINFO(self)) {
3552 Py_XDECREF(self->tzinfo);
3553 }
3554 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003555}
3556
3557/*
Tim Peters855fe882002-12-22 03:43:39 +00003558 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003559 */
3560
Tim Peters2a799bf2002-12-16 20:18:38 +00003561/* These are all METH_NOARGS, so don't need to check the arglist. */
3562static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003563time_utcoffset(PyObject *self, PyObject *unused) {
3564 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003565}
3566
3567static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003568time_dst(PyObject *self, PyObject *unused) {
3569 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003570}
3571
3572static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003573time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003574 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003575}
3576
3577/*
Tim Peters37f39822003-01-10 03:49:02 +00003578 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003579 */
3580
3581static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003582time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003583{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003584 const char *type_name = Py_TYPE(self)->tp_name;
3585 int h = TIME_GET_HOUR(self);
3586 int m = TIME_GET_MINUTE(self);
3587 int s = TIME_GET_SECOND(self);
3588 int us = TIME_GET_MICROSECOND(self);
3589 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003591 if (us)
3592 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3593 type_name, h, m, s, us);
3594 else if (s)
3595 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3596 type_name, h, m, s);
3597 else
3598 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3599 if (result != NULL && HASTZINFO(self))
3600 result = append_keyword_tzinfo(result, self->tzinfo);
3601 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003602}
3603
Tim Peters37f39822003-01-10 03:49:02 +00003604static PyObject *
3605time_str(PyDateTime_Time *self)
3606{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003607 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003608}
Tim Peters2a799bf2002-12-16 20:18:38 +00003609
3610static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003611time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003613 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003614 char *timespec = NULL;
3615 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003616 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003617 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003618 static char *specs[][2] = {
3619 {"hours", "%02d"},
3620 {"minutes", "%02d:%02d"},
3621 {"seconds", "%02d:%02d:%02d"},
3622 {"milliseconds", "%02d:%02d:%02d.%03d"},
3623 {"microseconds", "%02d:%02d:%02d.%06d"},
3624 };
3625 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003626
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003627 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3628 return NULL;
3629
3630 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3631 if (us == 0) {
3632 /* seconds */
3633 given_spec = 2;
3634 }
3635 else {
3636 /* microseconds */
3637 given_spec = 4;
3638 }
3639 }
3640 else {
3641 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3642 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3643 if (given_spec == 3) {
3644 /* milliseconds */
3645 us = us / 1000;
3646 }
3647 break;
3648 }
3649 }
3650 }
3651
3652 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3653 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3654 return NULL;
3655 }
3656 else {
3657 result = PyUnicode_FromFormat(specs[given_spec][1],
3658 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3659 TIME_GET_SECOND(self), us);
3660 }
Tim Peters37f39822003-01-10 03:49:02 +00003661
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003662 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003663 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003665 /* We need to append the UTC offset. */
3666 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3667 Py_None) < 0) {
3668 Py_DECREF(result);
3669 return NULL;
3670 }
3671 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3672 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003673}
3674
Tim Peters37f39822003-01-10 03:49:02 +00003675static PyObject *
3676time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003678 PyObject *result;
3679 PyObject *tuple;
3680 PyObject *format;
3681 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003683 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3684 &format))
3685 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003687 /* Python's strftime does insane things with the year part of the
3688 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003689 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003690 */
3691 tuple = Py_BuildValue("iiiiiiiii",
3692 1900, 1, 1, /* year, month, day */
3693 TIME_GET_HOUR(self),
3694 TIME_GET_MINUTE(self),
3695 TIME_GET_SECOND(self),
3696 0, 1, -1); /* weekday, daynum, dst */
3697 if (tuple == NULL)
3698 return NULL;
3699 assert(PyTuple_Size(tuple) == 9);
3700 result = wrap_strftime((PyObject *)self, format, tuple,
3701 Py_None);
3702 Py_DECREF(tuple);
3703 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003704}
Tim Peters2a799bf2002-12-16 20:18:38 +00003705
3706/*
3707 * Miscellaneous methods.
3708 */
3709
Tim Peters37f39822003-01-10 03:49:02 +00003710static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003711time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003712{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003713 PyObject *result = NULL;
3714 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003715 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003716
Brian Curtindfc80e32011-08-10 20:28:54 -05003717 if (! PyTime_Check(other))
3718 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003719
3720 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003721 diff = memcmp(((PyDateTime_Time *)self)->data,
3722 ((PyDateTime_Time *)other)->data,
3723 _PyDateTime_TIME_DATASIZE);
3724 return diff_to_bool(diff, op);
3725 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003726 offset1 = time_utcoffset(self, NULL);
3727 if (offset1 == NULL)
3728 return NULL;
3729 offset2 = time_utcoffset(other, NULL);
3730 if (offset2 == NULL)
3731 goto done;
3732 /* If they're both naive, or both aware and have the same offsets,
3733 * we get off cheap. Note that if they're both naive, offset1 ==
3734 * offset2 == Py_None at this point.
3735 */
3736 if ((offset1 == offset2) ||
3737 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3738 delta_cmp(offset1, offset2) == 0)) {
3739 diff = memcmp(((PyDateTime_Time *)self)->data,
3740 ((PyDateTime_Time *)other)->data,
3741 _PyDateTime_TIME_DATASIZE);
3742 result = diff_to_bool(diff, op);
3743 }
3744 /* The hard case: both aware with different UTC offsets */
3745 else if (offset1 != Py_None && offset2 != Py_None) {
3746 int offsecs1, offsecs2;
3747 assert(offset1 != offset2); /* else last "if" handled it */
3748 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3749 TIME_GET_MINUTE(self) * 60 +
3750 TIME_GET_SECOND(self) -
3751 GET_TD_DAYS(offset1) * 86400 -
3752 GET_TD_SECONDS(offset1);
3753 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3754 TIME_GET_MINUTE(other) * 60 +
3755 TIME_GET_SECOND(other) -
3756 GET_TD_DAYS(offset2) * 86400 -
3757 GET_TD_SECONDS(offset2);
3758 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003759 if (diff == 0)
3760 diff = TIME_GET_MICROSECOND(self) -
3761 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003762 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003763 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003764 else if (op == Py_EQ) {
3765 result = Py_False;
3766 Py_INCREF(result);
3767 }
3768 else if (op == Py_NE) {
3769 result = Py_True;
3770 Py_INCREF(result);
3771 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003772 else {
3773 PyErr_SetString(PyExc_TypeError,
3774 "can't compare offset-naive and "
3775 "offset-aware times");
3776 }
3777 done:
3778 Py_DECREF(offset1);
3779 Py_XDECREF(offset2);
3780 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003781}
3782
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003783static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003784time_hash(PyDateTime_Time *self)
3785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003786 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003787 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003788
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003789 offset = time_utcoffset((PyObject *)self, NULL);
3790
3791 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003792 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003794 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003795 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003796 self->hashcode = generic_hash(
3797 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003798 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003799 PyObject *temp1, *temp2;
3800 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003801 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003802 seconds = TIME_GET_HOUR(self) * 3600 +
3803 TIME_GET_MINUTE(self) * 60 +
3804 TIME_GET_SECOND(self);
3805 microseconds = TIME_GET_MICROSECOND(self);
3806 temp1 = new_delta(0, seconds, microseconds, 1);
3807 if (temp1 == NULL) {
3808 Py_DECREF(offset);
3809 return -1;
3810 }
3811 temp2 = delta_subtract(temp1, offset);
3812 Py_DECREF(temp1);
3813 if (temp2 == NULL) {
3814 Py_DECREF(offset);
3815 return -1;
3816 }
3817 self->hashcode = PyObject_Hash(temp2);
3818 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003819 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003820 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003821 }
3822 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003823}
Tim Peters2a799bf2002-12-16 20:18:38 +00003824
Tim Peters12bf3392002-12-24 05:41:27 +00003825static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003826time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003827{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003828 PyObject *clone;
3829 PyObject *tuple;
3830 int hh = TIME_GET_HOUR(self);
3831 int mm = TIME_GET_MINUTE(self);
3832 int ss = TIME_GET_SECOND(self);
3833 int us = TIME_GET_MICROSECOND(self);
3834 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003836 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3837 time_kws,
3838 &hh, &mm, &ss, &us, &tzinfo))
3839 return NULL;
3840 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3841 if (tuple == NULL)
3842 return NULL;
3843 clone = time_new(Py_TYPE(self), tuple, NULL);
3844 Py_DECREF(tuple);
3845 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003846}
3847
Tim Peters371935f2003-02-01 01:52:50 +00003848/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003849
Tim Peters33e0f382003-01-10 02:05:14 +00003850/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003851 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3852 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003853 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003854 */
3855static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003856time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 PyObject *basestate;
3859 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003861 basestate = PyBytes_FromStringAndSize((char *)self->data,
3862 _PyDateTime_TIME_DATASIZE);
3863 if (basestate != NULL) {
3864 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3865 result = PyTuple_Pack(1, basestate);
3866 else
3867 result = PyTuple_Pack(2, basestate, self->tzinfo);
3868 Py_DECREF(basestate);
3869 }
3870 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003871}
3872
3873static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003874time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003876 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003877}
3878
Tim Peters37f39822003-01-10 03:49:02 +00003879static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003880
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003881 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
3882 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
3883 "[+HH:MM].\n\n"
3884 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003886 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3887 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003889 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3890 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003892 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3893 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003895 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3896 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003898 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3899 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003901 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3902 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003904 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3905 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003907 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003908};
3909
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003910static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003911PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3912\n\
3913All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03003914a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003915
Neal Norwitz227b5332006-03-22 09:28:35 +00003916static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003917 PyVarObject_HEAD_INIT(NULL, 0)
3918 "datetime.time", /* tp_name */
3919 sizeof(PyDateTime_Time), /* tp_basicsize */
3920 0, /* tp_itemsize */
3921 (destructor)time_dealloc, /* tp_dealloc */
3922 0, /* tp_print */
3923 0, /* tp_getattr */
3924 0, /* tp_setattr */
3925 0, /* tp_reserved */
3926 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05003927 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003928 0, /* tp_as_sequence */
3929 0, /* tp_as_mapping */
3930 (hashfunc)time_hash, /* tp_hash */
3931 0, /* tp_call */
3932 (reprfunc)time_str, /* tp_str */
3933 PyObject_GenericGetAttr, /* tp_getattro */
3934 0, /* tp_setattro */
3935 0, /* tp_as_buffer */
3936 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3937 time_doc, /* tp_doc */
3938 0, /* tp_traverse */
3939 0, /* tp_clear */
3940 time_richcompare, /* tp_richcompare */
3941 0, /* tp_weaklistoffset */
3942 0, /* tp_iter */
3943 0, /* tp_iternext */
3944 time_methods, /* tp_methods */
3945 0, /* tp_members */
3946 time_getset, /* tp_getset */
3947 0, /* tp_base */
3948 0, /* tp_dict */
3949 0, /* tp_descr_get */
3950 0, /* tp_descr_set */
3951 0, /* tp_dictoffset */
3952 0, /* tp_init */
3953 time_alloc, /* tp_alloc */
3954 time_new, /* tp_new */
3955 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003956};
3957
3958/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003959 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003960 */
3961
Tim Petersa9bc1682003-01-11 03:39:11 +00003962/* Accessor properties. Properties for day, month, and year are inherited
3963 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003964 */
3965
3966static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003967datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003969 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003970}
3971
Tim Petersa9bc1682003-01-11 03:39:11 +00003972static PyObject *
3973datetime_minute(PyDateTime_DateTime *self, void *unused)
3974{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003975 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003976}
3977
3978static PyObject *
3979datetime_second(PyDateTime_DateTime *self, void *unused)
3980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003981 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003982}
3983
3984static PyObject *
3985datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003987 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003988}
3989
3990static PyObject *
3991datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003993 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3994 Py_INCREF(result);
3995 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003996}
3997
3998static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003999 {"hour", (getter)datetime_hour},
4000 {"minute", (getter)datetime_minute},
4001 {"second", (getter)datetime_second},
4002 {"microsecond", (getter)datetime_microsecond},
4003 {"tzinfo", (getter)datetime_tzinfo},
4004 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004005};
4006
4007/*
4008 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004009 */
4010
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004011static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004012 "year", "month", "day", "hour", "minute", "second",
4013 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004014};
4015
Tim Peters2a799bf2002-12-16 20:18:38 +00004016static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004017datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004018{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004019 PyObject *self = NULL;
4020 PyObject *state;
4021 int year;
4022 int month;
4023 int day;
4024 int hour = 0;
4025 int minute = 0;
4026 int second = 0;
4027 int usecond = 0;
4028 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004030 /* Check for invocation from pickle with __getstate__ state */
4031 if (PyTuple_GET_SIZE(args) >= 1 &&
4032 PyTuple_GET_SIZE(args) <= 2 &&
4033 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4034 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4035 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4036 {
4037 PyDateTime_DateTime *me;
4038 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004040 if (PyTuple_GET_SIZE(args) == 2) {
4041 tzinfo = PyTuple_GET_ITEM(args, 1);
4042 if (check_tzinfo_subclass(tzinfo) < 0) {
4043 PyErr_SetString(PyExc_TypeError, "bad "
4044 "tzinfo state arg");
4045 return NULL;
4046 }
4047 }
4048 aware = (char)(tzinfo != Py_None);
4049 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4050 if (me != NULL) {
4051 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004053 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4054 me->hashcode = -1;
4055 me->hastzinfo = aware;
4056 if (aware) {
4057 Py_INCREF(tzinfo);
4058 me->tzinfo = tzinfo;
4059 }
4060 }
4061 return (PyObject *)me;
4062 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004064 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4065 &year, &month, &day, &hour, &minute,
4066 &second, &usecond, &tzinfo)) {
4067 if (check_date_args(year, month, day) < 0)
4068 return NULL;
4069 if (check_time_args(hour, minute, second, usecond) < 0)
4070 return NULL;
4071 if (check_tzinfo_subclass(tzinfo) < 0)
4072 return NULL;
4073 self = new_datetime_ex(year, month, day,
4074 hour, minute, second, usecond,
4075 tzinfo, type);
4076 }
4077 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004078}
4079
Tim Petersa9bc1682003-01-11 03:39:11 +00004080/* TM_FUNC is the shared type of localtime() and gmtime(). */
4081typedef struct tm *(*TM_FUNC)(const time_t *timer);
4082
4083/* Internal helper.
4084 * Build datetime from a time_t and a distinct count of microseconds.
4085 * Pass localtime or gmtime for f, to control the interpretation of timet.
4086 */
4087static PyObject *
4088datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004089 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004090{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004091 struct tm *tm;
Tim Petersa9bc1682003-01-11 03:39:11 +00004092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004093 tm = f(&timet);
Victor Stinner21f58932012-03-14 00:15:40 +01004094 if (tm == NULL) {
4095#ifdef EINVAL
4096 if (errno == 0)
4097 errno = EINVAL;
4098#endif
4099 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004100 }
Victor Stinner21f58932012-03-14 00:15:40 +01004101
4102 /* The platform localtime/gmtime may insert leap seconds,
4103 * indicated by tm->tm_sec > 59. We don't care about them,
4104 * except to the extent that passing them on to the datetime
4105 * constructor would raise ValueError for a reason that
4106 * made no sense to the user.
4107 */
4108 if (tm->tm_sec > 59)
4109 tm->tm_sec = 59;
4110 return PyObject_CallFunction(cls, "iiiiiiiO",
4111 tm->tm_year + 1900,
4112 tm->tm_mon + 1,
4113 tm->tm_mday,
4114 tm->tm_hour,
4115 tm->tm_min,
4116 tm->tm_sec,
4117 us,
4118 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004119}
4120
4121/* Internal helper.
4122 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4123 * to control the interpretation of the timestamp. Since a double doesn't
4124 * have enough bits to cover a datetime's full range of precision, it's
4125 * better to call datetime_from_timet_and_us provided you have a way
4126 * to get that much precision (e.g., C time() isn't good enough).
4127 */
4128static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004129datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004132 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004133 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004134
Victor Stinnere4a994d2015-03-30 01:10:14 +02004135 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004136 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004137 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004138
Victor Stinner21f58932012-03-14 00:15:40 +01004139 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004140}
4141
4142/* Internal helper.
4143 * Build most accurate possible datetime for current time. Pass localtime or
4144 * gmtime for f as appropriate.
4145 */
4146static PyObject *
4147datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4148{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004149 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004150 time_t secs;
4151 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004152
Victor Stinner1e2b6882015-09-18 13:23:02 +02004153 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004154 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004155 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004156
Victor Stinner1e2b6882015-09-18 13:23:02 +02004157 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004158}
4159
Larry Hastings61272b72014-01-07 12:41:53 -08004160/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004161
4162@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004163datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004164
4165 tz: object = None
4166 Timezone object.
4167
4168Returns new datetime object representing current time local to tz.
4169
4170If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004171[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004172
Larry Hastings31826802013-10-19 00:09:25 -07004173static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004174datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004175/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004178
Larry Hastings31826802013-10-19 00:09:25 -07004179 /* Return best possible local time -- this isn't constrained by the
4180 * precision of a timestamp.
4181 */
4182 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004184
Larry Hastings5c661892014-01-24 06:17:25 -08004185 self = datetime_best_possible((PyObject *)type,
Larry Hastings31826802013-10-19 00:09:25 -07004186 tz == Py_None ? localtime : gmtime,
4187 tz);
4188 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004189 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004190 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 }
4192 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004193}
4194
Tim Petersa9bc1682003-01-11 03:39:11 +00004195/* Return best possible UTC time -- this isn't constrained by the
4196 * precision of a timestamp.
4197 */
4198static PyObject *
4199datetime_utcnow(PyObject *cls, PyObject *dummy)
4200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004201 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004202}
4203
Tim Peters2a799bf2002-12-16 20:18:38 +00004204/* Return new local datetime from timestamp (Python timestamp -- a double). */
4205static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004206datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004208 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004209 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004210 PyObject *tzinfo = Py_None;
4211 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004212
Victor Stinner5d272cc2012-03-13 13:35:55 +01004213 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004214 keywords, &timestamp, &tzinfo))
4215 return NULL;
4216 if (check_tzinfo_subclass(tzinfo) < 0)
4217 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004219 self = datetime_from_timestamp(cls,
4220 tzinfo == Py_None ? localtime : gmtime,
4221 timestamp,
4222 tzinfo);
4223 if (self != NULL && tzinfo != Py_None) {
4224 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004225 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 }
4227 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004228}
4229
Tim Petersa9bc1682003-01-11 03:39:11 +00004230/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4231static PyObject *
4232datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4233{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004234 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004235 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004236
Victor Stinner5d272cc2012-03-13 13:35:55 +01004237 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004238 result = datetime_from_timestamp(cls, gmtime, timestamp,
4239 Py_None);
4240 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004241}
4242
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004243/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004244static PyObject *
4245datetime_strptime(PyObject *cls, PyObject *args)
4246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004247 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004248 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004249 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004250
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004251 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004252 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004253
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004254 if (module == NULL) {
4255 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004256 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004257 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004258 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004259 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4260 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004261}
4262
Tim Petersa9bc1682003-01-11 03:39:11 +00004263/* Return new datetime from date/datetime and time arguments. */
4264static PyObject *
4265datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004267 static char *keywords[] = {"date", "time", NULL};
4268 PyObject *date;
4269 PyObject *time;
4270 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004272 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4273 &PyDateTime_DateType, &date,
4274 &PyDateTime_TimeType, &time)) {
4275 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004277 if (HASTZINFO(time))
4278 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4279 result = PyObject_CallFunction(cls, "iiiiiiiO",
4280 GET_YEAR(date),
4281 GET_MONTH(date),
4282 GET_DAY(date),
4283 TIME_GET_HOUR(time),
4284 TIME_GET_MINUTE(time),
4285 TIME_GET_SECOND(time),
4286 TIME_GET_MICROSECOND(time),
4287 tzinfo);
4288 }
4289 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004290}
Tim Peters2a799bf2002-12-16 20:18:38 +00004291
4292/*
4293 * Destructor.
4294 */
4295
4296static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004297datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004298{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004299 if (HASTZINFO(self)) {
4300 Py_XDECREF(self->tzinfo);
4301 }
4302 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004303}
4304
4305/*
4306 * Indirect access to tzinfo methods.
4307 */
4308
Tim Peters2a799bf2002-12-16 20:18:38 +00004309/* These are all METH_NOARGS, so don't need to check the arglist. */
4310static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004311datetime_utcoffset(PyObject *self, PyObject *unused) {
4312 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004313}
4314
4315static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004316datetime_dst(PyObject *self, PyObject *unused) {
4317 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004318}
4319
4320static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004321datetime_tzname(PyObject *self, PyObject *unused) {
4322 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004323}
4324
4325/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004326 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004327 */
4328
Tim Petersa9bc1682003-01-11 03:39:11 +00004329/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4330 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004331 */
4332static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004333add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004334 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004336 /* Note that the C-level additions can't overflow, because of
4337 * invariant bounds on the member values.
4338 */
4339 int year = GET_YEAR(date);
4340 int month = GET_MONTH(date);
4341 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4342 int hour = DATE_GET_HOUR(date);
4343 int minute = DATE_GET_MINUTE(date);
4344 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4345 int microsecond = DATE_GET_MICROSECOND(date) +
4346 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004348 assert(factor == 1 || factor == -1);
4349 if (normalize_datetime(&year, &month, &day,
4350 &hour, &minute, &second, &microsecond) < 0)
4351 return NULL;
4352 else
4353 return new_datetime(year, month, day,
4354 hour, minute, second, microsecond,
4355 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004356}
4357
4358static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004359datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004361 if (PyDateTime_Check(left)) {
4362 /* datetime + ??? */
4363 if (PyDelta_Check(right))
4364 /* datetime + delta */
4365 return add_datetime_timedelta(
4366 (PyDateTime_DateTime *)left,
4367 (PyDateTime_Delta *)right,
4368 1);
4369 }
4370 else if (PyDelta_Check(left)) {
4371 /* delta + datetime */
4372 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4373 (PyDateTime_Delta *) left,
4374 1);
4375 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004376 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004377}
4378
4379static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004380datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004382 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 if (PyDateTime_Check(left)) {
4385 /* datetime - ??? */
4386 if (PyDateTime_Check(right)) {
4387 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004388 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004389 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004390
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004391 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4392 offset2 = offset1 = Py_None;
4393 Py_INCREF(offset1);
4394 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004395 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004396 else {
4397 offset1 = datetime_utcoffset(left, NULL);
4398 if (offset1 == NULL)
4399 return NULL;
4400 offset2 = datetime_utcoffset(right, NULL);
4401 if (offset2 == NULL) {
4402 Py_DECREF(offset1);
4403 return NULL;
4404 }
4405 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4406 PyErr_SetString(PyExc_TypeError,
4407 "can't subtract offset-naive and "
4408 "offset-aware datetimes");
4409 Py_DECREF(offset1);
4410 Py_DECREF(offset2);
4411 return NULL;
4412 }
4413 }
4414 if ((offset1 != offset2) &&
4415 delta_cmp(offset1, offset2) != 0) {
4416 offdiff = delta_subtract(offset1, offset2);
4417 if (offdiff == NULL) {
4418 Py_DECREF(offset1);
4419 Py_DECREF(offset2);
4420 return NULL;
4421 }
4422 }
4423 Py_DECREF(offset1);
4424 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004425 delta_d = ymd_to_ord(GET_YEAR(left),
4426 GET_MONTH(left),
4427 GET_DAY(left)) -
4428 ymd_to_ord(GET_YEAR(right),
4429 GET_MONTH(right),
4430 GET_DAY(right));
4431 /* These can't overflow, since the values are
4432 * normalized. At most this gives the number of
4433 * seconds in one day.
4434 */
4435 delta_s = (DATE_GET_HOUR(left) -
4436 DATE_GET_HOUR(right)) * 3600 +
4437 (DATE_GET_MINUTE(left) -
4438 DATE_GET_MINUTE(right)) * 60 +
4439 (DATE_GET_SECOND(left) -
4440 DATE_GET_SECOND(right));
4441 delta_us = DATE_GET_MICROSECOND(left) -
4442 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004443 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004444 if (result == NULL)
4445 return NULL;
4446
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004447 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004448 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004449 Py_DECREF(offdiff);
4450 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004451 }
4452 else if (PyDelta_Check(right)) {
4453 /* datetime - delta */
4454 result = add_datetime_timedelta(
4455 (PyDateTime_DateTime *)left,
4456 (PyDateTime_Delta *)right,
4457 -1);
4458 }
4459 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004461 if (result == Py_NotImplemented)
4462 Py_INCREF(result);
4463 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004464}
4465
4466/* Various ways to turn a datetime into a string. */
4467
4468static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004469datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004471 const char *type_name = Py_TYPE(self)->tp_name;
4472 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004474 if (DATE_GET_MICROSECOND(self)) {
4475 baserepr = PyUnicode_FromFormat(
4476 "%s(%d, %d, %d, %d, %d, %d, %d)",
4477 type_name,
4478 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4479 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4480 DATE_GET_SECOND(self),
4481 DATE_GET_MICROSECOND(self));
4482 }
4483 else if (DATE_GET_SECOND(self)) {
4484 baserepr = PyUnicode_FromFormat(
4485 "%s(%d, %d, %d, %d, %d, %d)",
4486 type_name,
4487 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4488 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4489 DATE_GET_SECOND(self));
4490 }
4491 else {
4492 baserepr = PyUnicode_FromFormat(
4493 "%s(%d, %d, %d, %d, %d)",
4494 type_name,
4495 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4496 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4497 }
4498 if (baserepr == NULL || ! HASTZINFO(self))
4499 return baserepr;
4500 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004501}
4502
Tim Petersa9bc1682003-01-11 03:39:11 +00004503static PyObject *
4504datetime_str(PyDateTime_DateTime *self)
4505{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004506 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004507}
Tim Peters2a799bf2002-12-16 20:18:38 +00004508
4509static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004510datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004511{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004512 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004513 char *timespec = NULL;
4514 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004515 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004516 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004517 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004518 static char *specs[][2] = {
4519 {"hours", "%04d-%02d-%02d%c%02d"},
4520 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4521 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4522 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4523 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4524 };
4525 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004526
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004527 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004528 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004529
4530 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4531 if (us == 0) {
4532 /* seconds */
4533 given_spec = 2;
4534 }
4535 else {
4536 /* microseconds */
4537 given_spec = 4;
4538 }
4539 }
4540 else {
4541 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4542 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4543 if (given_spec == 3) {
4544 us = us / 1000;
4545 }
4546 break;
4547 }
4548 }
4549 }
4550
4551 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4552 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4553 return NULL;
4554 }
4555 else {
4556 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004557 GET_YEAR(self), GET_MONTH(self),
4558 GET_DAY(self), (int)sep,
4559 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4560 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004561 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004563 if (!result || !HASTZINFO(self))
4564 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004566 /* We need to append the UTC offset. */
4567 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4568 (PyObject *)self) < 0) {
4569 Py_DECREF(result);
4570 return NULL;
4571 }
4572 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4573 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004574}
4575
Tim Petersa9bc1682003-01-11 03:39:11 +00004576static PyObject *
4577datetime_ctime(PyDateTime_DateTime *self)
4578{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004579 return format_ctime((PyDateTime_Date *)self,
4580 DATE_GET_HOUR(self),
4581 DATE_GET_MINUTE(self),
4582 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004583}
4584
Tim Peters2a799bf2002-12-16 20:18:38 +00004585/* Miscellaneous methods. */
4586
Tim Petersa9bc1682003-01-11 03:39:11 +00004587static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004588datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004589{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004590 PyObject *result = NULL;
4591 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004592 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004594 if (! PyDateTime_Check(other)) {
4595 if (PyDate_Check(other)) {
4596 /* Prevent invocation of date_richcompare. We want to
4597 return NotImplemented here to give the other object
4598 a chance. But since DateTime is a subclass of
4599 Date, if the other object is a Date, it would
4600 compute an ordering based on the date part alone,
4601 and we don't want that. So force unequal or
4602 uncomparable here in that case. */
4603 if (op == Py_EQ)
4604 Py_RETURN_FALSE;
4605 if (op == Py_NE)
4606 Py_RETURN_TRUE;
4607 return cmperror(self, other);
4608 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004609 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004610 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004611
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004612 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004613 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4614 ((PyDateTime_DateTime *)other)->data,
4615 _PyDateTime_DATETIME_DATASIZE);
4616 return diff_to_bool(diff, op);
4617 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004618 offset1 = datetime_utcoffset(self, NULL);
4619 if (offset1 == NULL)
4620 return NULL;
4621 offset2 = datetime_utcoffset(other, NULL);
4622 if (offset2 == NULL)
4623 goto done;
4624 /* If they're both naive, or both aware and have the same offsets,
4625 * we get off cheap. Note that if they're both naive, offset1 ==
4626 * offset2 == Py_None at this point.
4627 */
4628 if ((offset1 == offset2) ||
4629 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4630 delta_cmp(offset1, offset2) == 0)) {
4631 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4632 ((PyDateTime_DateTime *)other)->data,
4633 _PyDateTime_DATETIME_DATASIZE);
4634 result = diff_to_bool(diff, op);
4635 }
4636 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004637 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004638
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004639 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004640 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4641 other);
4642 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004643 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004644 diff = GET_TD_DAYS(delta);
4645 if (diff == 0)
4646 diff = GET_TD_SECONDS(delta) |
4647 GET_TD_MICROSECONDS(delta);
4648 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004649 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004650 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004651 else if (op == Py_EQ) {
4652 result = Py_False;
4653 Py_INCREF(result);
4654 }
4655 else if (op == Py_NE) {
4656 result = Py_True;
4657 Py_INCREF(result);
4658 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004659 else {
4660 PyErr_SetString(PyExc_TypeError,
4661 "can't compare offset-naive and "
4662 "offset-aware datetimes");
4663 }
4664 done:
4665 Py_DECREF(offset1);
4666 Py_XDECREF(offset2);
4667 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004668}
4669
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004670static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004671datetime_hash(PyDateTime_DateTime *self)
4672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004673 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004674 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004675
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004676 offset = datetime_utcoffset((PyObject *)self, NULL);
4677
4678 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004679 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004682 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 self->hashcode = generic_hash(
4684 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004685 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004686 PyObject *temp1, *temp2;
4687 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004689 assert(HASTZINFO(self));
4690 days = ymd_to_ord(GET_YEAR(self),
4691 GET_MONTH(self),
4692 GET_DAY(self));
4693 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004694 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004695 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004696 temp1 = new_delta(days, seconds,
4697 DATE_GET_MICROSECOND(self),
4698 1);
4699 if (temp1 == NULL) {
4700 Py_DECREF(offset);
4701 return -1;
4702 }
4703 temp2 = delta_subtract(temp1, offset);
4704 Py_DECREF(temp1);
4705 if (temp2 == NULL) {
4706 Py_DECREF(offset);
4707 return -1;
4708 }
4709 self->hashcode = PyObject_Hash(temp2);
4710 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004711 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004712 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004713 }
4714 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004715}
Tim Peters2a799bf2002-12-16 20:18:38 +00004716
4717static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004718datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004720 PyObject *clone;
4721 PyObject *tuple;
4722 int y = GET_YEAR(self);
4723 int m = GET_MONTH(self);
4724 int d = GET_DAY(self);
4725 int hh = DATE_GET_HOUR(self);
4726 int mm = DATE_GET_MINUTE(self);
4727 int ss = DATE_GET_SECOND(self);
4728 int us = DATE_GET_MICROSECOND(self);
4729 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004731 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4732 datetime_kws,
4733 &y, &m, &d, &hh, &mm, &ss, &us,
4734 &tzinfo))
4735 return NULL;
4736 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4737 if (tuple == NULL)
4738 return NULL;
4739 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4740 Py_DECREF(tuple);
4741 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004742}
4743
4744static PyObject *
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004745local_timezone(PyDateTime_DateTime *utc_time)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004746{
4747 PyObject *result = NULL;
4748 struct tm *timep;
4749 time_t timestamp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004750 PyObject *delta;
4751 PyObject *one_second;
4752 PyObject *seconds;
4753 PyObject *nameo = NULL;
4754 const char *zone = NULL;
4755
Alexander Belopolsky1dcf4f92016-03-25 15:42:59 -04004756 delta = new_delta(ymd_to_ord(GET_YEAR(utc_time), GET_MONTH(utc_time),
4757 GET_DAY(utc_time)) - 719163,
4758 60 * (60 * DATE_GET_HOUR(utc_time) +
4759 DATE_GET_MINUTE(utc_time)) +
4760 DATE_GET_SECOND(utc_time),
4761 0, 0);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004762 if (delta == NULL)
4763 return NULL;
4764 one_second = new_delta(0, 1, 0, 0);
4765 if (one_second == NULL)
4766 goto error;
4767 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
4768 (PyDateTime_Delta *)one_second);
4769 Py_DECREF(one_second);
4770 if (seconds == NULL)
4771 goto error;
4772 Py_DECREF(delta);
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03004773 timestamp = _PyLong_AsTime_t(seconds);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004774 Py_DECREF(seconds);
4775 if (timestamp == -1 && PyErr_Occurred())
4776 return NULL;
4777 timep = localtime(&timestamp);
4778#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004779 zone = timep->tm_zone;
4780 delta = new_delta(0, timep->tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004781#else /* HAVE_STRUCT_TM_TM_ZONE */
4782 {
4783 PyObject *local_time;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004784 local_time = new_datetime(timep->tm_year + 1900, timep->tm_mon + 1,
4785 timep->tm_mday, timep->tm_hour, timep->tm_min,
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004786 timep->tm_sec, DATE_GET_MICROSECOND(utc_time),
4787 utc_time->tzinfo);
4788 if (local_time == NULL)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004789 goto error;
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004790 delta = datetime_subtract(local_time, (PyObject*)utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004791 /* XXX: before relying on tzname, we should compare delta
4792 to the offset implied by timezone/altzone */
4793 if (daylight && timep->tm_isdst >= 0)
4794 zone = tzname[timep->tm_isdst % 2];
4795 else
4796 zone = tzname[0];
4797 Py_DECREF(local_time);
4798 }
4799#endif /* HAVE_STRUCT_TM_TM_ZONE */
4800 if (zone != NULL) {
4801 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
4802 if (nameo == NULL)
4803 goto error;
4804 }
4805 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02004806 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004807 error:
4808 Py_DECREF(delta);
4809 return result;
4810}
4811
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004812static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00004813datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004814{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004815 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004816 PyObject *offset;
4817 PyObject *temp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004818 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004819 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004820
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004821 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07004822 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004823 return NULL;
4824
4825 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004826 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004828 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4829 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004831 /* Conversion to self's own time zone is a NOP. */
4832 if (self->tzinfo == tzinfo) {
4833 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004834 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004835 }
Tim Peters521fc152002-12-31 17:36:56 +00004836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004837 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004838 offset = datetime_utcoffset((PyObject *)self, NULL);
4839 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004840 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004841 if (offset == Py_None) {
4842 Py_DECREF(offset);
4843 NeedAware:
4844 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4845 "a naive datetime");
4846 return NULL;
4847 }
Tim Petersf3615152003-01-01 21:51:37 +00004848
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004849 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004850 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4851 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004852 Py_DECREF(offset);
4853 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004854 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004856 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004857 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004858 if (tzinfo == Py_None) {
4859 tzinfo = local_timezone(result);
4860 if (tzinfo == NULL) {
4861 Py_DECREF(result);
4862 return NULL;
4863 }
4864 }
4865 else
4866 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004867 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004868 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004869
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004870 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004871 result = (PyDateTime_DateTime *)
4872 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004873 Py_DECREF(temp);
4874
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004875 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004876}
4877
4878static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004879datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004881 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004883 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004884 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004885
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004886 dst = call_dst(self->tzinfo, (PyObject *)self);
4887 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004888 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004889
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004890 if (dst != Py_None)
4891 dstflag = delta_bool((PyDateTime_Delta *)dst);
4892 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004893 }
4894 return build_struct_time(GET_YEAR(self),
4895 GET_MONTH(self),
4896 GET_DAY(self),
4897 DATE_GET_HOUR(self),
4898 DATE_GET_MINUTE(self),
4899 DATE_GET_SECOND(self),
4900 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004901}
4902
4903static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04004904datetime_timestamp(PyDateTime_DateTime *self)
4905{
4906 PyObject *result;
4907
4908 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4909 PyObject *delta;
4910 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
4911 if (delta == NULL)
4912 return NULL;
4913 result = delta_total_seconds(delta);
4914 Py_DECREF(delta);
4915 }
4916 else {
4917 struct tm time;
4918 time_t timestamp;
4919 memset((void *) &time, '\0', sizeof(struct tm));
4920 time.tm_year = GET_YEAR(self) - 1900;
4921 time.tm_mon = GET_MONTH(self) - 1;
4922 time.tm_mday = GET_DAY(self);
4923 time.tm_hour = DATE_GET_HOUR(self);
4924 time.tm_min = DATE_GET_MINUTE(self);
4925 time.tm_sec = DATE_GET_SECOND(self);
4926 time.tm_wday = -1;
4927 time.tm_isdst = -1;
4928 timestamp = mktime(&time);
Victor Stinner93037492013-06-25 22:54:35 +02004929 if (timestamp == (time_t)(-1)
4930#ifndef _AIX
4931 /* Return value of -1 does not necessarily mean an error,
4932 * but tm_wday cannot remain set to -1 if mktime succeeded. */
4933 && time.tm_wday == -1
4934#else
4935 /* on AIX, tm_wday is always sets, even on error */
4936#endif
4937 )
4938 {
Alexander Belopolskya4415142012-06-08 12:33:09 -04004939 PyErr_SetString(PyExc_OverflowError,
4940 "timestamp out of range");
4941 return NULL;
4942 }
4943 result = PyFloat_FromDouble(timestamp + DATE_GET_MICROSECOND(self) / 1e6);
4944 }
4945 return result;
4946}
4947
4948static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004949datetime_getdate(PyDateTime_DateTime *self)
4950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004951 return new_date(GET_YEAR(self),
4952 GET_MONTH(self),
4953 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004954}
4955
4956static PyObject *
4957datetime_gettime(PyDateTime_DateTime *self)
4958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004959 return new_time(DATE_GET_HOUR(self),
4960 DATE_GET_MINUTE(self),
4961 DATE_GET_SECOND(self),
4962 DATE_GET_MICROSECOND(self),
4963 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004964}
4965
4966static PyObject *
4967datetime_gettimetz(PyDateTime_DateTime *self)
4968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004969 return new_time(DATE_GET_HOUR(self),
4970 DATE_GET_MINUTE(self),
4971 DATE_GET_SECOND(self),
4972 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004973 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004974}
4975
4976static PyObject *
4977datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004978{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004979 int y, m, d, hh, mm, ss;
4980 PyObject *tzinfo;
4981 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004982
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004983 tzinfo = GET_DT_TZINFO(self);
4984 if (tzinfo == Py_None) {
4985 utcself = self;
4986 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004987 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004988 else {
4989 PyObject *offset;
4990 offset = call_utcoffset(tzinfo, (PyObject *)self);
4991 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004992 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004993 if (offset == Py_None) {
4994 Py_DECREF(offset);
4995 utcself = self;
4996 Py_INCREF(utcself);
4997 }
4998 else {
4999 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5000 (PyDateTime_Delta *)offset, -1);
5001 Py_DECREF(offset);
5002 if (utcself == NULL)
5003 return NULL;
5004 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005005 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005006 y = GET_YEAR(utcself);
5007 m = GET_MONTH(utcself);
5008 d = GET_DAY(utcself);
5009 hh = DATE_GET_HOUR(utcself);
5010 mm = DATE_GET_MINUTE(utcself);
5011 ss = DATE_GET_SECOND(utcself);
5012
5013 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005014 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005015}
5016
Tim Peters371935f2003-02-01 01:52:50 +00005017/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005018
Tim Petersa9bc1682003-01-11 03:39:11 +00005019/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005020 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5021 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005022 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005023 */
5024static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005025datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005026{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005027 PyObject *basestate;
5028 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005030 basestate = PyBytes_FromStringAndSize((char *)self->data,
5031 _PyDateTime_DATETIME_DATASIZE);
5032 if (basestate != NULL) {
5033 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5034 result = PyTuple_Pack(1, basestate);
5035 else
5036 result = PyTuple_Pack(2, basestate, self->tzinfo);
5037 Py_DECREF(basestate);
5038 }
5039 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005040}
5041
5042static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00005043datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00005044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005045 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00005046}
5047
Tim Petersa9bc1682003-01-11 03:39:11 +00005048static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005050 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005051
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005052 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005054 {"utcnow", (PyCFunction)datetime_utcnow,
5055 METH_NOARGS | METH_CLASS,
5056 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005058 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5059 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5060 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005062 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5063 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005064 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005066 {"strptime", (PyCFunction)datetime_strptime,
5067 METH_VARARGS | METH_CLASS,
5068 PyDoc_STR("string, format -> new datetime parsed from a string "
5069 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005071 {"combine", (PyCFunction)datetime_combine,
5072 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5073 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005075 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005077 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5078 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005080 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5081 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005083 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5084 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005086 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5087 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005089 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5090 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005091
Alexander Belopolskya4415142012-06-08 12:33:09 -04005092 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5093 PyDoc_STR("Return POSIX timestamp as float.")},
5094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005095 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5096 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005098 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5099 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005100 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005101 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005102 "defaults to 'T'.\n"
5103 "timespec specifies what components of the time to include"
5104 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5105 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005107 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5108 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005110 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5111 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005113 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5114 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005116 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5117 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005119 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5120 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005122 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5123 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005125 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005126};
5127
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005128static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005129PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5130\n\
5131The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005132instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005133
Tim Petersa9bc1682003-01-11 03:39:11 +00005134static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005135 datetime_add, /* nb_add */
5136 datetime_subtract, /* nb_subtract */
5137 0, /* nb_multiply */
5138 0, /* nb_remainder */
5139 0, /* nb_divmod */
5140 0, /* nb_power */
5141 0, /* nb_negative */
5142 0, /* nb_positive */
5143 0, /* nb_absolute */
5144 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005145};
5146
Neal Norwitz227b5332006-03-22 09:28:35 +00005147static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005148 PyVarObject_HEAD_INIT(NULL, 0)
5149 "datetime.datetime", /* tp_name */
5150 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5151 0, /* tp_itemsize */
5152 (destructor)datetime_dealloc, /* tp_dealloc */
5153 0, /* tp_print */
5154 0, /* tp_getattr */
5155 0, /* tp_setattr */
5156 0, /* tp_reserved */
5157 (reprfunc)datetime_repr, /* tp_repr */
5158 &datetime_as_number, /* tp_as_number */
5159 0, /* tp_as_sequence */
5160 0, /* tp_as_mapping */
5161 (hashfunc)datetime_hash, /* tp_hash */
5162 0, /* tp_call */
5163 (reprfunc)datetime_str, /* tp_str */
5164 PyObject_GenericGetAttr, /* tp_getattro */
5165 0, /* tp_setattro */
5166 0, /* tp_as_buffer */
5167 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5168 datetime_doc, /* tp_doc */
5169 0, /* tp_traverse */
5170 0, /* tp_clear */
5171 datetime_richcompare, /* tp_richcompare */
5172 0, /* tp_weaklistoffset */
5173 0, /* tp_iter */
5174 0, /* tp_iternext */
5175 datetime_methods, /* tp_methods */
5176 0, /* tp_members */
5177 datetime_getset, /* tp_getset */
5178 &PyDateTime_DateType, /* tp_base */
5179 0, /* tp_dict */
5180 0, /* tp_descr_get */
5181 0, /* tp_descr_set */
5182 0, /* tp_dictoffset */
5183 0, /* tp_init */
5184 datetime_alloc, /* tp_alloc */
5185 datetime_new, /* tp_new */
5186 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005187};
5188
5189/* ---------------------------------------------------------------------------
5190 * Module methods and initialization.
5191 */
5192
5193static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005194 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005195};
5196
Tim Peters9ddf40b2004-06-20 22:41:32 +00005197/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5198 * datetime.h.
5199 */
5200static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005201 &PyDateTime_DateType,
5202 &PyDateTime_DateTimeType,
5203 &PyDateTime_TimeType,
5204 &PyDateTime_DeltaType,
5205 &PyDateTime_TZInfoType,
5206 new_date_ex,
5207 new_datetime_ex,
5208 new_time_ex,
5209 new_delta_ex,
5210 datetime_fromtimestamp,
5211 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005212};
5213
5214
Martin v. Löwis1a214512008-06-11 05:26:20 +00005215
5216static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005217 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005218 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005219 "Fast implementation of the datetime type.",
5220 -1,
5221 module_methods,
5222 NULL,
5223 NULL,
5224 NULL,
5225 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005226};
5227
Tim Peters2a799bf2002-12-16 20:18:38 +00005228PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005229PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005231 PyObject *m; /* a module object */
5232 PyObject *d; /* its dict */
5233 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005234 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005236 m = PyModule_Create(&datetimemodule);
5237 if (m == NULL)
5238 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005240 if (PyType_Ready(&PyDateTime_DateType) < 0)
5241 return NULL;
5242 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5243 return NULL;
5244 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5245 return NULL;
5246 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5247 return NULL;
5248 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5249 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005250 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5251 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005253 /* timedelta values */
5254 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005256 x = new_delta(0, 0, 1, 0);
5257 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5258 return NULL;
5259 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005261 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5262 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5263 return NULL;
5264 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005266 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5267 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5268 return NULL;
5269 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005271 /* date values */
5272 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005274 x = new_date(1, 1, 1);
5275 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5276 return NULL;
5277 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005279 x = new_date(MAXYEAR, 12, 31);
5280 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5281 return NULL;
5282 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005284 x = new_delta(1, 0, 0, 0);
5285 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5286 return NULL;
5287 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005289 /* time values */
5290 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005292 x = new_time(0, 0, 0, 0, Py_None);
5293 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5294 return NULL;
5295 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005297 x = new_time(23, 59, 59, 999999, Py_None);
5298 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5299 return NULL;
5300 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005302 x = new_delta(0, 0, 1, 0);
5303 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5304 return NULL;
5305 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005307 /* datetime values */
5308 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005310 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5311 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5312 return NULL;
5313 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005315 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5316 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5317 return NULL;
5318 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005320 x = new_delta(0, 0, 1, 0);
5321 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5322 return NULL;
5323 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005324
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005325 /* timezone values */
5326 d = PyDateTime_TimeZoneType.tp_dict;
5327
5328 delta = new_delta(0, 0, 0, 0);
5329 if (delta == NULL)
5330 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005331 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005332 Py_DECREF(delta);
5333 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5334 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005335 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005336
5337 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5338 if (delta == NULL)
5339 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005340 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005341 Py_DECREF(delta);
5342 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5343 return NULL;
5344 Py_DECREF(x);
5345
5346 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5347 if (delta == NULL)
5348 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005349 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005350 Py_DECREF(delta);
5351 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5352 return NULL;
5353 Py_DECREF(x);
5354
Alexander Belopolskya4415142012-06-08 12:33:09 -04005355 /* Epoch */
5356 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
5357 PyDateTime_TimeZone_UTC);
5358 if (PyDateTime_Epoch == NULL)
5359 return NULL;
5360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005361 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005362 PyModule_AddIntMacro(m, MINYEAR);
5363 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005365 Py_INCREF(&PyDateTime_DateType);
5366 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005368 Py_INCREF(&PyDateTime_DateTimeType);
5369 PyModule_AddObject(m, "datetime",
5370 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005372 Py_INCREF(&PyDateTime_TimeType);
5373 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005375 Py_INCREF(&PyDateTime_DeltaType);
5376 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005378 Py_INCREF(&PyDateTime_TZInfoType);
5379 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005380
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005381 Py_INCREF(&PyDateTime_TimeZoneType);
5382 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005384 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5385 if (x == NULL)
5386 return NULL;
5387 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005389 /* A 4-year cycle has an extra leap day over what we'd get from
5390 * pasting together 4 single years.
5391 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005392 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005393 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005395 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5396 * get from pasting together 4 100-year cycles.
5397 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005398 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005399 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005401 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5402 * pasting together 25 4-year cycles.
5403 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005404 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005405 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005406
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005407 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005408 us_per_ms = PyLong_FromLong(1000);
5409 us_per_second = PyLong_FromLong(1000000);
5410 us_per_minute = PyLong_FromLong(60000000);
5411 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005412 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005413 us_per_minute == NULL || seconds_per_day == NULL)
5414 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005416 /* The rest are too big for 32-bit ints, but even
5417 * us_per_week fits in 40 bits, so doubles should be exact.
5418 */
5419 us_per_hour = PyLong_FromDouble(3600000000.0);
5420 us_per_day = PyLong_FromDouble(86400000000.0);
5421 us_per_week = PyLong_FromDouble(604800000000.0);
5422 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5423 return NULL;
5424 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005425}
Tim Petersf3615152003-01-01 21:51:37 +00005426
5427/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005428Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005429 x.n = x stripped of its timezone -- its naive time.
5430 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005431 return None
Tim Petersf3615152003-01-01 21:51:37 +00005432 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005433 return None
Tim Petersf3615152003-01-01 21:51:37 +00005434 x.s = x's standard offset, x.o - x.d
5435
5436Now some derived rules, where k is a duration (timedelta).
5437
54381. x.o = x.s + x.d
5439 This follows from the definition of x.s.
5440
Tim Petersc5dc4da2003-01-02 17:55:03 +000054412. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005442 This is actually a requirement, an assumption we need to make about
5443 sane tzinfo classes.
5444
54453. The naive UTC time corresponding to x is x.n - x.o.
5446 This is again a requirement for a sane tzinfo class.
5447
54484. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005449 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005450
Tim Petersc5dc4da2003-01-02 17:55:03 +000054515. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005452 Again follows from how arithmetic is defined.
5453
Tim Peters8bb5ad22003-01-24 02:44:45 +00005454Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005455(meaning that the various tzinfo methods exist, and don't blow up or return
5456None when called).
5457
Tim Petersa9bc1682003-01-11 03:39:11 +00005458The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005459x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005460
5461By #3, we want
5462
Tim Peters8bb5ad22003-01-24 02:44:45 +00005463 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005464
5465The algorithm starts by attaching tz to x.n, and calling that y. So
5466x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5467becomes true; in effect, we want to solve [2] for k:
5468
Tim Peters8bb5ad22003-01-24 02:44:45 +00005469 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005470
5471By #1, this is the same as
5472
Tim Peters8bb5ad22003-01-24 02:44:45 +00005473 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005474
5475By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5476Substituting that into [3],
5477
Tim Peters8bb5ad22003-01-24 02:44:45 +00005478 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5479 k - (y+k).s - (y+k).d = 0; rearranging,
5480 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5481 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005482
Tim Peters8bb5ad22003-01-24 02:44:45 +00005483On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5484approximate k by ignoring the (y+k).d term at first. Note that k can't be
5485very large, since all offset-returning methods return a duration of magnitude
5486less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5487be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005488
5489In any case, the new value is
5490
Tim Peters8bb5ad22003-01-24 02:44:45 +00005491 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005492
Tim Peters8bb5ad22003-01-24 02:44:45 +00005493It's helpful to step back at look at [4] from a higher level: it's simply
5494mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005495
5496At this point, if
5497
Tim Peters8bb5ad22003-01-24 02:44:45 +00005498 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005499
5500we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005501at the start of daylight time. Picture US Eastern for concreteness. The wall
5502time 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 +00005503sense then. The docs ask that an Eastern tzinfo class consider such a time to
5504be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5505on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005506the only spelling that makes sense on the local wall clock.
5507
Tim Petersc5dc4da2003-01-02 17:55:03 +00005508In fact, if [5] holds at this point, we do have the standard-time spelling,
5509but that takes a bit of proof. We first prove a stronger result. What's the
5510difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005511
Tim Peters8bb5ad22003-01-24 02:44:45 +00005512 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005513
Tim Petersc5dc4da2003-01-02 17:55:03 +00005514Now
5515 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005516 (y + y.s).n = by #5
5517 y.n + y.s = since y.n = x.n
5518 x.n + y.s = since z and y are have the same tzinfo member,
5519 y.s = z.s by #2
5520 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005521
Tim Petersc5dc4da2003-01-02 17:55:03 +00005522Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005523
Tim Petersc5dc4da2003-01-02 17:55:03 +00005524 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005525 x.n - ((x.n + z.s) - z.o) = expanding
5526 x.n - x.n - z.s + z.o = cancelling
5527 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005528 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005529
Tim Petersc5dc4da2003-01-02 17:55:03 +00005530So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005531
Tim Petersc5dc4da2003-01-02 17:55:03 +00005532If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005533spelling we wanted in the endcase described above. We're done. Contrarily,
5534if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005535
Tim Petersc5dc4da2003-01-02 17:55:03 +00005536If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5537add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005538local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005539
Tim Petersc5dc4da2003-01-02 17:55:03 +00005540Let
Tim Petersf3615152003-01-01 21:51:37 +00005541
Tim Peters4fede1a2003-01-04 00:26:59 +00005542 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005543
Tim Peters4fede1a2003-01-04 00:26:59 +00005544and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005545
Tim Peters8bb5ad22003-01-24 02:44:45 +00005546 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005547
Tim Peters8bb5ad22003-01-24 02:44:45 +00005548If so, we're done. If not, the tzinfo class is insane, according to the
5549assumptions we've made. This also requires a bit of proof. As before, let's
5550compute the difference between the LHS and RHS of [8] (and skipping some of
5551the justifications for the kinds of substitutions we've done several times
5552already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005553
Tim Peters8bb5ad22003-01-24 02:44:45 +00005554 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005555 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5556 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5557 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5558 - z.n + z.n - z.o + z'.o = cancel z.n
5559 - z.o + z'.o = #1 twice
5560 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5561 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005562
5563So 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 +00005564we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5565return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005566
Tim Peters8bb5ad22003-01-24 02:44:45 +00005567How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5568a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5569would have to change the result dst() returns: we start in DST, and moving
5570a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005571
Tim Peters8bb5ad22003-01-24 02:44:45 +00005572There isn't a sane case where this can happen. The closest it gets is at
5573the end of DST, where there's an hour in UTC with no spelling in a hybrid
5574tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5575that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5576UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5577time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5578clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5579standard time. Since that's what the local clock *does*, we want to map both
5580UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005581in local time, but so it goes -- it's the way the local clock works.
5582
Tim Peters8bb5ad22003-01-24 02:44:45 +00005583When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5584so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5585z' = 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 +00005586(correctly) concludes that z' is not UTC-equivalent to x.
5587
5588Because we know z.d said z was in daylight time (else [5] would have held and
5589we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005590and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005591return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5592but the reasoning doesn't depend on the example -- it depends on there being
5593two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005594z' must be in standard time, and is the spelling we want in this case.
5595
5596Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5597concerned (because it takes z' as being in standard time rather than the
5598daylight time we intend here), but returning it gives the real-life "local
5599clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5600tz.
5601
5602When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5603the 1:MM standard time spelling we want.
5604
5605So how can this break? One of the assumptions must be violated. Two
5606possibilities:
5607
56081) [2] effectively says that y.s is invariant across all y belong to a given
5609 time zone. This isn't true if, for political reasons or continental drift,
5610 a region decides to change its base offset from UTC.
5611
56122) There may be versions of "double daylight" time where the tail end of
5613 the analysis gives up a step too early. I haven't thought about that
5614 enough to say.
5615
5616In any case, it's clear that the default fromutc() is strong enough to handle
5617"almost all" time zones: so long as the standard offset is invariant, it
5618doesn't matter if daylight time transition points change from year to year, or
5619if daylight time is skipped in some years; it doesn't matter how large or
5620small dst() may get within its bounds; and it doesn't even matter if some
5621perverse time zone returns a negative dst()). So a breaking case must be
5622pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005623--------------------------------------------------------------------------- */