blob: 3e5e195e153a56a2be657ffb949371eb608fed1a [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) {
1060 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001062 offset = delta_negative((PyDateTime_Delta *)offset);
1063 Py_DECREF(temp);
1064 if (offset == NULL)
1065 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001067 else {
1068 sign = '+';
1069 }
1070 /* Offset is not negative here. */
1071 seconds = GET_TD_SECONDS(offset);
1072 Py_DECREF(offset);
1073 minutes = divmod(seconds, 60, &seconds);
1074 hours = divmod(minutes, 60, &minutes);
1075 assert(seconds == 0);
1076 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001080}
1081
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001082static PyObject *
1083make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 PyObject *temp;
1086 PyObject *tzinfo = get_tzinfo_member(object);
1087 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001088 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 if (Zreplacement == NULL)
1091 return NULL;
1092 if (tzinfo == Py_None || tzinfo == NULL)
1093 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 assert(tzinfoarg != NULL);
1096 temp = call_tzname(tzinfo, tzinfoarg);
1097 if (temp == NULL)
1098 goto Error;
1099 if (temp == Py_None) {
1100 Py_DECREF(temp);
1101 return Zreplacement;
1102 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 assert(PyUnicode_Check(temp));
1105 /* Since the tzname is getting stuffed into the
1106 * format, we have to double any % signs so that
1107 * strftime doesn't treat them as format codes.
1108 */
1109 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001110 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 Py_DECREF(temp);
1112 if (Zreplacement == NULL)
1113 return NULL;
1114 if (!PyUnicode_Check(Zreplacement)) {
1115 PyErr_SetString(PyExc_TypeError,
1116 "tzname.replace() did not return a string");
1117 goto Error;
1118 }
1119 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001120
1121 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 Py_DECREF(Zreplacement);
1123 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001124}
1125
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001126static PyObject *
1127make_freplacement(PyObject *object)
1128{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 char freplacement[64];
1130 if (PyTime_Check(object))
1131 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1132 else if (PyDateTime_Check(object))
1133 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1134 else
1135 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001138}
1139
Tim Peters2a799bf2002-12-16 20:18:38 +00001140/* I sure don't want to reproduce the strftime code from the time module,
1141 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001142 * giving special meanings to the %z, %Z and %f format codes via a
1143 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001144 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1145 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001146 */
1147static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001148wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1154 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1155 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 const char *pin; /* pointer to next char in input format */
1158 Py_ssize_t flen; /* length of input format */
1159 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 PyObject *newfmt = NULL; /* py string, the output format */
1162 char *pnew; /* pointer to available byte in output format */
1163 size_t totalnew; /* number bytes total in output format buffer,
1164 exclusive of trailing \0 */
1165 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 const char *ptoappend; /* ptr to string to append to output buffer */
1168 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 assert(object && format && timetuple);
1171 assert(PyUnicode_Check(format));
1172 /* Convert the input format to a C string and size */
1173 pin = _PyUnicode_AsStringAndSize(format, &flen);
1174 if (!pin)
1175 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 /* Scan the input format, looking for %z/%Z/%f escapes, building
1178 * a new format. Since computing the replacements for those codes
1179 * is expensive, don't unless they're actually used.
1180 */
1181 if (flen > INT_MAX - 1) {
1182 PyErr_NoMemory();
1183 goto Done;
1184 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 totalnew = flen + 1; /* realistic if no %z/%Z */
1187 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1188 if (newfmt == NULL) goto Done;
1189 pnew = PyBytes_AsString(newfmt);
1190 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 while ((ch = *pin++) != '\0') {
1193 if (ch != '%') {
1194 ptoappend = pin - 1;
1195 ntoappend = 1;
1196 }
1197 else if ((ch = *pin++) == '\0') {
1198 /* There's a lone trailing %; doesn't make sense. */
1199 PyErr_SetString(PyExc_ValueError, "strftime format "
1200 "ends with raw %");
1201 goto Done;
1202 }
1203 /* A % has been seen and ch is the character after it. */
1204 else if (ch == 'z') {
1205 if (zreplacement == NULL) {
1206 /* format utcoffset */
1207 char buf[100];
1208 PyObject *tzinfo = get_tzinfo_member(object);
1209 zreplacement = PyBytes_FromStringAndSize("", 0);
1210 if (zreplacement == NULL) goto Done;
1211 if (tzinfo != Py_None && tzinfo != NULL) {
1212 assert(tzinfoarg != NULL);
1213 if (format_utcoffset(buf,
1214 sizeof(buf),
1215 "",
1216 tzinfo,
1217 tzinfoarg) < 0)
1218 goto Done;
1219 Py_DECREF(zreplacement);
1220 zreplacement =
1221 PyBytes_FromStringAndSize(buf,
1222 strlen(buf));
1223 if (zreplacement == NULL)
1224 goto Done;
1225 }
1226 }
1227 assert(zreplacement != NULL);
1228 ptoappend = PyBytes_AS_STRING(zreplacement);
1229 ntoappend = PyBytes_GET_SIZE(zreplacement);
1230 }
1231 else if (ch == 'Z') {
1232 /* format tzname */
1233 if (Zreplacement == NULL) {
1234 Zreplacement = make_Zreplacement(object,
1235 tzinfoarg);
1236 if (Zreplacement == NULL)
1237 goto Done;
1238 }
1239 assert(Zreplacement != NULL);
1240 assert(PyUnicode_Check(Zreplacement));
1241 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1242 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001243 if (ptoappend == NULL)
1244 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 }
1246 else if (ch == 'f') {
1247 /* format microseconds */
1248 if (freplacement == NULL) {
1249 freplacement = make_freplacement(object);
1250 if (freplacement == NULL)
1251 goto Done;
1252 }
1253 assert(freplacement != NULL);
1254 assert(PyBytes_Check(freplacement));
1255 ptoappend = PyBytes_AS_STRING(freplacement);
1256 ntoappend = PyBytes_GET_SIZE(freplacement);
1257 }
1258 else {
1259 /* percent followed by neither z nor Z */
1260 ptoappend = pin - 2;
1261 ntoappend = 2;
1262 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 /* Append the ntoappend chars starting at ptoappend to
1265 * the new format.
1266 */
1267 if (ntoappend == 0)
1268 continue;
1269 assert(ptoappend != NULL);
1270 assert(ntoappend > 0);
1271 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001272 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 PyErr_NoMemory();
1274 goto Done;
1275 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001276 totalnew <<= 1;
1277 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 pnew = PyBytes_AsString(newfmt) + usednew;
1280 }
1281 memcpy(pnew, ptoappend, ntoappend);
1282 pnew += ntoappend;
1283 usednew += ntoappend;
1284 assert(usednew <= totalnew);
1285 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1288 goto Done;
1289 {
1290 PyObject *format;
1291 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 if (time == NULL)
1294 goto Done;
1295 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1296 if (format != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001297 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1298 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 Py_DECREF(format);
1300 }
1301 Py_DECREF(time);
1302 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001303 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 Py_XDECREF(freplacement);
1305 Py_XDECREF(zreplacement);
1306 Py_XDECREF(Zreplacement);
1307 Py_XDECREF(newfmt);
1308 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001309}
1310
Tim Peters2a799bf2002-12-16 20:18:38 +00001311/* ---------------------------------------------------------------------------
1312 * Wrap functions from the time module. These aren't directly available
1313 * from C. Perhaps they should be.
1314 */
1315
1316/* Call time.time() and return its result (a Python float). */
1317static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001318time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 PyObject *result = NULL;
1321 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001324 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001325
1326 result = _PyObject_CallMethodId(time, &PyId_time, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 Py_DECREF(time);
1328 }
1329 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001330}
1331
1332/* Build a time.struct_time. The weekday and day number are automatically
1333 * computed from the y,m,d args.
1334 */
1335static PyObject *
1336build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 PyObject *time;
1339 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 time = PyImport_ImportModuleNoBlock("time");
1342 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001343 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001344
1345 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1346 "((iiiiiiiii))",
1347 y, m, d,
1348 hh, mm, ss,
1349 weekday(y, m, d),
1350 days_before_month(y, m) + d,
1351 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 Py_DECREF(time);
1353 }
1354 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001355}
1356
1357/* ---------------------------------------------------------------------------
1358 * Miscellaneous helpers.
1359 */
1360
Mark Dickinsone94c6792009-02-02 20:36:42 +00001361/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001362 * The comparisons here all most naturally compute a cmp()-like result.
1363 * This little helper turns that into a bool result for rich comparisons.
1364 */
1365static PyObject *
1366diff_to_bool(int diff, int op)
1367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 PyObject *result;
1369 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 switch (op) {
1372 case Py_EQ: istrue = diff == 0; break;
1373 case Py_NE: istrue = diff != 0; break;
1374 case Py_LE: istrue = diff <= 0; break;
1375 case Py_GE: istrue = diff >= 0; break;
1376 case Py_LT: istrue = diff < 0; break;
1377 case Py_GT: istrue = diff > 0; break;
1378 default:
1379 assert(! "op unknown");
1380 istrue = 0; /* To shut up compiler */
1381 }
1382 result = istrue ? Py_True : Py_False;
1383 Py_INCREF(result);
1384 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001385}
1386
Tim Peters07534a62003-02-07 22:50:28 +00001387/* Raises a "can't compare" TypeError and returns NULL. */
1388static PyObject *
1389cmperror(PyObject *a, PyObject *b)
1390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 PyErr_Format(PyExc_TypeError,
1392 "can't compare %s to %s",
1393 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1394 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001395}
1396
Tim Peters2a799bf2002-12-16 20:18:38 +00001397/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001398 * Cached Python objects; these are set by the module init function.
1399 */
1400
1401/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001402static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403static PyObject *us_per_ms = NULL; /* 1000 */
1404static PyObject *us_per_second = NULL; /* 1000000 */
1405static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001406static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1407static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1408static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001409static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1410
Tim Peters2a799bf2002-12-16 20:18:38 +00001411/* ---------------------------------------------------------------------------
1412 * Class implementations.
1413 */
1414
1415/*
1416 * PyDateTime_Delta implementation.
1417 */
1418
1419/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001421 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001422 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1423 * due to ubiquitous overflow possibilities.
1424 */
1425static PyObject *
1426delta_to_microseconds(PyDateTime_Delta *self)
1427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 PyObject *x1 = NULL;
1429 PyObject *x2 = NULL;
1430 PyObject *x3 = NULL;
1431 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1434 if (x1 == NULL)
1435 goto Done;
1436 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1437 if (x2 == NULL)
1438 goto Done;
1439 Py_DECREF(x1);
1440 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 /* x2 has days in seconds */
1443 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1444 if (x1 == NULL)
1445 goto Done;
1446 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1447 if (x3 == NULL)
1448 goto Done;
1449 Py_DECREF(x1);
1450 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001451 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 /* x3 has days+seconds in seconds */
1454 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1455 if (x1 == NULL)
1456 goto Done;
1457 Py_DECREF(x3);
1458 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 /* x1 has days+seconds in us */
1461 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1462 if (x2 == NULL)
1463 goto Done;
1464 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001465
1466Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 Py_XDECREF(x1);
1468 Py_XDECREF(x2);
1469 Py_XDECREF(x3);
1470 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001471}
1472
Serhiy Storchaka95949422013-08-27 19:40:23 +03001473/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001474 */
1475static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001476microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 int us;
1479 int s;
1480 int d;
1481 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 PyObject *tuple = NULL;
1484 PyObject *num = NULL;
1485 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 tuple = PyNumber_Divmod(pyus, us_per_second);
1488 if (tuple == NULL)
1489 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 num = PyTuple_GetItem(tuple, 1); /* us */
1492 if (num == NULL)
1493 goto Done;
1494 temp = PyLong_AsLong(num);
1495 num = NULL;
1496 if (temp == -1 && PyErr_Occurred())
1497 goto Done;
1498 assert(0 <= temp && temp < 1000000);
1499 us = (int)temp;
1500 if (us < 0) {
1501 /* The divisor was positive, so this must be an error. */
1502 assert(PyErr_Occurred());
1503 goto Done;
1504 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1507 if (num == NULL)
1508 goto Done;
1509 Py_INCREF(num);
1510 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 tuple = PyNumber_Divmod(num, seconds_per_day);
1513 if (tuple == NULL)
1514 goto Done;
1515 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 num = PyTuple_GetItem(tuple, 1); /* seconds */
1518 if (num == NULL)
1519 goto Done;
1520 temp = PyLong_AsLong(num);
1521 num = NULL;
1522 if (temp == -1 && PyErr_Occurred())
1523 goto Done;
1524 assert(0 <= temp && temp < 24*3600);
1525 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 if (s < 0) {
1528 /* The divisor was positive, so this must be an error. */
1529 assert(PyErr_Occurred());
1530 goto Done;
1531 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1534 if (num == NULL)
1535 goto Done;
1536 Py_INCREF(num);
1537 temp = PyLong_AsLong(num);
1538 if (temp == -1 && PyErr_Occurred())
1539 goto Done;
1540 d = (int)temp;
1541 if ((long)d != temp) {
1542 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1543 "large to fit in a C int");
1544 goto Done;
1545 }
1546 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001547
1548Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 Py_XDECREF(tuple);
1550 Py_XDECREF(num);
1551 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001552}
1553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554#define microseconds_to_delta(pymicros) \
1555 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001556
Tim Peters2a799bf2002-12-16 20:18:38 +00001557static PyObject *
1558multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 PyObject *pyus_in;
1561 PyObject *pyus_out;
1562 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 pyus_in = delta_to_microseconds(delta);
1565 if (pyus_in == NULL)
1566 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1569 Py_DECREF(pyus_in);
1570 if (pyus_out == NULL)
1571 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 result = microseconds_to_delta(pyus_out);
1574 Py_DECREF(pyus_out);
1575 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001576}
1577
1578static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001579multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1580{
1581 PyObject *result = NULL;
1582 PyObject *pyus_in = NULL, *temp, *pyus_out;
1583 PyObject *ratio = NULL;
1584
1585 pyus_in = delta_to_microseconds(delta);
1586 if (pyus_in == NULL)
1587 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001588 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001589 if (ratio == NULL)
1590 goto error;
1591 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1592 Py_DECREF(pyus_in);
1593 pyus_in = NULL;
1594 if (temp == NULL)
1595 goto error;
1596 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1597 Py_DECREF(temp);
1598 if (pyus_out == NULL)
1599 goto error;
1600 result = microseconds_to_delta(pyus_out);
1601 Py_DECREF(pyus_out);
1602 error:
1603 Py_XDECREF(pyus_in);
1604 Py_XDECREF(ratio);
1605
1606 return result;
1607}
1608
1609static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001610divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 PyObject *pyus_in;
1613 PyObject *pyus_out;
1614 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 pyus_in = delta_to_microseconds(delta);
1617 if (pyus_in == NULL)
1618 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1621 Py_DECREF(pyus_in);
1622 if (pyus_out == NULL)
1623 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 result = microseconds_to_delta(pyus_out);
1626 Py_DECREF(pyus_out);
1627 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001628}
1629
1630static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001631divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 PyObject *pyus_left;
1634 PyObject *pyus_right;
1635 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 pyus_left = delta_to_microseconds(left);
1638 if (pyus_left == NULL)
1639 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 pyus_right = delta_to_microseconds(right);
1642 if (pyus_right == NULL) {
1643 Py_DECREF(pyus_left);
1644 return NULL;
1645 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1648 Py_DECREF(pyus_left);
1649 Py_DECREF(pyus_right);
1650 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001651}
1652
1653static PyObject *
1654truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 PyObject *pyus_left;
1657 PyObject *pyus_right;
1658 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 pyus_left = delta_to_microseconds(left);
1661 if (pyus_left == NULL)
1662 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 pyus_right = delta_to_microseconds(right);
1665 if (pyus_right == NULL) {
1666 Py_DECREF(pyus_left);
1667 return NULL;
1668 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1671 Py_DECREF(pyus_left);
1672 Py_DECREF(pyus_right);
1673 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001674}
1675
1676static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001677truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1678{
1679 PyObject *result = NULL;
1680 PyObject *pyus_in = NULL, *temp, *pyus_out;
1681 PyObject *ratio = NULL;
1682
1683 pyus_in = delta_to_microseconds(delta);
1684 if (pyus_in == NULL)
1685 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001686 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001687 if (ratio == NULL)
1688 goto error;
1689 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1690 Py_DECREF(pyus_in);
1691 pyus_in = NULL;
1692 if (temp == NULL)
1693 goto error;
1694 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1695 Py_DECREF(temp);
1696 if (pyus_out == NULL)
1697 goto error;
1698 result = microseconds_to_delta(pyus_out);
1699 Py_DECREF(pyus_out);
1700 error:
1701 Py_XDECREF(pyus_in);
1702 Py_XDECREF(ratio);
1703
1704 return result;
1705}
1706
1707static PyObject *
1708truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1709{
1710 PyObject *result;
1711 PyObject *pyus_in, *pyus_out;
1712 pyus_in = delta_to_microseconds(delta);
1713 if (pyus_in == NULL)
1714 return NULL;
1715 pyus_out = divide_nearest(pyus_in, i);
1716 Py_DECREF(pyus_in);
1717 if (pyus_out == NULL)
1718 return NULL;
1719 result = microseconds_to_delta(pyus_out);
1720 Py_DECREF(pyus_out);
1721
1722 return result;
1723}
1724
1725static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001726delta_add(PyObject *left, PyObject *right)
1727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1731 /* delta + delta */
1732 /* The C-level additions can't overflow because of the
1733 * invariant bounds.
1734 */
1735 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1736 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1737 int microseconds = GET_TD_MICROSECONDS(left) +
1738 GET_TD_MICROSECONDS(right);
1739 result = new_delta(days, seconds, microseconds, 1);
1740 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 if (result == Py_NotImplemented)
1743 Py_INCREF(result);
1744 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001745}
1746
1747static PyObject *
1748delta_negative(PyDateTime_Delta *self)
1749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 return new_delta(-GET_TD_DAYS(self),
1751 -GET_TD_SECONDS(self),
1752 -GET_TD_MICROSECONDS(self),
1753 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001754}
1755
1756static PyObject *
1757delta_positive(PyDateTime_Delta *self)
1758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 /* Could optimize this (by returning self) if this isn't a
1760 * subclass -- but who uses unary + ? Approximately nobody.
1761 */
1762 return new_delta(GET_TD_DAYS(self),
1763 GET_TD_SECONDS(self),
1764 GET_TD_MICROSECONDS(self),
1765 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001766}
1767
1768static PyObject *
1769delta_abs(PyDateTime_Delta *self)
1770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 assert(GET_TD_MICROSECONDS(self) >= 0);
1774 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 if (GET_TD_DAYS(self) < 0)
1777 result = delta_negative(self);
1778 else
1779 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001782}
1783
1784static PyObject *
1785delta_subtract(PyObject *left, PyObject *right)
1786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1790 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001791 /* The C-level additions can't overflow because of the
1792 * invariant bounds.
1793 */
1794 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1795 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1796 int microseconds = GET_TD_MICROSECONDS(left) -
1797 GET_TD_MICROSECONDS(right);
1798 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 if (result == Py_NotImplemented)
1802 Py_INCREF(result);
1803 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001804}
1805
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001806static int
1807delta_cmp(PyObject *self, PyObject *other)
1808{
1809 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1810 if (diff == 0) {
1811 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1812 if (diff == 0)
1813 diff = GET_TD_MICROSECONDS(self) -
1814 GET_TD_MICROSECONDS(other);
1815 }
1816 return diff;
1817}
1818
Tim Peters2a799bf2002-12-16 20:18:38 +00001819static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001820delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001823 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 return diff_to_bool(diff, op);
1825 }
1826 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001827 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001829}
1830
1831static PyObject *delta_getstate(PyDateTime_Delta *self);
1832
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001833static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001834delta_hash(PyDateTime_Delta *self)
1835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 if (self->hashcode == -1) {
1837 PyObject *temp = delta_getstate(self);
1838 if (temp != NULL) {
1839 self->hashcode = PyObject_Hash(temp);
1840 Py_DECREF(temp);
1841 }
1842 }
1843 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001844}
1845
1846static PyObject *
1847delta_multiply(PyObject *left, PyObject *right)
1848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 if (PyDelta_Check(left)) {
1852 /* delta * ??? */
1853 if (PyLong_Check(right))
1854 result = multiply_int_timedelta(right,
1855 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001856 else if (PyFloat_Check(right))
1857 result = multiply_float_timedelta(right,
1858 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 }
1860 else if (PyLong_Check(left))
1861 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001862 (PyDateTime_Delta *) right);
1863 else if (PyFloat_Check(left))
1864 result = multiply_float_timedelta(left,
1865 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 if (result == Py_NotImplemented)
1868 Py_INCREF(result);
1869 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001870}
1871
1872static PyObject *
1873delta_divide(PyObject *left, PyObject *right)
1874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 if (PyDelta_Check(left)) {
1878 /* delta * ??? */
1879 if (PyLong_Check(right))
1880 result = divide_timedelta_int(
1881 (PyDateTime_Delta *)left,
1882 right);
1883 else if (PyDelta_Check(right))
1884 result = divide_timedelta_timedelta(
1885 (PyDateTime_Delta *)left,
1886 (PyDateTime_Delta *)right);
1887 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 if (result == Py_NotImplemented)
1890 Py_INCREF(result);
1891 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001892}
1893
Mark Dickinson7c186e22010-04-20 22:32:49 +00001894static PyObject *
1895delta_truedivide(PyObject *left, PyObject *right)
1896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 if (PyDelta_Check(left)) {
1900 if (PyDelta_Check(right))
1901 result = truedivide_timedelta_timedelta(
1902 (PyDateTime_Delta *)left,
1903 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001904 else if (PyFloat_Check(right))
1905 result = truedivide_timedelta_float(
1906 (PyDateTime_Delta *)left, right);
1907 else if (PyLong_Check(right))
1908 result = truedivide_timedelta_int(
1909 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 if (result == Py_NotImplemented)
1913 Py_INCREF(result);
1914 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001915}
1916
1917static PyObject *
1918delta_remainder(PyObject *left, PyObject *right)
1919{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 PyObject *pyus_left;
1921 PyObject *pyus_right;
1922 PyObject *pyus_remainder;
1923 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001924
Brian Curtindfc80e32011-08-10 20:28:54 -05001925 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1926 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1929 if (pyus_left == NULL)
1930 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1933 if (pyus_right == NULL) {
1934 Py_DECREF(pyus_left);
1935 return NULL;
1936 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1939 Py_DECREF(pyus_left);
1940 Py_DECREF(pyus_right);
1941 if (pyus_remainder == NULL)
1942 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 remainder = microseconds_to_delta(pyus_remainder);
1945 Py_DECREF(pyus_remainder);
1946 if (remainder == NULL)
1947 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001950}
1951
1952static PyObject *
1953delta_divmod(PyObject *left, PyObject *right)
1954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 PyObject *pyus_left;
1956 PyObject *pyus_right;
1957 PyObject *divmod;
1958 PyObject *delta;
1959 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001960
Brian Curtindfc80e32011-08-10 20:28:54 -05001961 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1962 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1965 if (pyus_left == NULL)
1966 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1969 if (pyus_right == NULL) {
1970 Py_DECREF(pyus_left);
1971 return NULL;
1972 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1975 Py_DECREF(pyus_left);
1976 Py_DECREF(pyus_right);
1977 if (divmod == NULL)
1978 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 assert(PyTuple_Size(divmod) == 2);
1981 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1982 if (delta == NULL) {
1983 Py_DECREF(divmod);
1984 return NULL;
1985 }
1986 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1987 Py_DECREF(delta);
1988 Py_DECREF(divmod);
1989 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001990}
1991
Tim Peters2a799bf2002-12-16 20:18:38 +00001992/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1993 * timedelta constructor. sofar is the # of microseconds accounted for
1994 * so far, and there are factor microseconds per current unit, the number
1995 * of which is given by num. num * factor is added to sofar in a
1996 * numerically careful way, and that's the result. Any fractional
1997 * microseconds left over (this can happen if num is a float type) are
1998 * added into *leftover.
1999 * Note that there are many ways this can give an error (NULL) return.
2000 */
2001static PyObject *
2002accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2003 double *leftover)
2004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 PyObject *prod;
2006 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 if (PyLong_Check(num)) {
2011 prod = PyNumber_Multiply(num, factor);
2012 if (prod == NULL)
2013 return NULL;
2014 sum = PyNumber_Add(sofar, prod);
2015 Py_DECREF(prod);
2016 return sum;
2017 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 if (PyFloat_Check(num)) {
2020 double dnum;
2021 double fracpart;
2022 double intpart;
2023 PyObject *x;
2024 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 /* The Plan: decompose num into an integer part and a
2027 * fractional part, num = intpart + fracpart.
2028 * Then num * factor ==
2029 * intpart * factor + fracpart * factor
2030 * and the LHS can be computed exactly in long arithmetic.
2031 * The RHS is again broken into an int part and frac part.
2032 * and the frac part is added into *leftover.
2033 */
2034 dnum = PyFloat_AsDouble(num);
2035 if (dnum == -1.0 && PyErr_Occurred())
2036 return NULL;
2037 fracpart = modf(dnum, &intpart);
2038 x = PyLong_FromDouble(intpart);
2039 if (x == NULL)
2040 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 prod = PyNumber_Multiply(x, factor);
2043 Py_DECREF(x);
2044 if (prod == NULL)
2045 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 sum = PyNumber_Add(sofar, prod);
2048 Py_DECREF(prod);
2049 if (sum == NULL)
2050 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002052 if (fracpart == 0.0)
2053 return sum;
2054 /* So far we've lost no information. Dealing with the
2055 * fractional part requires float arithmetic, and may
2056 * lose a little info.
2057 */
2058 assert(PyLong_Check(factor));
2059 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 dnum *= fracpart;
2062 fracpart = modf(dnum, &intpart);
2063 x = PyLong_FromDouble(intpart);
2064 if (x == NULL) {
2065 Py_DECREF(sum);
2066 return NULL;
2067 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 y = PyNumber_Add(sum, x);
2070 Py_DECREF(sum);
2071 Py_DECREF(x);
2072 *leftover += fracpart;
2073 return y;
2074 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 PyErr_Format(PyExc_TypeError,
2077 "unsupported type for timedelta %s component: %s",
2078 tag, Py_TYPE(num)->tp_name);
2079 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002080}
2081
2082static PyObject *
2083delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 /* Argument objects. */
2088 PyObject *day = NULL;
2089 PyObject *second = NULL;
2090 PyObject *us = NULL;
2091 PyObject *ms = NULL;
2092 PyObject *minute = NULL;
2093 PyObject *hour = NULL;
2094 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 PyObject *x = NULL; /* running sum of microseconds */
2097 PyObject *y = NULL; /* temp sum of microseconds */
2098 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 static char *keywords[] = {
2101 "days", "seconds", "microseconds", "milliseconds",
2102 "minutes", "hours", "weeks", NULL
2103 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002105 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2106 keywords,
2107 &day, &second, &us,
2108 &ms, &minute, &hour, &week) == 0)
2109 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 x = PyLong_FromLong(0);
2112 if (x == NULL)
2113 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115#define CLEANUP \
2116 Py_DECREF(x); \
2117 x = y; \
2118 if (x == NULL) \
2119 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002122 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 CLEANUP;
2124 }
2125 if (ms) {
2126 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2127 CLEANUP;
2128 }
2129 if (second) {
2130 y = accum("seconds", x, second, us_per_second, &leftover_us);
2131 CLEANUP;
2132 }
2133 if (minute) {
2134 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2135 CLEANUP;
2136 }
2137 if (hour) {
2138 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2139 CLEANUP;
2140 }
2141 if (day) {
2142 y = accum("days", x, day, us_per_day, &leftover_us);
2143 CLEANUP;
2144 }
2145 if (week) {
2146 y = accum("weeks", x, week, us_per_week, &leftover_us);
2147 CLEANUP;
2148 }
2149 if (leftover_us) {
2150 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002151 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002152 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002153 PyObject *temp;
2154
Victor Stinner69cc4872015-09-08 23:58:54 +02002155 whole_us = round(leftover_us);
2156 if (fabs(whole_us - leftover_us) == 0.5) {
2157 /* We're exactly halfway between two integers. In order
2158 * to do round-half-to-even, we must determine whether x
2159 * is odd. Note that x is odd when it's last bit is 1. The
2160 * code below uses bitwise and operation to check the last
2161 * bit. */
2162 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2163 if (temp == NULL) {
2164 Py_DECREF(x);
2165 goto Done;
2166 }
2167 x_is_odd = PyObject_IsTrue(temp);
2168 Py_DECREF(temp);
2169 if (x_is_odd == -1) {
2170 Py_DECREF(x);
2171 goto Done;
2172 }
2173 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2174 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002175
Victor Stinner36a5a062013-08-28 01:53:39 +02002176 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 if (temp == NULL) {
2179 Py_DECREF(x);
2180 goto Done;
2181 }
2182 y = PyNumber_Add(x, temp);
2183 Py_DECREF(temp);
2184 CLEANUP;
2185 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 self = microseconds_to_delta_ex(x, type);
2188 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002189Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002191
2192#undef CLEANUP
2193}
2194
2195static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002196delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002197{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 return (GET_TD_DAYS(self) != 0
2199 || GET_TD_SECONDS(self) != 0
2200 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002201}
2202
2203static PyObject *
2204delta_repr(PyDateTime_Delta *self)
2205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 if (GET_TD_MICROSECONDS(self) != 0)
2207 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2208 Py_TYPE(self)->tp_name,
2209 GET_TD_DAYS(self),
2210 GET_TD_SECONDS(self),
2211 GET_TD_MICROSECONDS(self));
2212 if (GET_TD_SECONDS(self) != 0)
2213 return PyUnicode_FromFormat("%s(%d, %d)",
2214 Py_TYPE(self)->tp_name,
2215 GET_TD_DAYS(self),
2216 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002218 return PyUnicode_FromFormat("%s(%d)",
2219 Py_TYPE(self)->tp_name,
2220 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002221}
2222
2223static PyObject *
2224delta_str(PyDateTime_Delta *self)
2225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 int us = GET_TD_MICROSECONDS(self);
2227 int seconds = GET_TD_SECONDS(self);
2228 int minutes = divmod(seconds, 60, &seconds);
2229 int hours = divmod(minutes, 60, &minutes);
2230 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 if (days) {
2233 if (us)
2234 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2235 days, (days == 1 || days == -1) ? "" : "s",
2236 hours, minutes, seconds, us);
2237 else
2238 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2239 days, (days == 1 || days == -1) ? "" : "s",
2240 hours, minutes, seconds);
2241 } else {
2242 if (us)
2243 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2244 hours, minutes, seconds, us);
2245 else
2246 return PyUnicode_FromFormat("%d:%02d:%02d",
2247 hours, minutes, seconds);
2248 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002249
Tim Peters2a799bf2002-12-16 20:18:38 +00002250}
2251
Tim Peters371935f2003-02-01 01:52:50 +00002252/* Pickle support, a simple use of __reduce__. */
2253
Tim Petersb57f8f02003-02-01 02:54:15 +00002254/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002255static PyObject *
2256delta_getstate(PyDateTime_Delta *self)
2257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 return Py_BuildValue("iii", GET_TD_DAYS(self),
2259 GET_TD_SECONDS(self),
2260 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002261}
2262
Tim Peters2a799bf2002-12-16 20:18:38 +00002263static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002264delta_total_seconds(PyObject *self)
2265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 PyObject *total_seconds;
2267 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2270 if (total_microseconds == NULL)
2271 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002272
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002273 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002275 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002277}
2278
2279static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002280delta_reduce(PyDateTime_Delta* self)
2281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002283}
2284
2285#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2286
2287static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 {"days", T_INT, OFFSET(days), READONLY,
2290 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 {"seconds", T_INT, OFFSET(seconds), READONLY,
2293 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2296 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2297 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002298};
2299
2300static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002301 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2302 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2305 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002308};
2309
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002310static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002311PyDoc_STR("Difference between two datetime values.");
2312
2313static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 delta_add, /* nb_add */
2315 delta_subtract, /* nb_subtract */
2316 delta_multiply, /* nb_multiply */
2317 delta_remainder, /* nb_remainder */
2318 delta_divmod, /* nb_divmod */
2319 0, /* nb_power */
2320 (unaryfunc)delta_negative, /* nb_negative */
2321 (unaryfunc)delta_positive, /* nb_positive */
2322 (unaryfunc)delta_abs, /* nb_absolute */
2323 (inquiry)delta_bool, /* nb_bool */
2324 0, /*nb_invert*/
2325 0, /*nb_lshift*/
2326 0, /*nb_rshift*/
2327 0, /*nb_and*/
2328 0, /*nb_xor*/
2329 0, /*nb_or*/
2330 0, /*nb_int*/
2331 0, /*nb_reserved*/
2332 0, /*nb_float*/
2333 0, /*nb_inplace_add*/
2334 0, /*nb_inplace_subtract*/
2335 0, /*nb_inplace_multiply*/
2336 0, /*nb_inplace_remainder*/
2337 0, /*nb_inplace_power*/
2338 0, /*nb_inplace_lshift*/
2339 0, /*nb_inplace_rshift*/
2340 0, /*nb_inplace_and*/
2341 0, /*nb_inplace_xor*/
2342 0, /*nb_inplace_or*/
2343 delta_divide, /* nb_floor_divide */
2344 delta_truedivide, /* nb_true_divide */
2345 0, /* nb_inplace_floor_divide */
2346 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002347};
2348
2349static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350 PyVarObject_HEAD_INIT(NULL, 0)
2351 "datetime.timedelta", /* tp_name */
2352 sizeof(PyDateTime_Delta), /* tp_basicsize */
2353 0, /* tp_itemsize */
2354 0, /* tp_dealloc */
2355 0, /* tp_print */
2356 0, /* tp_getattr */
2357 0, /* tp_setattr */
2358 0, /* tp_reserved */
2359 (reprfunc)delta_repr, /* tp_repr */
2360 &delta_as_number, /* tp_as_number */
2361 0, /* tp_as_sequence */
2362 0, /* tp_as_mapping */
2363 (hashfunc)delta_hash, /* tp_hash */
2364 0, /* tp_call */
2365 (reprfunc)delta_str, /* tp_str */
2366 PyObject_GenericGetAttr, /* tp_getattro */
2367 0, /* tp_setattro */
2368 0, /* tp_as_buffer */
2369 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2370 delta_doc, /* tp_doc */
2371 0, /* tp_traverse */
2372 0, /* tp_clear */
2373 delta_richcompare, /* tp_richcompare */
2374 0, /* tp_weaklistoffset */
2375 0, /* tp_iter */
2376 0, /* tp_iternext */
2377 delta_methods, /* tp_methods */
2378 delta_members, /* tp_members */
2379 0, /* tp_getset */
2380 0, /* tp_base */
2381 0, /* tp_dict */
2382 0, /* tp_descr_get */
2383 0, /* tp_descr_set */
2384 0, /* tp_dictoffset */
2385 0, /* tp_init */
2386 0, /* tp_alloc */
2387 delta_new, /* tp_new */
2388 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002389};
2390
2391/*
2392 * PyDateTime_Date implementation.
2393 */
2394
2395/* Accessor properties. */
2396
2397static PyObject *
2398date_year(PyDateTime_Date *self, void *unused)
2399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002401}
2402
2403static PyObject *
2404date_month(PyDateTime_Date *self, void *unused)
2405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002407}
2408
2409static PyObject *
2410date_day(PyDateTime_Date *self, void *unused)
2411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002413}
2414
2415static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 {"year", (getter)date_year},
2417 {"month", (getter)date_month},
2418 {"day", (getter)date_day},
2419 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002420};
2421
2422/* Constructors. */
2423
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002424static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002425
Tim Peters2a799bf2002-12-16 20:18:38 +00002426static PyObject *
2427date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 PyObject *self = NULL;
2430 PyObject *state;
2431 int year;
2432 int month;
2433 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 /* Check for invocation from pickle with __getstate__ state */
2436 if (PyTuple_GET_SIZE(args) == 1 &&
2437 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2438 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2439 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2440 {
2441 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2444 if (me != NULL) {
2445 char *pdata = PyBytes_AS_STRING(state);
2446 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2447 me->hashcode = -1;
2448 }
2449 return (PyObject *)me;
2450 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2453 &year, &month, &day)) {
2454 if (check_date_args(year, month, day) < 0)
2455 return NULL;
2456 self = new_date_ex(year, month, day, type);
2457 }
2458 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002459}
2460
2461/* Return new date from localtime(t). */
2462static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002463date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 struct tm *tm;
2466 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002467
Victor Stinnere4a994d2015-03-30 01:10:14 +02002468 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 tm = localtime(&t);
Victor Stinner21f58932012-03-14 00:15:40 +01002472 if (tm == NULL) {
2473 /* unconvertible time */
2474#ifdef EINVAL
2475 if (errno == 0)
2476 errno = EINVAL;
2477#endif
2478 PyErr_SetFromErrno(PyExc_OSError);
2479 return NULL;
2480 }
2481
2482 return PyObject_CallFunction(cls, "iii",
2483 tm->tm_year + 1900,
2484 tm->tm_mon + 1,
2485 tm->tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002486}
2487
2488/* Return new date from current time.
2489 * We say this is equivalent to fromtimestamp(time.time()), and the
2490 * only way to be sure of that is to *call* time.time(). That's not
2491 * generally the same as calling C's time.
2492 */
2493static PyObject *
2494date_today(PyObject *cls, PyObject *dummy)
2495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 PyObject *time;
2497 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002498 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 time = time_time();
2501 if (time == NULL)
2502 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 /* Note well: today() is a class method, so this may not call
2505 * date.fromtimestamp. For example, it may call
2506 * datetime.fromtimestamp. That's why we need all the accuracy
2507 * time.time() delivers; if someone were gonzo about optimization,
2508 * date.today() could get away with plain C time().
2509 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002510 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 Py_DECREF(time);
2512 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002513}
2514
2515/* Return new date from given timestamp (Python timestamp -- a double). */
2516static PyObject *
2517date_fromtimestamp(PyObject *cls, PyObject *args)
2518{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002519 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002521
Victor Stinner5d272cc2012-03-13 13:35:55 +01002522 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2523 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002525}
2526
2527/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2528 * the ordinal is out of range.
2529 */
2530static PyObject *
2531date_fromordinal(PyObject *cls, PyObject *args)
2532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002533 PyObject *result = NULL;
2534 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2537 int year;
2538 int month;
2539 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002541 if (ordinal < 1)
2542 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2543 ">= 1");
2544 else {
2545 ord_to_ymd(ordinal, &year, &month, &day);
2546 result = PyObject_CallFunction(cls, "iii",
2547 year, month, day);
2548 }
2549 }
2550 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002551}
2552
2553/*
2554 * Date arithmetic.
2555 */
2556
2557/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2558 * instead.
2559 */
2560static PyObject *
2561add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2562{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002563 PyObject *result = NULL;
2564 int year = GET_YEAR(date);
2565 int month = GET_MONTH(date);
2566 int deltadays = GET_TD_DAYS(delta);
2567 /* C-level overflow is impossible because |deltadays| < 1e9. */
2568 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002570 if (normalize_date(&year, &month, &day) >= 0)
2571 result = new_date(year, month, day);
2572 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002573}
2574
2575static PyObject *
2576date_add(PyObject *left, PyObject *right)
2577{
Brian Curtindfc80e32011-08-10 20:28:54 -05002578 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2579 Py_RETURN_NOTIMPLEMENTED;
2580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 if (PyDate_Check(left)) {
2582 /* date + ??? */
2583 if (PyDelta_Check(right))
2584 /* date + delta */
2585 return add_date_timedelta((PyDateTime_Date *) left,
2586 (PyDateTime_Delta *) right,
2587 0);
2588 }
2589 else {
2590 /* ??? + date
2591 * 'right' must be one of us, or we wouldn't have been called
2592 */
2593 if (PyDelta_Check(left))
2594 /* delta + date */
2595 return add_date_timedelta((PyDateTime_Date *) right,
2596 (PyDateTime_Delta *) left,
2597 0);
2598 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002599 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002600}
2601
2602static PyObject *
2603date_subtract(PyObject *left, PyObject *right)
2604{
Brian Curtindfc80e32011-08-10 20:28:54 -05002605 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2606 Py_RETURN_NOTIMPLEMENTED;
2607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 if (PyDate_Check(left)) {
2609 if (PyDate_Check(right)) {
2610 /* date - date */
2611 int left_ord = ymd_to_ord(GET_YEAR(left),
2612 GET_MONTH(left),
2613 GET_DAY(left));
2614 int right_ord = ymd_to_ord(GET_YEAR(right),
2615 GET_MONTH(right),
2616 GET_DAY(right));
2617 return new_delta(left_ord - right_ord, 0, 0, 0);
2618 }
2619 if (PyDelta_Check(right)) {
2620 /* date - delta */
2621 return add_date_timedelta((PyDateTime_Date *) left,
2622 (PyDateTime_Delta *) right,
2623 1);
2624 }
2625 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002626 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002627}
2628
2629
2630/* Various ways to turn a date into a string. */
2631
2632static PyObject *
2633date_repr(PyDateTime_Date *self)
2634{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002635 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2636 Py_TYPE(self)->tp_name,
2637 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002638}
2639
2640static PyObject *
2641date_isoformat(PyDateTime_Date *self)
2642{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643 return PyUnicode_FromFormat("%04d-%02d-%02d",
2644 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002645}
2646
Tim Peterse2df5ff2003-05-02 18:39:55 +00002647/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002648static PyObject *
2649date_str(PyDateTime_Date *self)
2650{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002651 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002652}
2653
2654
2655static PyObject *
2656date_ctime(PyDateTime_Date *self)
2657{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002659}
2660
2661static PyObject *
2662date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2663{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002664 /* This method can be inherited, and needs to call the
2665 * timetuple() method appropriate to self's class.
2666 */
2667 PyObject *result;
2668 PyObject *tuple;
2669 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002670 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002673 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2674 &format))
2675 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002676
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002677 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002678 if (tuple == NULL)
2679 return NULL;
2680 result = wrap_strftime((PyObject *)self, format, tuple,
2681 (PyObject *)self);
2682 Py_DECREF(tuple);
2683 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002684}
2685
Eric Smith1ba31142007-09-11 18:06:02 +00002686static PyObject *
2687date_format(PyDateTime_Date *self, PyObject *args)
2688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002689 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002691 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2692 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002694 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002695 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002696 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002697
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002698 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002699}
2700
Tim Peters2a799bf2002-12-16 20:18:38 +00002701/* ISO methods. */
2702
2703static PyObject *
2704date_isoweekday(PyDateTime_Date *self)
2705{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002706 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002708 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002709}
2710
2711static PyObject *
2712date_isocalendar(PyDateTime_Date *self)
2713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002714 int year = GET_YEAR(self);
2715 int week1_monday = iso_week1_monday(year);
2716 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2717 int week;
2718 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 week = divmod(today - week1_monday, 7, &day);
2721 if (week < 0) {
2722 --year;
2723 week1_monday = iso_week1_monday(year);
2724 week = divmod(today - week1_monday, 7, &day);
2725 }
2726 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2727 ++year;
2728 week = 0;
2729 }
2730 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002731}
2732
2733/* Miscellaneous methods. */
2734
Tim Peters2a799bf2002-12-16 20:18:38 +00002735static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002736date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002738 if (PyDate_Check(other)) {
2739 int diff = memcmp(((PyDateTime_Date *)self)->data,
2740 ((PyDateTime_Date *)other)->data,
2741 _PyDateTime_DATE_DATASIZE);
2742 return diff_to_bool(diff, op);
2743 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002744 else
2745 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002746}
2747
2748static PyObject *
2749date_timetuple(PyDateTime_Date *self)
2750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002751 return build_struct_time(GET_YEAR(self),
2752 GET_MONTH(self),
2753 GET_DAY(self),
2754 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002755}
2756
Tim Peters12bf3392002-12-24 05:41:27 +00002757static PyObject *
2758date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002760 PyObject *clone;
2761 PyObject *tuple;
2762 int year = GET_YEAR(self);
2763 int month = GET_MONTH(self);
2764 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002766 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2767 &year, &month, &day))
2768 return NULL;
2769 tuple = Py_BuildValue("iii", year, month, day);
2770 if (tuple == NULL)
2771 return NULL;
2772 clone = date_new(Py_TYPE(self), tuple, NULL);
2773 Py_DECREF(tuple);
2774 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002775}
2776
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002777static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002778generic_hash(unsigned char *data, int len)
2779{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002780 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002781}
2782
2783
2784static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002785
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002786static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002787date_hash(PyDateTime_Date *self)
2788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002789 if (self->hashcode == -1)
2790 self->hashcode = generic_hash(
2791 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002793 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002794}
2795
2796static PyObject *
2797date_toordinal(PyDateTime_Date *self)
2798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002799 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2800 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002801}
2802
2803static PyObject *
2804date_weekday(PyDateTime_Date *self)
2805{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002806 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002808 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002809}
2810
Tim Peters371935f2003-02-01 01:52:50 +00002811/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002812
Tim Petersb57f8f02003-02-01 02:54:15 +00002813/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002814static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002815date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002817 PyObject* field;
2818 field = PyBytes_FromStringAndSize((char*)self->data,
2819 _PyDateTime_DATE_DATASIZE);
2820 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002821}
2822
2823static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002824date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002826 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002827}
2828
2829static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002833 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2834 METH_CLASS,
2835 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2836 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002838 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2839 METH_CLASS,
2840 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2841 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002843 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2844 PyDoc_STR("Current date or datetime: same as "
2845 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2850 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002852 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2853 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002855 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2856 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002858 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2859 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002861 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2862 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2863 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002865 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2866 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2869 PyDoc_STR("Return the day of the week represented by the date.\n"
2870 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002872 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2873 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2874 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002876 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2877 PyDoc_STR("Return the day of the week represented by the date.\n"
2878 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002880 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2881 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002883 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2884 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002886 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002887};
2888
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002889static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002890PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002891
2892static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 date_add, /* nb_add */
2894 date_subtract, /* nb_subtract */
2895 0, /* nb_multiply */
2896 0, /* nb_remainder */
2897 0, /* nb_divmod */
2898 0, /* nb_power */
2899 0, /* nb_negative */
2900 0, /* nb_positive */
2901 0, /* nb_absolute */
2902 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002903};
2904
2905static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002906 PyVarObject_HEAD_INIT(NULL, 0)
2907 "datetime.date", /* tp_name */
2908 sizeof(PyDateTime_Date), /* tp_basicsize */
2909 0, /* tp_itemsize */
2910 0, /* tp_dealloc */
2911 0, /* tp_print */
2912 0, /* tp_getattr */
2913 0, /* tp_setattr */
2914 0, /* tp_reserved */
2915 (reprfunc)date_repr, /* tp_repr */
2916 &date_as_number, /* tp_as_number */
2917 0, /* tp_as_sequence */
2918 0, /* tp_as_mapping */
2919 (hashfunc)date_hash, /* tp_hash */
2920 0, /* tp_call */
2921 (reprfunc)date_str, /* tp_str */
2922 PyObject_GenericGetAttr, /* tp_getattro */
2923 0, /* tp_setattro */
2924 0, /* tp_as_buffer */
2925 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2926 date_doc, /* tp_doc */
2927 0, /* tp_traverse */
2928 0, /* tp_clear */
2929 date_richcompare, /* tp_richcompare */
2930 0, /* tp_weaklistoffset */
2931 0, /* tp_iter */
2932 0, /* tp_iternext */
2933 date_methods, /* tp_methods */
2934 0, /* tp_members */
2935 date_getset, /* tp_getset */
2936 0, /* tp_base */
2937 0, /* tp_dict */
2938 0, /* tp_descr_get */
2939 0, /* tp_descr_set */
2940 0, /* tp_dictoffset */
2941 0, /* tp_init */
2942 0, /* tp_alloc */
2943 date_new, /* tp_new */
2944 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002945};
2946
2947/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002948 * PyDateTime_TZInfo implementation.
2949 */
2950
2951/* This is a pure abstract base class, so doesn't do anything beyond
2952 * raising NotImplemented exceptions. Real tzinfo classes need
2953 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002954 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002955 * be subclasses of this tzinfo class, which is easy and quick to check).
2956 *
2957 * Note: For reasons having to do with pickling of subclasses, we have
2958 * to allow tzinfo objects to be instantiated. This wasn't an issue
2959 * in the Python implementation (__init__() could raise NotImplementedError
2960 * there without ill effect), but doing so in the C implementation hit a
2961 * brick wall.
2962 */
2963
2964static PyObject *
2965tzinfo_nogo(const char* methodname)
2966{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002967 PyErr_Format(PyExc_NotImplementedError,
2968 "a tzinfo subclass must implement %s()",
2969 methodname);
2970 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002971}
2972
2973/* Methods. A subclass must implement these. */
2974
Tim Peters52dcce22003-01-23 16:36:11 +00002975static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002976tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002978 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002979}
2980
Tim Peters52dcce22003-01-23 16:36:11 +00002981static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002982tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002984 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002985}
2986
Tim Peters52dcce22003-01-23 16:36:11 +00002987static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002988tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002990 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002991}
2992
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002993
2994static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2995 PyDateTime_Delta *delta,
2996 int factor);
2997static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2998static PyObject *datetime_dst(PyObject *self, PyObject *);
2999
Tim Peters52dcce22003-01-23 16:36:11 +00003000static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003001tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003002{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003003 PyObject *result = NULL;
3004 PyObject *off = NULL, *dst = NULL;
3005 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003006
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003007 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003008 PyErr_SetString(PyExc_TypeError,
3009 "fromutc: argument must be a datetime");
3010 return NULL;
3011 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003012 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003013 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3014 "is not self");
3015 return NULL;
3016 }
Tim Peters52dcce22003-01-23 16:36:11 +00003017
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003018 off = datetime_utcoffset(dt, NULL);
3019 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003020 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003021 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003022 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3023 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003024 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003025 }
Tim Peters52dcce22003-01-23 16:36:11 +00003026
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003027 dst = datetime_dst(dt, NULL);
3028 if (dst == NULL)
3029 goto Fail;
3030 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003031 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3032 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003033 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003034 }
Tim Peters52dcce22003-01-23 16:36:11 +00003035
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003036 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3037 if (delta == NULL)
3038 goto Fail;
3039 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003040 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003041 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003042
3043 Py_DECREF(dst);
3044 dst = call_dst(GET_DT_TZINFO(dt), result);
3045 if (dst == NULL)
3046 goto Fail;
3047 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003048 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003049 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003050 PyObject *temp = result;
3051 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3052 (PyDateTime_Delta *)dst, 1);
3053 Py_DECREF(temp);
3054 if (result == NULL)
3055 goto Fail;
3056 }
3057 Py_DECREF(delta);
3058 Py_DECREF(dst);
3059 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003060 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003061
3062Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003063 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3064 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003066 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003067Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003068 Py_XDECREF(off);
3069 Py_XDECREF(dst);
3070 Py_XDECREF(delta);
3071 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003072 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003073}
3074
Tim Peters2a799bf2002-12-16 20:18:38 +00003075/*
3076 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003077 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003078 */
3079
Guido van Rossum177e41a2003-01-30 22:06:23 +00003080static PyObject *
3081tzinfo_reduce(PyObject *self)
3082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 PyObject *args, *state, *tmp;
3084 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003085 _Py_IDENTIFIER(__getinitargs__);
3086 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003088 tmp = PyTuple_New(0);
3089 if (tmp == NULL)
3090 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003091
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003092 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003093 if (getinitargs != NULL) {
3094 args = PyObject_CallObject(getinitargs, tmp);
3095 Py_DECREF(getinitargs);
3096 if (args == NULL) {
3097 Py_DECREF(tmp);
3098 return NULL;
3099 }
3100 }
3101 else {
3102 PyErr_Clear();
3103 args = tmp;
3104 Py_INCREF(args);
3105 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003106
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003107 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003108 if (getstate != NULL) {
3109 state = PyObject_CallObject(getstate, tmp);
3110 Py_DECREF(getstate);
3111 if (state == NULL) {
3112 Py_DECREF(args);
3113 Py_DECREF(tmp);
3114 return NULL;
3115 }
3116 }
3117 else {
3118 PyObject **dictptr;
3119 PyErr_Clear();
3120 state = Py_None;
3121 dictptr = _PyObject_GetDictPtr(self);
3122 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3123 state = *dictptr;
3124 Py_INCREF(state);
3125 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003127 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003129 if (state == Py_None) {
3130 Py_DECREF(state);
3131 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3132 }
3133 else
3134 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003135}
Tim Peters2a799bf2002-12-16 20:18:38 +00003136
3137static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3140 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003142 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003143 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3144 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003146 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3147 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003149 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003150 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003152 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3153 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003155 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003156};
3157
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003158static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003159PyDoc_STR("Abstract base class for time zone info objects.");
3160
Neal Norwitz227b5332006-03-22 09:28:35 +00003161static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003162 PyVarObject_HEAD_INIT(NULL, 0)
3163 "datetime.tzinfo", /* tp_name */
3164 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3165 0, /* tp_itemsize */
3166 0, /* tp_dealloc */
3167 0, /* tp_print */
3168 0, /* tp_getattr */
3169 0, /* tp_setattr */
3170 0, /* tp_reserved */
3171 0, /* tp_repr */
3172 0, /* tp_as_number */
3173 0, /* tp_as_sequence */
3174 0, /* tp_as_mapping */
3175 0, /* tp_hash */
3176 0, /* tp_call */
3177 0, /* tp_str */
3178 PyObject_GenericGetAttr, /* tp_getattro */
3179 0, /* tp_setattro */
3180 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003181 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003182 tzinfo_doc, /* tp_doc */
3183 0, /* tp_traverse */
3184 0, /* tp_clear */
3185 0, /* tp_richcompare */
3186 0, /* tp_weaklistoffset */
3187 0, /* tp_iter */
3188 0, /* tp_iternext */
3189 tzinfo_methods, /* tp_methods */
3190 0, /* tp_members */
3191 0, /* tp_getset */
3192 0, /* tp_base */
3193 0, /* tp_dict */
3194 0, /* tp_descr_get */
3195 0, /* tp_descr_set */
3196 0, /* tp_dictoffset */
3197 0, /* tp_init */
3198 0, /* tp_alloc */
3199 PyType_GenericNew, /* tp_new */
3200 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003201};
3202
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003203static char *timezone_kws[] = {"offset", "name", NULL};
3204
3205static PyObject *
3206timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3207{
3208 PyObject *offset;
3209 PyObject *name = NULL;
3210 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3211 &PyDateTime_DeltaType, &offset,
3212 &PyUnicode_Type, &name))
3213 return new_timezone(offset, name);
3214
3215 return NULL;
3216}
3217
3218static void
3219timezone_dealloc(PyDateTime_TimeZone *self)
3220{
3221 Py_CLEAR(self->offset);
3222 Py_CLEAR(self->name);
3223 Py_TYPE(self)->tp_free((PyObject *)self);
3224}
3225
3226static PyObject *
3227timezone_richcompare(PyDateTime_TimeZone *self,
3228 PyDateTime_TimeZone *other, int op)
3229{
Brian Curtindfc80e32011-08-10 20:28:54 -05003230 if (op != Py_EQ && op != Py_NE)
3231 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003232 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003233 if (op == Py_EQ)
3234 Py_RETURN_FALSE;
3235 else
3236 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003237 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003238 return delta_richcompare(self->offset, other->offset, op);
3239}
3240
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003241static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003242timezone_hash(PyDateTime_TimeZone *self)
3243{
3244 return delta_hash((PyDateTime_Delta *)self->offset);
3245}
3246
3247/* Check argument type passed to tzname, utcoffset, or dst methods.
3248 Returns 0 for good argument. Returns -1 and sets exception info
3249 otherwise.
3250 */
3251static int
3252_timezone_check_argument(PyObject *dt, const char *meth)
3253{
3254 if (dt == Py_None || PyDateTime_Check(dt))
3255 return 0;
3256 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3257 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3258 return -1;
3259}
3260
3261static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003262timezone_repr(PyDateTime_TimeZone *self)
3263{
3264 /* Note that although timezone is not subclassable, it is convenient
3265 to use Py_TYPE(self)->tp_name here. */
3266 const char *type_name = Py_TYPE(self)->tp_name;
3267
3268 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3269 return PyUnicode_FromFormat("%s.utc", type_name);
3270
3271 if (self->name == NULL)
3272 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3273
3274 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3275 self->name);
3276}
3277
3278
3279static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003280timezone_str(PyDateTime_TimeZone *self)
3281{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003282 int hours, minutes, seconds;
3283 PyObject *offset;
3284 char sign;
3285
3286 if (self->name != NULL) {
3287 Py_INCREF(self->name);
3288 return self->name;
3289 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003290 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003291 (GET_TD_DAYS(self->offset) == 0 &&
3292 GET_TD_SECONDS(self->offset) == 0 &&
3293 GET_TD_MICROSECONDS(self->offset) == 0))
3294 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003295 /* Offset is normalized, so it is negative if days < 0 */
3296 if (GET_TD_DAYS(self->offset) < 0) {
3297 sign = '-';
3298 offset = delta_negative((PyDateTime_Delta *)self->offset);
3299 if (offset == NULL)
3300 return NULL;
3301 }
3302 else {
3303 sign = '+';
3304 offset = self->offset;
3305 Py_INCREF(offset);
3306 }
3307 /* Offset is not negative here. */
3308 seconds = GET_TD_SECONDS(offset);
3309 Py_DECREF(offset);
3310 minutes = divmod(seconds, 60, &seconds);
3311 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003312 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003313 assert(seconds == 0);
3314 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003315}
3316
3317static PyObject *
3318timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3319{
3320 if (_timezone_check_argument(dt, "tzname") == -1)
3321 return NULL;
3322
3323 return timezone_str(self);
3324}
3325
3326static PyObject *
3327timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3328{
3329 if (_timezone_check_argument(dt, "utcoffset") == -1)
3330 return NULL;
3331
3332 Py_INCREF(self->offset);
3333 return self->offset;
3334}
3335
3336static PyObject *
3337timezone_dst(PyObject *self, PyObject *dt)
3338{
3339 if (_timezone_check_argument(dt, "dst") == -1)
3340 return NULL;
3341
3342 Py_RETURN_NONE;
3343}
3344
3345static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003346timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3347{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003348 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003349 PyErr_SetString(PyExc_TypeError,
3350 "fromutc: argument must be a datetime");
3351 return NULL;
3352 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003353 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003354 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3355 "is not self");
3356 return NULL;
3357 }
3358
3359 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3360}
3361
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003362static PyObject *
3363timezone_getinitargs(PyDateTime_TimeZone *self)
3364{
3365 if (self->name == NULL)
3366 return Py_BuildValue("(O)", self->offset);
3367 return Py_BuildValue("(OO)", self->offset, self->name);
3368}
3369
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003370static PyMethodDef timezone_methods[] = {
3371 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3372 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003373 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003374
3375 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003376 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003377
3378 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003379 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003380
3381 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3382 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3383
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003384 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3385 PyDoc_STR("pickle support")},
3386
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003387 {NULL, NULL}
3388};
3389
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003390static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003391PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3392
3393static PyTypeObject PyDateTime_TimeZoneType = {
3394 PyVarObject_HEAD_INIT(NULL, 0)
3395 "datetime.timezone", /* tp_name */
3396 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3397 0, /* tp_itemsize */
3398 (destructor)timezone_dealloc, /* tp_dealloc */
3399 0, /* tp_print */
3400 0, /* tp_getattr */
3401 0, /* tp_setattr */
3402 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003403 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003404 0, /* tp_as_number */
3405 0, /* tp_as_sequence */
3406 0, /* tp_as_mapping */
3407 (hashfunc)timezone_hash, /* tp_hash */
3408 0, /* tp_call */
3409 (reprfunc)timezone_str, /* tp_str */
3410 0, /* tp_getattro */
3411 0, /* tp_setattro */
3412 0, /* tp_as_buffer */
3413 Py_TPFLAGS_DEFAULT, /* tp_flags */
3414 timezone_doc, /* tp_doc */
3415 0, /* tp_traverse */
3416 0, /* tp_clear */
3417 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3418 0, /* tp_weaklistoffset */
3419 0, /* tp_iter */
3420 0, /* tp_iternext */
3421 timezone_methods, /* tp_methods */
3422 0, /* tp_members */
3423 0, /* tp_getset */
3424 &PyDateTime_TZInfoType, /* tp_base */
3425 0, /* tp_dict */
3426 0, /* tp_descr_get */
3427 0, /* tp_descr_set */
3428 0, /* tp_dictoffset */
3429 0, /* tp_init */
3430 0, /* tp_alloc */
3431 timezone_new, /* tp_new */
3432};
3433
Tim Peters2a799bf2002-12-16 20:18:38 +00003434/*
Tim Peters37f39822003-01-10 03:49:02 +00003435 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003436 */
3437
Tim Peters37f39822003-01-10 03:49:02 +00003438/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003439 */
3440
3441static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003442time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003443{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003444 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003445}
3446
Tim Peters37f39822003-01-10 03:49:02 +00003447static PyObject *
3448time_minute(PyDateTime_Time *self, void *unused)
3449{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003450 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003451}
3452
3453/* The name time_second conflicted with some platform header file. */
3454static PyObject *
3455py_time_second(PyDateTime_Time *self, void *unused)
3456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003457 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003458}
3459
3460static PyObject *
3461time_microsecond(PyDateTime_Time *self, void *unused)
3462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003463 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003464}
3465
3466static PyObject *
3467time_tzinfo(PyDateTime_Time *self, void *unused)
3468{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003469 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3470 Py_INCREF(result);
3471 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003472}
3473
3474static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003475 {"hour", (getter)time_hour},
3476 {"minute", (getter)time_minute},
3477 {"second", (getter)py_time_second},
3478 {"microsecond", (getter)time_microsecond},
3479 {"tzinfo", (getter)time_tzinfo},
3480 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003481};
3482
3483/*
3484 * Constructors.
3485 */
3486
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003487static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003488 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003489
Tim Peters2a799bf2002-12-16 20:18:38 +00003490static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003491time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003492{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003493 PyObject *self = NULL;
3494 PyObject *state;
3495 int hour = 0;
3496 int minute = 0;
3497 int second = 0;
3498 int usecond = 0;
3499 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003501 /* Check for invocation from pickle with __getstate__ state */
3502 if (PyTuple_GET_SIZE(args) >= 1 &&
3503 PyTuple_GET_SIZE(args) <= 2 &&
3504 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3505 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3506 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3507 {
3508 PyDateTime_Time *me;
3509 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003511 if (PyTuple_GET_SIZE(args) == 2) {
3512 tzinfo = PyTuple_GET_ITEM(args, 1);
3513 if (check_tzinfo_subclass(tzinfo) < 0) {
3514 PyErr_SetString(PyExc_TypeError, "bad "
3515 "tzinfo state arg");
3516 return NULL;
3517 }
3518 }
3519 aware = (char)(tzinfo != Py_None);
3520 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3521 if (me != NULL) {
3522 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003524 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3525 me->hashcode = -1;
3526 me->hastzinfo = aware;
3527 if (aware) {
3528 Py_INCREF(tzinfo);
3529 me->tzinfo = tzinfo;
3530 }
3531 }
3532 return (PyObject *)me;
3533 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003535 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3536 &hour, &minute, &second, &usecond,
3537 &tzinfo)) {
3538 if (check_time_args(hour, minute, second, usecond) < 0)
3539 return NULL;
3540 if (check_tzinfo_subclass(tzinfo) < 0)
3541 return NULL;
3542 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3543 type);
3544 }
3545 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003546}
3547
3548/*
3549 * Destructor.
3550 */
3551
3552static void
Tim Peters37f39822003-01-10 03:49:02 +00003553time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 if (HASTZINFO(self)) {
3556 Py_XDECREF(self->tzinfo);
3557 }
3558 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003559}
3560
3561/*
Tim Peters855fe882002-12-22 03:43:39 +00003562 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003563 */
3564
Tim Peters2a799bf2002-12-16 20:18:38 +00003565/* These are all METH_NOARGS, so don't need to check the arglist. */
3566static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003567time_utcoffset(PyObject *self, PyObject *unused) {
3568 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003569}
3570
3571static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003572time_dst(PyObject *self, PyObject *unused) {
3573 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003574}
3575
3576static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003577time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003578 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003579}
3580
3581/*
Tim Peters37f39822003-01-10 03:49:02 +00003582 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003583 */
3584
3585static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003586time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003588 const char *type_name = Py_TYPE(self)->tp_name;
3589 int h = TIME_GET_HOUR(self);
3590 int m = TIME_GET_MINUTE(self);
3591 int s = TIME_GET_SECOND(self);
3592 int us = TIME_GET_MICROSECOND(self);
3593 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003595 if (us)
3596 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3597 type_name, h, m, s, us);
3598 else if (s)
3599 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3600 type_name, h, m, s);
3601 else
3602 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3603 if (result != NULL && HASTZINFO(self))
3604 result = append_keyword_tzinfo(result, self->tzinfo);
3605 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003606}
3607
Tim Peters37f39822003-01-10 03:49:02 +00003608static PyObject *
3609time_str(PyDateTime_Time *self)
3610{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003611 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003612}
Tim Peters2a799bf2002-12-16 20:18:38 +00003613
3614static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003615time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003617 char buf[100];
3618 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003619 int us = TIME_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003621 if (us)
3622 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3623 TIME_GET_HOUR(self),
3624 TIME_GET_MINUTE(self),
3625 TIME_GET_SECOND(self),
3626 us);
3627 else
3628 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3629 TIME_GET_HOUR(self),
3630 TIME_GET_MINUTE(self),
3631 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003632
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003633 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003634 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003636 /* We need to append the UTC offset. */
3637 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3638 Py_None) < 0) {
3639 Py_DECREF(result);
3640 return NULL;
3641 }
3642 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3643 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003644}
3645
Tim Peters37f39822003-01-10 03:49:02 +00003646static PyObject *
3647time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003649 PyObject *result;
3650 PyObject *tuple;
3651 PyObject *format;
3652 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003654 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3655 &format))
3656 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003658 /* Python's strftime does insane things with the year part of the
3659 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003660 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003661 */
3662 tuple = Py_BuildValue("iiiiiiiii",
3663 1900, 1, 1, /* year, month, day */
3664 TIME_GET_HOUR(self),
3665 TIME_GET_MINUTE(self),
3666 TIME_GET_SECOND(self),
3667 0, 1, -1); /* weekday, daynum, dst */
3668 if (tuple == NULL)
3669 return NULL;
3670 assert(PyTuple_Size(tuple) == 9);
3671 result = wrap_strftime((PyObject *)self, format, tuple,
3672 Py_None);
3673 Py_DECREF(tuple);
3674 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003675}
Tim Peters2a799bf2002-12-16 20:18:38 +00003676
3677/*
3678 * Miscellaneous methods.
3679 */
3680
Tim Peters37f39822003-01-10 03:49:02 +00003681static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003682time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003683{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003684 PyObject *result = NULL;
3685 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003686 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003687
Brian Curtindfc80e32011-08-10 20:28:54 -05003688 if (! PyTime_Check(other))
3689 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003690
3691 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003692 diff = memcmp(((PyDateTime_Time *)self)->data,
3693 ((PyDateTime_Time *)other)->data,
3694 _PyDateTime_TIME_DATASIZE);
3695 return diff_to_bool(diff, op);
3696 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003697 offset1 = time_utcoffset(self, NULL);
3698 if (offset1 == NULL)
3699 return NULL;
3700 offset2 = time_utcoffset(other, NULL);
3701 if (offset2 == NULL)
3702 goto done;
3703 /* If they're both naive, or both aware and have the same offsets,
3704 * we get off cheap. Note that if they're both naive, offset1 ==
3705 * offset2 == Py_None at this point.
3706 */
3707 if ((offset1 == offset2) ||
3708 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3709 delta_cmp(offset1, offset2) == 0)) {
3710 diff = memcmp(((PyDateTime_Time *)self)->data,
3711 ((PyDateTime_Time *)other)->data,
3712 _PyDateTime_TIME_DATASIZE);
3713 result = diff_to_bool(diff, op);
3714 }
3715 /* The hard case: both aware with different UTC offsets */
3716 else if (offset1 != Py_None && offset2 != Py_None) {
3717 int offsecs1, offsecs2;
3718 assert(offset1 != offset2); /* else last "if" handled it */
3719 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3720 TIME_GET_MINUTE(self) * 60 +
3721 TIME_GET_SECOND(self) -
3722 GET_TD_DAYS(offset1) * 86400 -
3723 GET_TD_SECONDS(offset1);
3724 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3725 TIME_GET_MINUTE(other) * 60 +
3726 TIME_GET_SECOND(other) -
3727 GET_TD_DAYS(offset2) * 86400 -
3728 GET_TD_SECONDS(offset2);
3729 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003730 if (diff == 0)
3731 diff = TIME_GET_MICROSECOND(self) -
3732 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003733 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003734 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003735 else if (op == Py_EQ) {
3736 result = Py_False;
3737 Py_INCREF(result);
3738 }
3739 else if (op == Py_NE) {
3740 result = Py_True;
3741 Py_INCREF(result);
3742 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003743 else {
3744 PyErr_SetString(PyExc_TypeError,
3745 "can't compare offset-naive and "
3746 "offset-aware times");
3747 }
3748 done:
3749 Py_DECREF(offset1);
3750 Py_XDECREF(offset2);
3751 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003752}
3753
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003754static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003755time_hash(PyDateTime_Time *self)
3756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003757 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003758 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003759
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003760 offset = time_utcoffset((PyObject *)self, NULL);
3761
3762 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003763 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003765 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003766 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003767 self->hashcode = generic_hash(
3768 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003769 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003770 PyObject *temp1, *temp2;
3771 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003772 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003773 seconds = TIME_GET_HOUR(self) * 3600 +
3774 TIME_GET_MINUTE(self) * 60 +
3775 TIME_GET_SECOND(self);
3776 microseconds = TIME_GET_MICROSECOND(self);
3777 temp1 = new_delta(0, seconds, microseconds, 1);
3778 if (temp1 == NULL) {
3779 Py_DECREF(offset);
3780 return -1;
3781 }
3782 temp2 = delta_subtract(temp1, offset);
3783 Py_DECREF(temp1);
3784 if (temp2 == NULL) {
3785 Py_DECREF(offset);
3786 return -1;
3787 }
3788 self->hashcode = PyObject_Hash(temp2);
3789 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003790 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003791 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003792 }
3793 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003794}
Tim Peters2a799bf2002-12-16 20:18:38 +00003795
Tim Peters12bf3392002-12-24 05:41:27 +00003796static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003797time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003799 PyObject *clone;
3800 PyObject *tuple;
3801 int hh = TIME_GET_HOUR(self);
3802 int mm = TIME_GET_MINUTE(self);
3803 int ss = TIME_GET_SECOND(self);
3804 int us = TIME_GET_MICROSECOND(self);
3805 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003807 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3808 time_kws,
3809 &hh, &mm, &ss, &us, &tzinfo))
3810 return NULL;
3811 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3812 if (tuple == NULL)
3813 return NULL;
3814 clone = time_new(Py_TYPE(self), tuple, NULL);
3815 Py_DECREF(tuple);
3816 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003817}
3818
Tim Peters371935f2003-02-01 01:52:50 +00003819/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003820
Tim Peters33e0f382003-01-10 02:05:14 +00003821/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003822 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3823 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003824 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003825 */
3826static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003827time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003829 PyObject *basestate;
3830 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003832 basestate = PyBytes_FromStringAndSize((char *)self->data,
3833 _PyDateTime_TIME_DATASIZE);
3834 if (basestate != NULL) {
3835 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3836 result = PyTuple_Pack(1, basestate);
3837 else
3838 result = PyTuple_Pack(2, basestate, self->tzinfo);
3839 Py_DECREF(basestate);
3840 }
3841 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003842}
3843
3844static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003845time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003847 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003848}
3849
Tim Peters37f39822003-01-10 03:49:02 +00003850static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003852 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3853 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3854 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003856 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3857 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003859 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3860 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003862 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3863 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003865 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3866 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003868 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3869 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003871 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3872 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003874 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3875 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003877 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003878};
3879
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003880static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003881PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3882\n\
3883All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03003884a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003885
Neal Norwitz227b5332006-03-22 09:28:35 +00003886static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003887 PyVarObject_HEAD_INIT(NULL, 0)
3888 "datetime.time", /* tp_name */
3889 sizeof(PyDateTime_Time), /* tp_basicsize */
3890 0, /* tp_itemsize */
3891 (destructor)time_dealloc, /* tp_dealloc */
3892 0, /* tp_print */
3893 0, /* tp_getattr */
3894 0, /* tp_setattr */
3895 0, /* tp_reserved */
3896 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05003897 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003898 0, /* tp_as_sequence */
3899 0, /* tp_as_mapping */
3900 (hashfunc)time_hash, /* tp_hash */
3901 0, /* tp_call */
3902 (reprfunc)time_str, /* tp_str */
3903 PyObject_GenericGetAttr, /* tp_getattro */
3904 0, /* tp_setattro */
3905 0, /* tp_as_buffer */
3906 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3907 time_doc, /* tp_doc */
3908 0, /* tp_traverse */
3909 0, /* tp_clear */
3910 time_richcompare, /* tp_richcompare */
3911 0, /* tp_weaklistoffset */
3912 0, /* tp_iter */
3913 0, /* tp_iternext */
3914 time_methods, /* tp_methods */
3915 0, /* tp_members */
3916 time_getset, /* tp_getset */
3917 0, /* tp_base */
3918 0, /* tp_dict */
3919 0, /* tp_descr_get */
3920 0, /* tp_descr_set */
3921 0, /* tp_dictoffset */
3922 0, /* tp_init */
3923 time_alloc, /* tp_alloc */
3924 time_new, /* tp_new */
3925 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003926};
3927
3928/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003929 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003930 */
3931
Tim Petersa9bc1682003-01-11 03:39:11 +00003932/* Accessor properties. Properties for day, month, and year are inherited
3933 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003934 */
3935
3936static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003937datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003938{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003939 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003940}
3941
Tim Petersa9bc1682003-01-11 03:39:11 +00003942static PyObject *
3943datetime_minute(PyDateTime_DateTime *self, void *unused)
3944{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003945 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003946}
3947
3948static PyObject *
3949datetime_second(PyDateTime_DateTime *self, void *unused)
3950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003951 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003952}
3953
3954static PyObject *
3955datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003957 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003958}
3959
3960static PyObject *
3961datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003963 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3964 Py_INCREF(result);
3965 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003966}
3967
3968static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003969 {"hour", (getter)datetime_hour},
3970 {"minute", (getter)datetime_minute},
3971 {"second", (getter)datetime_second},
3972 {"microsecond", (getter)datetime_microsecond},
3973 {"tzinfo", (getter)datetime_tzinfo},
3974 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003975};
3976
3977/*
3978 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003979 */
3980
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003981static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003982 "year", "month", "day", "hour", "minute", "second",
3983 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003984};
3985
Tim Peters2a799bf2002-12-16 20:18:38 +00003986static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003987datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003988{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003989 PyObject *self = NULL;
3990 PyObject *state;
3991 int year;
3992 int month;
3993 int day;
3994 int hour = 0;
3995 int minute = 0;
3996 int second = 0;
3997 int usecond = 0;
3998 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004000 /* Check for invocation from pickle with __getstate__ state */
4001 if (PyTuple_GET_SIZE(args) >= 1 &&
4002 PyTuple_GET_SIZE(args) <= 2 &&
4003 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4004 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4005 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4006 {
4007 PyDateTime_DateTime *me;
4008 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004010 if (PyTuple_GET_SIZE(args) == 2) {
4011 tzinfo = PyTuple_GET_ITEM(args, 1);
4012 if (check_tzinfo_subclass(tzinfo) < 0) {
4013 PyErr_SetString(PyExc_TypeError, "bad "
4014 "tzinfo state arg");
4015 return NULL;
4016 }
4017 }
4018 aware = (char)(tzinfo != Py_None);
4019 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4020 if (me != NULL) {
4021 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004023 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4024 me->hashcode = -1;
4025 me->hastzinfo = aware;
4026 if (aware) {
4027 Py_INCREF(tzinfo);
4028 me->tzinfo = tzinfo;
4029 }
4030 }
4031 return (PyObject *)me;
4032 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004034 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4035 &year, &month, &day, &hour, &minute,
4036 &second, &usecond, &tzinfo)) {
4037 if (check_date_args(year, month, day) < 0)
4038 return NULL;
4039 if (check_time_args(hour, minute, second, usecond) < 0)
4040 return NULL;
4041 if (check_tzinfo_subclass(tzinfo) < 0)
4042 return NULL;
4043 self = new_datetime_ex(year, month, day,
4044 hour, minute, second, usecond,
4045 tzinfo, type);
4046 }
4047 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004048}
4049
Tim Petersa9bc1682003-01-11 03:39:11 +00004050/* TM_FUNC is the shared type of localtime() and gmtime(). */
4051typedef struct tm *(*TM_FUNC)(const time_t *timer);
4052
4053/* Internal helper.
4054 * Build datetime from a time_t and a distinct count of microseconds.
4055 * Pass localtime or gmtime for f, to control the interpretation of timet.
4056 */
4057static PyObject *
4058datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004059 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004060{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004061 struct tm *tm;
Tim Petersa9bc1682003-01-11 03:39:11 +00004062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004063 tm = f(&timet);
Victor Stinner21f58932012-03-14 00:15:40 +01004064 if (tm == NULL) {
4065#ifdef EINVAL
4066 if (errno == 0)
4067 errno = EINVAL;
4068#endif
4069 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004070 }
Victor Stinner21f58932012-03-14 00:15:40 +01004071
4072 /* The platform localtime/gmtime may insert leap seconds,
4073 * indicated by tm->tm_sec > 59. We don't care about them,
4074 * except to the extent that passing them on to the datetime
4075 * constructor would raise ValueError for a reason that
4076 * made no sense to the user.
4077 */
4078 if (tm->tm_sec > 59)
4079 tm->tm_sec = 59;
4080 return PyObject_CallFunction(cls, "iiiiiiiO",
4081 tm->tm_year + 1900,
4082 tm->tm_mon + 1,
4083 tm->tm_mday,
4084 tm->tm_hour,
4085 tm->tm_min,
4086 tm->tm_sec,
4087 us,
4088 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004089}
4090
4091/* Internal helper.
4092 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4093 * to control the interpretation of the timestamp. Since a double doesn't
4094 * have enough bits to cover a datetime's full range of precision, it's
4095 * better to call datetime_from_timet_and_us provided you have a way
4096 * to get that much precision (e.g., C time() isn't good enough).
4097 */
4098static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004099datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004100 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004103 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004104
Victor Stinnere4a994d2015-03-30 01:10:14 +02004105 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004106 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004107 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004108
Victor Stinner21f58932012-03-14 00:15:40 +01004109 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004110}
4111
4112/* Internal helper.
4113 * Build most accurate possible datetime for current time. Pass localtime or
4114 * gmtime for f as appropriate.
4115 */
4116static PyObject *
4117datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4118{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004119 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004120 time_t secs;
4121 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004122
Victor Stinner1e2b6882015-09-18 13:23:02 +02004123 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004124 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004125 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004126
Victor Stinner1e2b6882015-09-18 13:23:02 +02004127 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004128}
4129
Larry Hastings61272b72014-01-07 12:41:53 -08004130/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004131
4132@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004133datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004134
4135 tz: object = None
4136 Timezone object.
4137
4138Returns new datetime object representing current time local to tz.
4139
4140If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004141[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004142
Larry Hastings31826802013-10-19 00:09:25 -07004143static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004144datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004145/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004147 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004148
Larry Hastings31826802013-10-19 00:09:25 -07004149 /* Return best possible local time -- this isn't constrained by the
4150 * precision of a timestamp.
4151 */
4152 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004153 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004154
Larry Hastings5c661892014-01-24 06:17:25 -08004155 self = datetime_best_possible((PyObject *)type,
Larry Hastings31826802013-10-19 00:09:25 -07004156 tz == Py_None ? localtime : gmtime,
4157 tz);
4158 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004159 /* Convert UTC to tzinfo's zone. */
4160 PyObject *temp = self;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004161
Larry Hastings31826802013-10-19 00:09:25 -07004162 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004163 Py_DECREF(temp);
4164 }
4165 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004166}
4167
Tim Petersa9bc1682003-01-11 03:39:11 +00004168/* Return best possible UTC time -- this isn't constrained by the
4169 * precision of a timestamp.
4170 */
4171static PyObject *
4172datetime_utcnow(PyObject *cls, PyObject *dummy)
4173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004174 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004175}
4176
Tim Peters2a799bf2002-12-16 20:18:38 +00004177/* Return new local datetime from timestamp (Python timestamp -- a double). */
4178static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004179datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004181 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004182 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 PyObject *tzinfo = Py_None;
4184 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004185
Victor Stinner5d272cc2012-03-13 13:35:55 +01004186 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004187 keywords, &timestamp, &tzinfo))
4188 return NULL;
4189 if (check_tzinfo_subclass(tzinfo) < 0)
4190 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004192 self = datetime_from_timestamp(cls,
4193 tzinfo == Py_None ? localtime : gmtime,
4194 timestamp,
4195 tzinfo);
4196 if (self != NULL && tzinfo != Py_None) {
4197 /* Convert UTC to tzinfo's zone. */
4198 PyObject *temp = self;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004199
4200 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004201 Py_DECREF(temp);
4202 }
4203 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004204}
4205
Tim Petersa9bc1682003-01-11 03:39:11 +00004206/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4207static PyObject *
4208datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4209{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004210 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004211 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004212
Victor Stinner5d272cc2012-03-13 13:35:55 +01004213 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004214 result = datetime_from_timestamp(cls, gmtime, timestamp,
4215 Py_None);
4216 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004217}
4218
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004219/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004220static PyObject *
4221datetime_strptime(PyObject *cls, PyObject *args)
4222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004223 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004224 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004225 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004226
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004227 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004228 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004229
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004230 if (module == NULL) {
4231 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004232 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004233 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004235 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4236 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004237}
4238
Tim Petersa9bc1682003-01-11 03:39:11 +00004239/* Return new datetime from date/datetime and time arguments. */
4240static PyObject *
4241datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4242{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004243 static char *keywords[] = {"date", "time", NULL};
4244 PyObject *date;
4245 PyObject *time;
4246 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004248 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4249 &PyDateTime_DateType, &date,
4250 &PyDateTime_TimeType, &time)) {
4251 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004253 if (HASTZINFO(time))
4254 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4255 result = PyObject_CallFunction(cls, "iiiiiiiO",
4256 GET_YEAR(date),
4257 GET_MONTH(date),
4258 GET_DAY(date),
4259 TIME_GET_HOUR(time),
4260 TIME_GET_MINUTE(time),
4261 TIME_GET_SECOND(time),
4262 TIME_GET_MICROSECOND(time),
4263 tzinfo);
4264 }
4265 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004266}
Tim Peters2a799bf2002-12-16 20:18:38 +00004267
4268/*
4269 * Destructor.
4270 */
4271
4272static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004273datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004275 if (HASTZINFO(self)) {
4276 Py_XDECREF(self->tzinfo);
4277 }
4278 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004279}
4280
4281/*
4282 * Indirect access to tzinfo methods.
4283 */
4284
Tim Peters2a799bf2002-12-16 20:18:38 +00004285/* These are all METH_NOARGS, so don't need to check the arglist. */
4286static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004287datetime_utcoffset(PyObject *self, PyObject *unused) {
4288 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004289}
4290
4291static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004292datetime_dst(PyObject *self, PyObject *unused) {
4293 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004294}
4295
4296static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004297datetime_tzname(PyObject *self, PyObject *unused) {
4298 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004299}
4300
4301/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004302 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004303 */
4304
Tim Petersa9bc1682003-01-11 03:39:11 +00004305/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4306 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004307 */
4308static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004309add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004310 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004312 /* Note that the C-level additions can't overflow, because of
4313 * invariant bounds on the member values.
4314 */
4315 int year = GET_YEAR(date);
4316 int month = GET_MONTH(date);
4317 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4318 int hour = DATE_GET_HOUR(date);
4319 int minute = DATE_GET_MINUTE(date);
4320 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4321 int microsecond = DATE_GET_MICROSECOND(date) +
4322 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004324 assert(factor == 1 || factor == -1);
4325 if (normalize_datetime(&year, &month, &day,
4326 &hour, &minute, &second, &microsecond) < 0)
4327 return NULL;
4328 else
4329 return new_datetime(year, month, day,
4330 hour, minute, second, microsecond,
4331 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004332}
4333
4334static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004335datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004337 if (PyDateTime_Check(left)) {
4338 /* datetime + ??? */
4339 if (PyDelta_Check(right))
4340 /* datetime + delta */
4341 return add_datetime_timedelta(
4342 (PyDateTime_DateTime *)left,
4343 (PyDateTime_Delta *)right,
4344 1);
4345 }
4346 else if (PyDelta_Check(left)) {
4347 /* delta + datetime */
4348 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4349 (PyDateTime_Delta *) left,
4350 1);
4351 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004352 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004353}
4354
4355static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004356datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004358 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004360 if (PyDateTime_Check(left)) {
4361 /* datetime - ??? */
4362 if (PyDateTime_Check(right)) {
4363 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004364 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004365 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004366
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004367 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4368 offset2 = offset1 = Py_None;
4369 Py_INCREF(offset1);
4370 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004371 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004372 else {
4373 offset1 = datetime_utcoffset(left, NULL);
4374 if (offset1 == NULL)
4375 return NULL;
4376 offset2 = datetime_utcoffset(right, NULL);
4377 if (offset2 == NULL) {
4378 Py_DECREF(offset1);
4379 return NULL;
4380 }
4381 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4382 PyErr_SetString(PyExc_TypeError,
4383 "can't subtract offset-naive and "
4384 "offset-aware datetimes");
4385 Py_DECREF(offset1);
4386 Py_DECREF(offset2);
4387 return NULL;
4388 }
4389 }
4390 if ((offset1 != offset2) &&
4391 delta_cmp(offset1, offset2) != 0) {
4392 offdiff = delta_subtract(offset1, offset2);
4393 if (offdiff == NULL) {
4394 Py_DECREF(offset1);
4395 Py_DECREF(offset2);
4396 return NULL;
4397 }
4398 }
4399 Py_DECREF(offset1);
4400 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004401 delta_d = ymd_to_ord(GET_YEAR(left),
4402 GET_MONTH(left),
4403 GET_DAY(left)) -
4404 ymd_to_ord(GET_YEAR(right),
4405 GET_MONTH(right),
4406 GET_DAY(right));
4407 /* These can't overflow, since the values are
4408 * normalized. At most this gives the number of
4409 * seconds in one day.
4410 */
4411 delta_s = (DATE_GET_HOUR(left) -
4412 DATE_GET_HOUR(right)) * 3600 +
4413 (DATE_GET_MINUTE(left) -
4414 DATE_GET_MINUTE(right)) * 60 +
4415 (DATE_GET_SECOND(left) -
4416 DATE_GET_SECOND(right));
4417 delta_us = DATE_GET_MICROSECOND(left) -
4418 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004419 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004420 if (result == NULL)
4421 return NULL;
4422
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004423 if (offdiff != NULL) {
4424 PyObject *temp = result;
4425 result = delta_subtract(result, offdiff);
4426 Py_DECREF(temp);
4427 Py_DECREF(offdiff);
4428 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004429 }
4430 else if (PyDelta_Check(right)) {
4431 /* datetime - delta */
4432 result = add_datetime_timedelta(
4433 (PyDateTime_DateTime *)left,
4434 (PyDateTime_Delta *)right,
4435 -1);
4436 }
4437 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004439 if (result == Py_NotImplemented)
4440 Py_INCREF(result);
4441 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004442}
4443
4444/* Various ways to turn a datetime into a string. */
4445
4446static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004447datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004449 const char *type_name = Py_TYPE(self)->tp_name;
4450 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004452 if (DATE_GET_MICROSECOND(self)) {
4453 baserepr = PyUnicode_FromFormat(
4454 "%s(%d, %d, %d, %d, %d, %d, %d)",
4455 type_name,
4456 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4457 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4458 DATE_GET_SECOND(self),
4459 DATE_GET_MICROSECOND(self));
4460 }
4461 else if (DATE_GET_SECOND(self)) {
4462 baserepr = PyUnicode_FromFormat(
4463 "%s(%d, %d, %d, %d, %d, %d)",
4464 type_name,
4465 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4466 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4467 DATE_GET_SECOND(self));
4468 }
4469 else {
4470 baserepr = PyUnicode_FromFormat(
4471 "%s(%d, %d, %d, %d, %d)",
4472 type_name,
4473 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4474 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4475 }
4476 if (baserepr == NULL || ! HASTZINFO(self))
4477 return baserepr;
4478 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004479}
4480
Tim Petersa9bc1682003-01-11 03:39:11 +00004481static PyObject *
4482datetime_str(PyDateTime_DateTime *self)
4483{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004484 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004485}
Tim Peters2a799bf2002-12-16 20:18:38 +00004486
4487static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004488datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004490 int sep = 'T';
4491 static char *keywords[] = {"sep", NULL};
4492 char buffer[100];
4493 PyObject *result;
4494 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004496 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4497 return NULL;
4498 if (us)
4499 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4500 GET_YEAR(self), GET_MONTH(self),
4501 GET_DAY(self), (int)sep,
4502 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4503 DATE_GET_SECOND(self), us);
4504 else
4505 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4506 GET_YEAR(self), GET_MONTH(self),
4507 GET_DAY(self), (int)sep,
4508 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4509 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004511 if (!result || !HASTZINFO(self))
4512 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004514 /* We need to append the UTC offset. */
4515 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4516 (PyObject *)self) < 0) {
4517 Py_DECREF(result);
4518 return NULL;
4519 }
4520 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4521 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004522}
4523
Tim Petersa9bc1682003-01-11 03:39:11 +00004524static PyObject *
4525datetime_ctime(PyDateTime_DateTime *self)
4526{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004527 return format_ctime((PyDateTime_Date *)self,
4528 DATE_GET_HOUR(self),
4529 DATE_GET_MINUTE(self),
4530 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004531}
4532
Tim Peters2a799bf2002-12-16 20:18:38 +00004533/* Miscellaneous methods. */
4534
Tim Petersa9bc1682003-01-11 03:39:11 +00004535static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004536datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004537{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004538 PyObject *result = NULL;
4539 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004540 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004542 if (! PyDateTime_Check(other)) {
4543 if (PyDate_Check(other)) {
4544 /* Prevent invocation of date_richcompare. We want to
4545 return NotImplemented here to give the other object
4546 a chance. But since DateTime is a subclass of
4547 Date, if the other object is a Date, it would
4548 compute an ordering based on the date part alone,
4549 and we don't want that. So force unequal or
4550 uncomparable here in that case. */
4551 if (op == Py_EQ)
4552 Py_RETURN_FALSE;
4553 if (op == Py_NE)
4554 Py_RETURN_TRUE;
4555 return cmperror(self, other);
4556 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004557 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004558 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004559
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004560 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004561 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4562 ((PyDateTime_DateTime *)other)->data,
4563 _PyDateTime_DATETIME_DATASIZE);
4564 return diff_to_bool(diff, op);
4565 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004566 offset1 = datetime_utcoffset(self, NULL);
4567 if (offset1 == NULL)
4568 return NULL;
4569 offset2 = datetime_utcoffset(other, NULL);
4570 if (offset2 == NULL)
4571 goto done;
4572 /* If they're both naive, or both aware and have the same offsets,
4573 * we get off cheap. Note that if they're both naive, offset1 ==
4574 * offset2 == Py_None at this point.
4575 */
4576 if ((offset1 == offset2) ||
4577 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4578 delta_cmp(offset1, offset2) == 0)) {
4579 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4580 ((PyDateTime_DateTime *)other)->data,
4581 _PyDateTime_DATETIME_DATASIZE);
4582 result = diff_to_bool(diff, op);
4583 }
4584 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004585 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004586
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004587 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004588 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4589 other);
4590 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004591 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004592 diff = GET_TD_DAYS(delta);
4593 if (diff == 0)
4594 diff = GET_TD_SECONDS(delta) |
4595 GET_TD_MICROSECONDS(delta);
4596 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004597 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004598 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004599 else if (op == Py_EQ) {
4600 result = Py_False;
4601 Py_INCREF(result);
4602 }
4603 else if (op == Py_NE) {
4604 result = Py_True;
4605 Py_INCREF(result);
4606 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004607 else {
4608 PyErr_SetString(PyExc_TypeError,
4609 "can't compare offset-naive and "
4610 "offset-aware datetimes");
4611 }
4612 done:
4613 Py_DECREF(offset1);
4614 Py_XDECREF(offset2);
4615 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004616}
4617
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004618static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004619datetime_hash(PyDateTime_DateTime *self)
4620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004621 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004622 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004623
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004624 offset = datetime_utcoffset((PyObject *)self, NULL);
4625
4626 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004627 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004629 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004630 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 self->hashcode = generic_hash(
4632 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004633 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004634 PyObject *temp1, *temp2;
4635 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004637 assert(HASTZINFO(self));
4638 days = ymd_to_ord(GET_YEAR(self),
4639 GET_MONTH(self),
4640 GET_DAY(self));
4641 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004642 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004643 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004644 temp1 = new_delta(days, seconds,
4645 DATE_GET_MICROSECOND(self),
4646 1);
4647 if (temp1 == NULL) {
4648 Py_DECREF(offset);
4649 return -1;
4650 }
4651 temp2 = delta_subtract(temp1, offset);
4652 Py_DECREF(temp1);
4653 if (temp2 == NULL) {
4654 Py_DECREF(offset);
4655 return -1;
4656 }
4657 self->hashcode = PyObject_Hash(temp2);
4658 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004659 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004660 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004661 }
4662 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004663}
Tim Peters2a799bf2002-12-16 20:18:38 +00004664
4665static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004666datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004667{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004668 PyObject *clone;
4669 PyObject *tuple;
4670 int y = GET_YEAR(self);
4671 int m = GET_MONTH(self);
4672 int d = GET_DAY(self);
4673 int hh = DATE_GET_HOUR(self);
4674 int mm = DATE_GET_MINUTE(self);
4675 int ss = DATE_GET_SECOND(self);
4676 int us = DATE_GET_MICROSECOND(self);
4677 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004679 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4680 datetime_kws,
4681 &y, &m, &d, &hh, &mm, &ss, &us,
4682 &tzinfo))
4683 return NULL;
4684 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4685 if (tuple == NULL)
4686 return NULL;
4687 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4688 Py_DECREF(tuple);
4689 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004690}
4691
4692static PyObject *
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004693local_timezone(PyDateTime_DateTime *utc_time)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004694{
4695 PyObject *result = NULL;
4696 struct tm *timep;
4697 time_t timestamp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004698 PyObject *delta;
4699 PyObject *one_second;
4700 PyObject *seconds;
4701 PyObject *nameo = NULL;
4702 const char *zone = NULL;
4703
4704 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
4705 if (delta == NULL)
4706 return NULL;
4707 one_second = new_delta(0, 1, 0, 0);
4708 if (one_second == NULL)
4709 goto error;
4710 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
4711 (PyDateTime_Delta *)one_second);
4712 Py_DECREF(one_second);
4713 if (seconds == NULL)
4714 goto error;
4715 Py_DECREF(delta);
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03004716 timestamp = _PyLong_AsTime_t(seconds);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004717 Py_DECREF(seconds);
4718 if (timestamp == -1 && PyErr_Occurred())
4719 return NULL;
4720 timep = localtime(&timestamp);
4721#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004722 zone = timep->tm_zone;
4723 delta = new_delta(0, timep->tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004724#else /* HAVE_STRUCT_TM_TM_ZONE */
4725 {
4726 PyObject *local_time;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004727 local_time = new_datetime(timep->tm_year + 1900, timep->tm_mon + 1,
4728 timep->tm_mday, timep->tm_hour, timep->tm_min,
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004729 timep->tm_sec, DATE_GET_MICROSECOND(utc_time),
4730 utc_time->tzinfo);
4731 if (local_time == NULL)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004732 goto error;
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004733 delta = datetime_subtract(local_time, (PyObject*)utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004734 /* XXX: before relying on tzname, we should compare delta
4735 to the offset implied by timezone/altzone */
4736 if (daylight && timep->tm_isdst >= 0)
4737 zone = tzname[timep->tm_isdst % 2];
4738 else
4739 zone = tzname[0];
4740 Py_DECREF(local_time);
4741 }
4742#endif /* HAVE_STRUCT_TM_TM_ZONE */
4743 if (zone != NULL) {
4744 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
4745 if (nameo == NULL)
4746 goto error;
4747 }
4748 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02004749 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004750 error:
4751 Py_DECREF(delta);
4752 return result;
4753}
4754
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004755static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00004756datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004757{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004758 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004759 PyObject *offset;
4760 PyObject *temp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004761 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004762 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004763
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004764 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07004765 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004766 return NULL;
4767
4768 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004769 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004771 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4772 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004774 /* Conversion to self's own time zone is a NOP. */
4775 if (self->tzinfo == tzinfo) {
4776 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004777 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004778 }
Tim Peters521fc152002-12-31 17:36:56 +00004779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004780 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004781 offset = datetime_utcoffset((PyObject *)self, NULL);
4782 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004783 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004784 if (offset == Py_None) {
4785 Py_DECREF(offset);
4786 NeedAware:
4787 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4788 "a naive datetime");
4789 return NULL;
4790 }
Tim Petersf3615152003-01-01 21:51:37 +00004791
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004792 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004793 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4794 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004795 Py_DECREF(offset);
4796 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004797 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004799 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004800 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004801 if (tzinfo == Py_None) {
4802 tzinfo = local_timezone(result);
4803 if (tzinfo == NULL) {
4804 Py_DECREF(result);
4805 return NULL;
4806 }
4807 }
4808 else
4809 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004810 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004811 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004812
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004813 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004814 result = (PyDateTime_DateTime *)
4815 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004816 Py_DECREF(temp);
4817
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004818 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004819}
4820
4821static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004822datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004824 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004826 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004827 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004828
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004829 dst = call_dst(self->tzinfo, (PyObject *)self);
4830 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004831 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004832
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004833 if (dst != Py_None)
4834 dstflag = delta_bool((PyDateTime_Delta *)dst);
4835 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004836 }
4837 return build_struct_time(GET_YEAR(self),
4838 GET_MONTH(self),
4839 GET_DAY(self),
4840 DATE_GET_HOUR(self),
4841 DATE_GET_MINUTE(self),
4842 DATE_GET_SECOND(self),
4843 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004844}
4845
4846static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04004847datetime_timestamp(PyDateTime_DateTime *self)
4848{
4849 PyObject *result;
4850
4851 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4852 PyObject *delta;
4853 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
4854 if (delta == NULL)
4855 return NULL;
4856 result = delta_total_seconds(delta);
4857 Py_DECREF(delta);
4858 }
4859 else {
4860 struct tm time;
4861 time_t timestamp;
4862 memset((void *) &time, '\0', sizeof(struct tm));
4863 time.tm_year = GET_YEAR(self) - 1900;
4864 time.tm_mon = GET_MONTH(self) - 1;
4865 time.tm_mday = GET_DAY(self);
4866 time.tm_hour = DATE_GET_HOUR(self);
4867 time.tm_min = DATE_GET_MINUTE(self);
4868 time.tm_sec = DATE_GET_SECOND(self);
4869 time.tm_wday = -1;
4870 time.tm_isdst = -1;
4871 timestamp = mktime(&time);
Victor Stinner93037492013-06-25 22:54:35 +02004872 if (timestamp == (time_t)(-1)
4873#ifndef _AIX
4874 /* Return value of -1 does not necessarily mean an error,
4875 * but tm_wday cannot remain set to -1 if mktime succeeded. */
4876 && time.tm_wday == -1
4877#else
4878 /* on AIX, tm_wday is always sets, even on error */
4879#endif
4880 )
4881 {
Alexander Belopolskya4415142012-06-08 12:33:09 -04004882 PyErr_SetString(PyExc_OverflowError,
4883 "timestamp out of range");
4884 return NULL;
4885 }
4886 result = PyFloat_FromDouble(timestamp + DATE_GET_MICROSECOND(self) / 1e6);
4887 }
4888 return result;
4889}
4890
4891static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004892datetime_getdate(PyDateTime_DateTime *self)
4893{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004894 return new_date(GET_YEAR(self),
4895 GET_MONTH(self),
4896 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004897}
4898
4899static PyObject *
4900datetime_gettime(PyDateTime_DateTime *self)
4901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004902 return new_time(DATE_GET_HOUR(self),
4903 DATE_GET_MINUTE(self),
4904 DATE_GET_SECOND(self),
4905 DATE_GET_MICROSECOND(self),
4906 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004907}
4908
4909static PyObject *
4910datetime_gettimetz(PyDateTime_DateTime *self)
4911{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004912 return new_time(DATE_GET_HOUR(self),
4913 DATE_GET_MINUTE(self),
4914 DATE_GET_SECOND(self),
4915 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004916 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004917}
4918
4919static PyObject *
4920datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004921{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004922 int y, m, d, hh, mm, ss;
4923 PyObject *tzinfo;
4924 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004925
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004926 tzinfo = GET_DT_TZINFO(self);
4927 if (tzinfo == Py_None) {
4928 utcself = self;
4929 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004930 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004931 else {
4932 PyObject *offset;
4933 offset = call_utcoffset(tzinfo, (PyObject *)self);
4934 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004935 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004936 if (offset == Py_None) {
4937 Py_DECREF(offset);
4938 utcself = self;
4939 Py_INCREF(utcself);
4940 }
4941 else {
4942 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4943 (PyDateTime_Delta *)offset, -1);
4944 Py_DECREF(offset);
4945 if (utcself == NULL)
4946 return NULL;
4947 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004948 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004949 y = GET_YEAR(utcself);
4950 m = GET_MONTH(utcself);
4951 d = GET_DAY(utcself);
4952 hh = DATE_GET_HOUR(utcself);
4953 mm = DATE_GET_MINUTE(utcself);
4954 ss = DATE_GET_SECOND(utcself);
4955
4956 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004957 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004958}
4959
Tim Peters371935f2003-02-01 01:52:50 +00004960/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004961
Tim Petersa9bc1682003-01-11 03:39:11 +00004962/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004963 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4964 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004965 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004966 */
4967static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004968datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004970 PyObject *basestate;
4971 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004973 basestate = PyBytes_FromStringAndSize((char *)self->data,
4974 _PyDateTime_DATETIME_DATASIZE);
4975 if (basestate != NULL) {
4976 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4977 result = PyTuple_Pack(1, basestate);
4978 else
4979 result = PyTuple_Pack(2, basestate, self->tzinfo);
4980 Py_DECREF(basestate);
4981 }
4982 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004983}
4984
4985static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004986datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004988 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004989}
4990
Tim Petersa9bc1682003-01-11 03:39:11 +00004991static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004993 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004994
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004995 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00004996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004997 {"utcnow", (PyCFunction)datetime_utcnow,
4998 METH_NOARGS | METH_CLASS,
4999 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005001 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5002 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5003 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005005 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5006 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005007 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005009 {"strptime", (PyCFunction)datetime_strptime,
5010 METH_VARARGS | METH_CLASS,
5011 PyDoc_STR("string, format -> new datetime parsed from a string "
5012 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005014 {"combine", (PyCFunction)datetime_combine,
5015 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5016 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005018 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005020 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5021 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005023 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5024 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005026 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5027 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005029 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5030 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005032 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5033 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005034
Alexander Belopolskya4415142012-06-08 12:33:09 -04005035 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5036 PyDoc_STR("Return POSIX timestamp as float.")},
5037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005038 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5039 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005041 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5042 PyDoc_STR("[sep] -> string in ISO 8601 format, "
5043 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
5044 "sep is used to separate the year from the time, and "
5045 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005047 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5048 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005050 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5051 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005053 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5054 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005056 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5057 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005059 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5060 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005062 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5063 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005065 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005066};
5067
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005068static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005069PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5070\n\
5071The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005072instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005073
Tim Petersa9bc1682003-01-11 03:39:11 +00005074static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005075 datetime_add, /* nb_add */
5076 datetime_subtract, /* nb_subtract */
5077 0, /* nb_multiply */
5078 0, /* nb_remainder */
5079 0, /* nb_divmod */
5080 0, /* nb_power */
5081 0, /* nb_negative */
5082 0, /* nb_positive */
5083 0, /* nb_absolute */
5084 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005085};
5086
Neal Norwitz227b5332006-03-22 09:28:35 +00005087static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005088 PyVarObject_HEAD_INIT(NULL, 0)
5089 "datetime.datetime", /* tp_name */
5090 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5091 0, /* tp_itemsize */
5092 (destructor)datetime_dealloc, /* tp_dealloc */
5093 0, /* tp_print */
5094 0, /* tp_getattr */
5095 0, /* tp_setattr */
5096 0, /* tp_reserved */
5097 (reprfunc)datetime_repr, /* tp_repr */
5098 &datetime_as_number, /* tp_as_number */
5099 0, /* tp_as_sequence */
5100 0, /* tp_as_mapping */
5101 (hashfunc)datetime_hash, /* tp_hash */
5102 0, /* tp_call */
5103 (reprfunc)datetime_str, /* tp_str */
5104 PyObject_GenericGetAttr, /* tp_getattro */
5105 0, /* tp_setattro */
5106 0, /* tp_as_buffer */
5107 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5108 datetime_doc, /* tp_doc */
5109 0, /* tp_traverse */
5110 0, /* tp_clear */
5111 datetime_richcompare, /* tp_richcompare */
5112 0, /* tp_weaklistoffset */
5113 0, /* tp_iter */
5114 0, /* tp_iternext */
5115 datetime_methods, /* tp_methods */
5116 0, /* tp_members */
5117 datetime_getset, /* tp_getset */
5118 &PyDateTime_DateType, /* tp_base */
5119 0, /* tp_dict */
5120 0, /* tp_descr_get */
5121 0, /* tp_descr_set */
5122 0, /* tp_dictoffset */
5123 0, /* tp_init */
5124 datetime_alloc, /* tp_alloc */
5125 datetime_new, /* tp_new */
5126 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005127};
5128
5129/* ---------------------------------------------------------------------------
5130 * Module methods and initialization.
5131 */
5132
5133static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005134 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005135};
5136
Tim Peters9ddf40b2004-06-20 22:41:32 +00005137/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5138 * datetime.h.
5139 */
5140static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005141 &PyDateTime_DateType,
5142 &PyDateTime_DateTimeType,
5143 &PyDateTime_TimeType,
5144 &PyDateTime_DeltaType,
5145 &PyDateTime_TZInfoType,
5146 new_date_ex,
5147 new_datetime_ex,
5148 new_time_ex,
5149 new_delta_ex,
5150 datetime_fromtimestamp,
5151 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005152};
5153
5154
Martin v. Löwis1a214512008-06-11 05:26:20 +00005155
5156static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005157 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005158 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005159 "Fast implementation of the datetime type.",
5160 -1,
5161 module_methods,
5162 NULL,
5163 NULL,
5164 NULL,
5165 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005166};
5167
Tim Peters2a799bf2002-12-16 20:18:38 +00005168PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005169PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005171 PyObject *m; /* a module object */
5172 PyObject *d; /* its dict */
5173 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005174 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005176 m = PyModule_Create(&datetimemodule);
5177 if (m == NULL)
5178 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005180 if (PyType_Ready(&PyDateTime_DateType) < 0)
5181 return NULL;
5182 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5183 return NULL;
5184 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5185 return NULL;
5186 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5187 return NULL;
5188 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5189 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005190 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5191 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005193 /* timedelta values */
5194 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005196 x = new_delta(0, 0, 1, 0);
5197 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5198 return NULL;
5199 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005201 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5202 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5203 return NULL;
5204 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005206 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5207 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5208 return NULL;
5209 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005211 /* date values */
5212 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005214 x = new_date(1, 1, 1);
5215 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5216 return NULL;
5217 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005219 x = new_date(MAXYEAR, 12, 31);
5220 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5221 return NULL;
5222 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005224 x = new_delta(1, 0, 0, 0);
5225 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5226 return NULL;
5227 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005229 /* time values */
5230 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005232 x = new_time(0, 0, 0, 0, Py_None);
5233 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5234 return NULL;
5235 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005237 x = new_time(23, 59, 59, 999999, Py_None);
5238 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5239 return NULL;
5240 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005242 x = new_delta(0, 0, 1, 0);
5243 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5244 return NULL;
5245 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005247 /* datetime values */
5248 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005250 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5251 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5252 return NULL;
5253 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005255 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5256 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5257 return NULL;
5258 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005260 x = new_delta(0, 0, 1, 0);
5261 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5262 return NULL;
5263 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005264
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005265 /* timezone values */
5266 d = PyDateTime_TimeZoneType.tp_dict;
5267
5268 delta = new_delta(0, 0, 0, 0);
5269 if (delta == NULL)
5270 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005271 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005272 Py_DECREF(delta);
5273 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5274 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005275 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005276
5277 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5278 if (delta == NULL)
5279 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005280 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005281 Py_DECREF(delta);
5282 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5283 return NULL;
5284 Py_DECREF(x);
5285
5286 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5287 if (delta == NULL)
5288 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005289 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005290 Py_DECREF(delta);
5291 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5292 return NULL;
5293 Py_DECREF(x);
5294
Alexander Belopolskya4415142012-06-08 12:33:09 -04005295 /* Epoch */
5296 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
5297 PyDateTime_TimeZone_UTC);
5298 if (PyDateTime_Epoch == NULL)
5299 return NULL;
5300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005301 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005302 PyModule_AddIntMacro(m, MINYEAR);
5303 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005305 Py_INCREF(&PyDateTime_DateType);
5306 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005308 Py_INCREF(&PyDateTime_DateTimeType);
5309 PyModule_AddObject(m, "datetime",
5310 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005312 Py_INCREF(&PyDateTime_TimeType);
5313 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005315 Py_INCREF(&PyDateTime_DeltaType);
5316 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005318 Py_INCREF(&PyDateTime_TZInfoType);
5319 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005320
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005321 Py_INCREF(&PyDateTime_TimeZoneType);
5322 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005324 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5325 if (x == NULL)
5326 return NULL;
5327 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005329 /* A 4-year cycle has an extra leap day over what we'd get from
5330 * pasting together 4 single years.
5331 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005332 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005333 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005335 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5336 * get from pasting together 4 100-year cycles.
5337 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005338 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005339 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005341 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5342 * pasting together 25 4-year cycles.
5343 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005344 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005345 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005346
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005347 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005348 us_per_ms = PyLong_FromLong(1000);
5349 us_per_second = PyLong_FromLong(1000000);
5350 us_per_minute = PyLong_FromLong(60000000);
5351 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005352 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005353 us_per_minute == NULL || seconds_per_day == NULL)
5354 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005356 /* The rest are too big for 32-bit ints, but even
5357 * us_per_week fits in 40 bits, so doubles should be exact.
5358 */
5359 us_per_hour = PyLong_FromDouble(3600000000.0);
5360 us_per_day = PyLong_FromDouble(86400000000.0);
5361 us_per_week = PyLong_FromDouble(604800000000.0);
5362 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5363 return NULL;
5364 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005365}
Tim Petersf3615152003-01-01 21:51:37 +00005366
5367/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005368Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005369 x.n = x stripped of its timezone -- its naive time.
5370 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005371 return None
Tim Petersf3615152003-01-01 21:51:37 +00005372 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005373 return None
Tim Petersf3615152003-01-01 21:51:37 +00005374 x.s = x's standard offset, x.o - x.d
5375
5376Now some derived rules, where k is a duration (timedelta).
5377
53781. x.o = x.s + x.d
5379 This follows from the definition of x.s.
5380
Tim Petersc5dc4da2003-01-02 17:55:03 +000053812. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005382 This is actually a requirement, an assumption we need to make about
5383 sane tzinfo classes.
5384
53853. The naive UTC time corresponding to x is x.n - x.o.
5386 This is again a requirement for a sane tzinfo class.
5387
53884. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005389 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005390
Tim Petersc5dc4da2003-01-02 17:55:03 +000053915. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005392 Again follows from how arithmetic is defined.
5393
Tim Peters8bb5ad22003-01-24 02:44:45 +00005394Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005395(meaning that the various tzinfo methods exist, and don't blow up or return
5396None when called).
5397
Tim Petersa9bc1682003-01-11 03:39:11 +00005398The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005399x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005400
5401By #3, we want
5402
Tim Peters8bb5ad22003-01-24 02:44:45 +00005403 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005404
5405The algorithm starts by attaching tz to x.n, and calling that y. So
5406x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5407becomes true; in effect, we want to solve [2] for k:
5408
Tim Peters8bb5ad22003-01-24 02:44:45 +00005409 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005410
5411By #1, this is the same as
5412
Tim Peters8bb5ad22003-01-24 02:44:45 +00005413 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005414
5415By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5416Substituting that into [3],
5417
Tim Peters8bb5ad22003-01-24 02:44:45 +00005418 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5419 k - (y+k).s - (y+k).d = 0; rearranging,
5420 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5421 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005422
Tim Peters8bb5ad22003-01-24 02:44:45 +00005423On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5424approximate k by ignoring the (y+k).d term at first. Note that k can't be
5425very large, since all offset-returning methods return a duration of magnitude
5426less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5427be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005428
5429In any case, the new value is
5430
Tim Peters8bb5ad22003-01-24 02:44:45 +00005431 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005432
Tim Peters8bb5ad22003-01-24 02:44:45 +00005433It's helpful to step back at look at [4] from a higher level: it's simply
5434mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005435
5436At this point, if
5437
Tim Peters8bb5ad22003-01-24 02:44:45 +00005438 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005439
5440we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005441at the start of daylight time. Picture US Eastern for concreteness. The wall
5442time 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 +00005443sense then. The docs ask that an Eastern tzinfo class consider such a time to
5444be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5445on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005446the only spelling that makes sense on the local wall clock.
5447
Tim Petersc5dc4da2003-01-02 17:55:03 +00005448In fact, if [5] holds at this point, we do have the standard-time spelling,
5449but that takes a bit of proof. We first prove a stronger result. What's the
5450difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005451
Tim Peters8bb5ad22003-01-24 02:44:45 +00005452 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005453
Tim Petersc5dc4da2003-01-02 17:55:03 +00005454Now
5455 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005456 (y + y.s).n = by #5
5457 y.n + y.s = since y.n = x.n
5458 x.n + y.s = since z and y are have the same tzinfo member,
5459 y.s = z.s by #2
5460 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005461
Tim Petersc5dc4da2003-01-02 17:55:03 +00005462Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005463
Tim Petersc5dc4da2003-01-02 17:55:03 +00005464 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005465 x.n - ((x.n + z.s) - z.o) = expanding
5466 x.n - x.n - z.s + z.o = cancelling
5467 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005468 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005469
Tim Petersc5dc4da2003-01-02 17:55:03 +00005470So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005471
Tim Petersc5dc4da2003-01-02 17:55:03 +00005472If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005473spelling we wanted in the endcase described above. We're done. Contrarily,
5474if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005475
Tim Petersc5dc4da2003-01-02 17:55:03 +00005476If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5477add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005478local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005479
Tim Petersc5dc4da2003-01-02 17:55:03 +00005480Let
Tim Petersf3615152003-01-01 21:51:37 +00005481
Tim Peters4fede1a2003-01-04 00:26:59 +00005482 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005483
Tim Peters4fede1a2003-01-04 00:26:59 +00005484and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005485
Tim Peters8bb5ad22003-01-24 02:44:45 +00005486 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005487
Tim Peters8bb5ad22003-01-24 02:44:45 +00005488If so, we're done. If not, the tzinfo class is insane, according to the
5489assumptions we've made. This also requires a bit of proof. As before, let's
5490compute the difference between the LHS and RHS of [8] (and skipping some of
5491the justifications for the kinds of substitutions we've done several times
5492already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005493
Tim Peters8bb5ad22003-01-24 02:44:45 +00005494 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005495 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5496 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5497 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5498 - z.n + z.n - z.o + z'.o = cancel z.n
5499 - z.o + z'.o = #1 twice
5500 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5501 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005502
5503So 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 +00005504we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5505return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005506
Tim Peters8bb5ad22003-01-24 02:44:45 +00005507How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5508a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5509would have to change the result dst() returns: we start in DST, and moving
5510a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005511
Tim Peters8bb5ad22003-01-24 02:44:45 +00005512There isn't a sane case where this can happen. The closest it gets is at
5513the end of DST, where there's an hour in UTC with no spelling in a hybrid
5514tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5515that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5516UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5517time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5518clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5519standard time. Since that's what the local clock *does*, we want to map both
5520UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005521in local time, but so it goes -- it's the way the local clock works.
5522
Tim Peters8bb5ad22003-01-24 02:44:45 +00005523When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5524so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5525z' = 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 +00005526(correctly) concludes that z' is not UTC-equivalent to x.
5527
5528Because we know z.d said z was in daylight time (else [5] would have held and
5529we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005530and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005531return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5532but the reasoning doesn't depend on the example -- it depends on there being
5533two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005534z' must be in standard time, and is the spelling we want in this case.
5535
5536Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5537concerned (because it takes z' as being in standard time rather than the
5538daylight time we intend here), but returning it gives the real-life "local
5539clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5540tz.
5541
5542When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5543the 1:MM standard time spelling we want.
5544
5545So how can this break? One of the assumptions must be violated. Two
5546possibilities:
5547
55481) [2] effectively says that y.s is invariant across all y belong to a given
5549 time zone. This isn't true if, for political reasons or continental drift,
5550 a region decides to change its base offset from UTC.
5551
55522) There may be versions of "double daylight" time where the tail end of
5553 the analysis gives up a step too early. I haven't thought about that
5554 enough to say.
5555
5556In any case, it's clear that the default fromutc() is strong enough to handle
5557"almost all" time zones: so long as the standard offset is invariant, it
5558doesn't matter if daylight time transition points change from year to year, or
5559if daylight time is skipped in some years; it doesn't matter how large or
5560small dst() may get within its bounds; and it doesn't even matter if some
5561perverse time zone returns a negative dst()). So a breaking case must be
5562pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005563--------------------------------------------------------------------------- */