blob: 91456e9506c2581ccbc59444839bd8530d510e2d [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
Tim Peters9ddf40b2004-06-20 22:41:32 +000010/* Differentiate between building the core module and building extension
11 * modules.
12 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000013#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000014#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000015#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000016#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000017#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000018
19/* We require that C int be at least 32 bits, and use int virtually
20 * everywhere. In just a few cases we use a temp long, where a Python
21 * API returns a C long. In such cases, we have to ensure that the
22 * final result fits in a C int (this can be an issue on 64-bit boxes).
23 */
24#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000025# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000026#endif
27
28#define MINYEAR 1
29#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000030#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000031
32/* Nine decimal digits is easy to communicate, and leaves enough room
33 * so that two delta days can be added w/o fear of overflowing a signed
34 * 32-bit int, and with plenty of room left over to absorb any possible
35 * carries from adding seconds.
36 */
37#define MAX_DELTA_DAYS 999999999
38
39/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040#define GET_YEAR PyDateTime_GET_YEAR
41#define GET_MONTH PyDateTime_GET_MONTH
42#define GET_DAY PyDateTime_GET_DAY
43#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
44#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
45#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
46#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000047
48/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
50 ((o)->data[1] = ((v) & 0x00ff)))
51#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
52#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000053
54/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000055#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
56#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
57#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
58#define DATE_SET_MICROSECOND(o, v) \
59 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
60 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
61 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000062
63/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
65#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
66#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
67#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
68#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
69#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
70#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
71#define TIME_SET_MICROSECOND(o, v) \
72 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
73 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
74 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000075
76/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
78#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
79#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081#define SET_TD_DAYS(o, v) ((o)->days = (v))
82#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000083#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
84
Tim Petersa032d2e2003-01-11 00:15:54 +000085/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
86 * p->hastzinfo.
87 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +000088#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
89#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
90 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
91#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
92 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +000093/* M is a char or int claiming to be a valid month. The macro is equivalent
94 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +000096 */
97#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
98
Tim Peters2a799bf2002-12-16 20:18:38 +000099/* Forward declarations. */
100static PyTypeObject PyDateTime_DateType;
101static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000102static PyTypeObject PyDateTime_DeltaType;
103static PyTypeObject PyDateTime_TimeType;
104static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000105static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000106
Martin v. Löwise75fc142013-11-07 18:46:53 +0100107_Py_IDENTIFIER(as_integer_ratio);
108_Py_IDENTIFIER(fromutc);
109_Py_IDENTIFIER(isoformat);
110_Py_IDENTIFIER(strftime);
111
Tim Peters2a799bf2002-12-16 20:18:38 +0000112/* ---------------------------------------------------------------------------
113 * Math utilities.
114 */
115
116/* k = i+j overflows iff k differs in sign from both inputs,
117 * iff k^i has sign bit set and k^j has sign bit set,
118 * iff (k^i)&(k^j) has sign bit set.
119 */
120#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000122
123/* Compute Python divmod(x, y), returning the quotient and storing the
124 * remainder into *r. The quotient is the floor of x/y, and that's
125 * the real point of this. C will probably truncate instead (C99
126 * requires truncation; C89 left it implementation-defined).
127 * Simplification: we *require* that y > 0 here. That's appropriate
128 * for all the uses made of it. This simplifies the code and makes
129 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
130 * overflow case).
131 */
132static int
133divmod(int x, int y, int *r)
134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 assert(y > 0);
138 quo = x / y;
139 *r = x - quo * y;
140 if (*r < 0) {
141 --quo;
142 *r += y;
143 }
144 assert(0 <= *r && *r < y);
145 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000146}
147
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000148/* Nearest integer to m / n for integers m and n. Half-integer results
149 * are rounded to even.
150 */
151static PyObject *
152divide_nearest(PyObject *m, PyObject *n)
153{
154 PyObject *result;
155 PyObject *temp;
156
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000157 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000158 if (temp == NULL)
159 return NULL;
160 result = PyTuple_GET_ITEM(temp, 0);
161 Py_INCREF(result);
162 Py_DECREF(temp);
163
164 return result;
165}
166
Tim Peters2a799bf2002-12-16 20:18:38 +0000167/* ---------------------------------------------------------------------------
168 * General calendrical helper functions
169 */
170
171/* For each month ordinal in 1..12, the number of days in that month,
172 * and the number of days before that month in the same year. These
173 * are correct for non-leap years only.
174 */
175static int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 0, /* unused; this vector uses 1-based indexing */
177 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000178};
179
180static int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 0, /* unused; this vector uses 1-based indexing */
182 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000183};
184
185/* year -> 1 if leap year, else 0. */
186static int
187is_leap(int year)
188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 /* Cast year to unsigned. The result is the same either way, but
190 * C can generate faster code for unsigned mod than for signed
191 * mod (especially for % 4 -- a good compiler should just grab
192 * the last 2 bits when the LHS is unsigned).
193 */
194 const unsigned int ayear = (unsigned int)year;
195 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000196}
197
198/* year, month -> number of days in that month in that year */
199static int
200days_in_month(int year, int month)
201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 assert(month >= 1);
203 assert(month <= 12);
204 if (month == 2 && is_leap(year))
205 return 29;
206 else
207 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000208}
209
210/* year, month -> number of days in year preceeding first day of month */
211static int
212days_before_month(int year, int month)
213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 assert(month >= 1);
217 assert(month <= 12);
218 days = _days_before_month[month];
219 if (month > 2 && is_leap(year))
220 ++days;
221 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000222}
223
224/* year -> number of days before January 1st of year. Remember that we
225 * start with year 1, so days_before_year(1) == 0.
226 */
227static int
228days_before_year(int year)
229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 int y = year - 1;
231 /* This is incorrect if year <= 0; we really want the floor
232 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000233 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000235 assert (year >= 1);
236 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000237}
238
239/* Number of days in 4, 100, and 400 year cycles. That these have
240 * the correct values is asserted in the module init function.
241 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242#define DI4Y 1461 /* days_before_year(5); days in 4 years */
243#define DI100Y 36524 /* days_before_year(101); days in 100 years */
244#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000245
246/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
247static void
248ord_to_ymd(int ordinal, int *year, int *month, int *day)
249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
253 * leap years repeats exactly every 400 years. The basic strategy is
254 * to find the closest 400-year boundary at or before ordinal, then
255 * work with the offset from that boundary to ordinal. Life is much
256 * clearer if we subtract 1 from ordinal first -- then the values
257 * of ordinal at 400-year boundaries are exactly those divisible
258 * by DI400Y:
259 *
260 * D M Y n n-1
261 * -- --- ---- ---------- ----------------
262 * 31 Dec -400 -DI400Y -DI400Y -1
263 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
264 * ...
265 * 30 Dec 000 -1 -2
266 * 31 Dec 000 0 -1
267 * 1 Jan 001 1 0 400-year boundary
268 * 2 Jan 001 2 1
269 * 3 Jan 001 3 2
270 * ...
271 * 31 Dec 400 DI400Y DI400Y -1
272 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
273 */
274 assert(ordinal >= 1);
275 --ordinal;
276 n400 = ordinal / DI400Y;
277 n = ordinal % DI400Y;
278 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 /* Now n is the (non-negative) offset, in days, from January 1 of
281 * year, to the desired date. Now compute how many 100-year cycles
282 * precede n.
283 * Note that it's possible for n100 to equal 4! In that case 4 full
284 * 100-year cycles precede the desired day, which implies the
285 * desired day is December 31 at the end of a 400-year cycle.
286 */
287 n100 = n / DI100Y;
288 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 /* Now compute how many 4-year cycles precede it. */
291 n4 = n / DI4Y;
292 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 /* And now how many single years. Again n1 can be 4, and again
295 * meaning that the desired day is December 31 at the end of the
296 * 4-year cycle.
297 */
298 n1 = n / 365;
299 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 *year += n100 * 100 + n4 * 4 + n1;
302 if (n1 == 4 || n100 == 4) {
303 assert(n == 0);
304 *year -= 1;
305 *month = 12;
306 *day = 31;
307 return;
308 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 /* Now the year is correct, and n is the offset from January 1. We
311 * find the month via an estimate that's either exact or one too
312 * large.
313 */
314 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
315 assert(leapyear == is_leap(*year));
316 *month = (n + 50) >> 5;
317 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
318 if (preceding > n) {
319 /* estimate is too large */
320 *month -= 1;
321 preceding -= days_in_month(*year, *month);
322 }
323 n -= preceding;
324 assert(0 <= n);
325 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000328}
329
330/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
331static int
332ymd_to_ord(int year, int month, int day)
333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000335}
336
337/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
338static int
339weekday(int year, int month, int day)
340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000342}
343
344/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
345 * first calendar week containing a Thursday.
346 */
347static int
348iso_week1_monday(int year)
349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
351 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
352 int first_weekday = (first_day + 6) % 7;
353 /* ordinal of closest Monday at or before 1/1 */
354 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
357 week1_monday += 7;
358 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000359}
360
361/* ---------------------------------------------------------------------------
362 * Range checkers.
363 */
364
365/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
366 * If not, raise OverflowError and return -1.
367 */
368static int
369check_delta_day_range(int days)
370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
372 return 0;
373 PyErr_Format(PyExc_OverflowError,
374 "days=%d; must have magnitude <= %d",
375 days, MAX_DELTA_DAYS);
376 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000377}
378
379/* Check that date arguments are in range. Return 0 if they are. If they
380 * aren't, raise ValueError and return -1.
381 */
382static int
383check_date_args(int year, int month, int day)
384{
385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 if (year < MINYEAR || year > MAXYEAR) {
387 PyErr_SetString(PyExc_ValueError,
388 "year is out of range");
389 return -1;
390 }
391 if (month < 1 || month > 12) {
392 PyErr_SetString(PyExc_ValueError,
393 "month must be in 1..12");
394 return -1;
395 }
396 if (day < 1 || day > days_in_month(year, month)) {
397 PyErr_SetString(PyExc_ValueError,
398 "day is out of range for month");
399 return -1;
400 }
401 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000402}
403
404/* Check that time arguments are in range. Return 0 if they are. If they
405 * aren't, raise ValueError and return -1.
406 */
407static int
408check_time_args(int h, int m, int s, int us)
409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 if (h < 0 || h > 23) {
411 PyErr_SetString(PyExc_ValueError,
412 "hour must be in 0..23");
413 return -1;
414 }
415 if (m < 0 || m > 59) {
416 PyErr_SetString(PyExc_ValueError,
417 "minute must be in 0..59");
418 return -1;
419 }
420 if (s < 0 || s > 59) {
421 PyErr_SetString(PyExc_ValueError,
422 "second must be in 0..59");
423 return -1;
424 }
425 if (us < 0 || us > 999999) {
426 PyErr_SetString(PyExc_ValueError,
427 "microsecond must be in 0..999999");
428 return -1;
429 }
430 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000431}
432
433/* ---------------------------------------------------------------------------
434 * Normalization utilities.
435 */
436
437/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
438 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
439 * at least factor, enough of *lo is converted into "hi" units so that
440 * 0 <= *lo < factor. The input values must be such that int overflow
441 * is impossible.
442 */
443static void
444normalize_pair(int *hi, int *lo, int factor)
445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 assert(factor > 0);
447 assert(lo != hi);
448 if (*lo < 0 || *lo >= factor) {
449 const int num_hi = divmod(*lo, factor, lo);
450 const int new_hi = *hi + num_hi;
451 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
452 *hi = new_hi;
453 }
454 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000455}
456
457/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 * 0 <= *s < 24*3600
459 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000460 * The input values must be such that the internals don't overflow.
461 * The way this routine is used, we don't get close.
462 */
463static void
464normalize_d_s_us(int *d, int *s, int *us)
465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 if (*us < 0 || *us >= 1000000) {
467 normalize_pair(s, us, 1000000);
468 /* |s| can't be bigger than about
469 * |original s| + |original us|/1000000 now.
470 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 }
473 if (*s < 0 || *s >= 24*3600) {
474 normalize_pair(d, s, 24*3600);
475 /* |d| can't be bigger than about
476 * |original d| +
477 * (|original s| + |original us|/1000000) / (24*3600) now.
478 */
479 }
480 assert(0 <= *s && *s < 24*3600);
481 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000482}
483
484/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 * 1 <= *m <= 12
486 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000487 * The input values must be such that the internals don't overflow.
488 * The way this routine is used, we don't get close.
489 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000490static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000491normalize_y_m_d(int *y, int *m, int *d)
492{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000494
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000495 /* In actual use, m is always the month component extracted from a
496 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 /* Now only day can be out of bounds (year may also be out of bounds
502 * for a datetime object, but we don't care about that here).
503 * If day is out of bounds, what to do is arguable, but at least the
504 * method here is principled and explainable.
505 */
506 dim = days_in_month(*y, *m);
507 if (*d < 1 || *d > dim) {
508 /* Move day-1 days from the first of the month. First try to
509 * get off cheap if we're only one day out of range
510 * (adjustments for timezone alone can't be worse than that).
511 */
512 if (*d == 0) {
513 --*m;
514 if (*m > 0)
515 *d = days_in_month(*y, *m);
516 else {
517 --*y;
518 *m = 12;
519 *d = 31;
520 }
521 }
522 else if (*d == dim + 1) {
523 /* move forward a day */
524 ++*m;
525 *d = 1;
526 if (*m > 12) {
527 *m = 1;
528 ++*y;
529 }
530 }
531 else {
532 int ordinal = ymd_to_ord(*y, *m, 1) +
533 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000534 if (ordinal < 1 || ordinal > MAXORDINAL) {
535 goto error;
536 } else {
537 ord_to_ymd(ordinal, y, m, d);
538 return 0;
539 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 }
541 }
542 assert(*m > 0);
543 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000544 if (MINYEAR <= *y && *y <= MAXYEAR)
545 return 0;
546 error:
547 PyErr_SetString(PyExc_OverflowError,
548 "date value out of range");
549 return -1;
550
Tim Peters2a799bf2002-12-16 20:18:38 +0000551}
552
553/* Fiddle out-of-bounds months and days so that the result makes some kind
554 * of sense. The parameters are both inputs and outputs. Returns < 0 on
555 * failure, where failure means the adjusted year is out of bounds.
556 */
557static int
558normalize_date(int *year, int *month, int *day)
559{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000560 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000561}
562
563/* Force all the datetime fields into range. The parameters are both
564 * inputs and outputs. Returns < 0 on error.
565 */
566static int
567normalize_datetime(int *year, int *month, int *day,
568 int *hour, int *minute, int *second,
569 int *microsecond)
570{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 normalize_pair(second, microsecond, 1000000);
572 normalize_pair(minute, second, 60);
573 normalize_pair(hour, minute, 60);
574 normalize_pair(day, hour, 24);
575 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000576}
577
578/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000579 * Basic object allocation: tp_alloc implementations. These allocate
580 * Python objects of the right size and type, and do the Python object-
581 * initialization bit. If there's not enough memory, they return NULL after
582 * setting MemoryError. All data members remain uninitialized trash.
583 *
584 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000585 * member is needed. This is ugly, imprecise, and possibly insecure.
586 * tp_basicsize for the time and datetime types is set to the size of the
587 * struct that has room for the tzinfo member, so subclasses in Python will
588 * allocate enough space for a tzinfo member whether or not one is actually
589 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
590 * part is that PyType_GenericAlloc() (which subclasses in Python end up
591 * using) just happens today to effectively ignore the nitems argument
592 * when tp_itemsize is 0, which it is for these type objects. If that
593 * changes, perhaps the callers of tp_alloc slots in this file should
594 * be changed to force a 0 nitems argument unless the type being allocated
595 * is a base type implemented in this file (so that tp_alloc is time_alloc
596 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000597 */
598
599static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000600time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000601{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 self = (PyObject *)
605 PyObject_MALLOC(aware ?
606 sizeof(PyDateTime_Time) :
607 sizeof(_PyDateTime_BaseTime));
608 if (self == NULL)
609 return (PyObject *)PyErr_NoMemory();
610 PyObject_INIT(self, type);
611 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000612}
613
614static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000615datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 self = (PyObject *)
620 PyObject_MALLOC(aware ?
621 sizeof(PyDateTime_DateTime) :
622 sizeof(_PyDateTime_BaseDateTime));
623 if (self == NULL)
624 return (PyObject *)PyErr_NoMemory();
625 PyObject_INIT(self, type);
626 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000627}
628
629/* ---------------------------------------------------------------------------
630 * Helpers for setting object fields. These work on pointers to the
631 * appropriate base class.
632 */
633
634/* For date and datetime. */
635static void
636set_date_fields(PyDateTime_Date *self, int y, int m, int d)
637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 self->hashcode = -1;
639 SET_YEAR(self, y);
640 SET_MONTH(self, m);
641 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000642}
643
644/* ---------------------------------------------------------------------------
645 * Create various objects, mostly without range checking.
646 */
647
648/* Create a date instance with no range checking. */
649static PyObject *
650new_date_ex(int year, int month, int day, PyTypeObject *type)
651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
655 if (self != NULL)
656 set_date_fields(self, year, month, day);
657 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000658}
659
660#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000662
663/* Create a datetime instance with no range checking. */
664static PyObject *
665new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000667{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 PyDateTime_DateTime *self;
669 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
672 if (self != NULL) {
673 self->hastzinfo = aware;
674 set_date_fields((PyDateTime_Date *)self, year, month, day);
675 DATE_SET_HOUR(self, hour);
676 DATE_SET_MINUTE(self, minute);
677 DATE_SET_SECOND(self, second);
678 DATE_SET_MICROSECOND(self, usecond);
679 if (aware) {
680 Py_INCREF(tzinfo);
681 self->tzinfo = tzinfo;
682 }
683 }
684 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000685}
686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
688 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
689 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000690
691/* Create a time instance with no range checking. */
692static PyObject *
693new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000695{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 PyDateTime_Time *self;
697 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
700 if (self != NULL) {
701 self->hastzinfo = aware;
702 self->hashcode = -1;
703 TIME_SET_HOUR(self, hour);
704 TIME_SET_MINUTE(self, minute);
705 TIME_SET_SECOND(self, second);
706 TIME_SET_MICROSECOND(self, usecond);
707 if (aware) {
708 Py_INCREF(tzinfo);
709 self->tzinfo = tzinfo;
710 }
711 }
712 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000713}
714
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715#define new_time(hh, mm, ss, us, tzinfo) \
716 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000717
718/* Create a timedelta instance. Normalize the members iff normalize is
719 * true. Passing false is a speed optimization, if you know for sure
720 * that seconds and microseconds are already in their proper ranges. In any
721 * case, raises OverflowError and returns NULL if the normalized days is out
722 * of range).
723 */
724static PyObject *
725new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 if (normalize)
731 normalize_d_s_us(&days, &seconds, &microseconds);
732 assert(0 <= seconds && seconds < 24*3600);
733 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 if (check_delta_day_range(days) < 0)
736 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
739 if (self != NULL) {
740 self->hashcode = -1;
741 SET_TD_DAYS(self, days);
742 SET_TD_SECONDS(self, seconds);
743 SET_TD_MICROSECONDS(self, microseconds);
744 }
745 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000746}
747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748#define new_delta(d, s, us, normalize) \
749 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000750
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000751
752typedef struct
753{
754 PyObject_HEAD
755 PyObject *offset;
756 PyObject *name;
757} PyDateTime_TimeZone;
758
Victor Stinner6ced7c42011-03-21 18:15:42 +0100759/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000760static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -0400761/* The interned Epoch datetime instance */
762static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000763
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000764/* Create new timezone instance checking offset range. This
765 function does not check the name argument. Caller must assure
766 that offset is a timedelta instance and name is either NULL
767 or a unicode object. */
768static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000769create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000770{
771 PyDateTime_TimeZone *self;
772 PyTypeObject *type = &PyDateTime_TimeZoneType;
773
774 assert(offset != NULL);
775 assert(PyDelta_Check(offset));
776 assert(name == NULL || PyUnicode_Check(name));
777
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000778 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
779 if (self == NULL) {
780 return NULL;
781 }
782 Py_INCREF(offset);
783 self->offset = offset;
784 Py_XINCREF(name);
785 self->name = name;
786 return (PyObject *)self;
787}
788
789static int delta_bool(PyDateTime_Delta *self);
790
791static PyObject *
792new_timezone(PyObject *offset, PyObject *name)
793{
794 assert(offset != NULL);
795 assert(PyDelta_Check(offset));
796 assert(name == NULL || PyUnicode_Check(name));
797
798 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
799 Py_INCREF(PyDateTime_TimeZone_UTC);
800 return PyDateTime_TimeZone_UTC;
801 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000802 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
803 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400804 " representing a whole number of minutes,"
805 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000806 return NULL;
807 }
808 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
809 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
810 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
811 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400812 " timedelta(hours=24),"
813 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000814 return NULL;
815 }
816
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000817 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000818}
819
Tim Petersb0c854d2003-05-17 15:57:00 +0000820/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000821 * tzinfo helpers.
822 */
823
Tim Peters855fe882002-12-22 03:43:39 +0000824/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
825 * raise TypeError and return -1.
826 */
827static int
828check_tzinfo_subclass(PyObject *p)
829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 if (p == Py_None || PyTZInfo_Check(p))
831 return 0;
832 PyErr_Format(PyExc_TypeError,
833 "tzinfo argument must be None or of a tzinfo subclass, "
834 "not type '%s'",
835 Py_TYPE(p)->tp_name);
836 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000837}
838
Tim Peters2a799bf2002-12-16 20:18:38 +0000839/* If self has a tzinfo member, return a BORROWED reference to it. Else
840 * return NULL, which is NOT AN ERROR. There are no error returns here,
841 * and the caller must not decref the result.
842 */
843static PyObject *
844get_tzinfo_member(PyObject *self)
845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 if (PyDateTime_Check(self) && HASTZINFO(self))
849 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
850 else if (PyTime_Check(self) && HASTZINFO(self))
851 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000854}
855
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000856/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
857 * be an instance of the tzinfo class. If the method returns None, this
858 * returns None. If the method doesn't return None or timedelta, TypeError is
859 * raised and this returns NULL. If it returns a timedelta and the value is
860 * out of range or isn't a whole number of minutes, ValueError is raised and
861 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000862 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000863static PyObject *
864call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000865{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000866 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000869 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000871
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000872 if (tzinfo == Py_None)
873 Py_RETURN_NONE;
874 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
875 if (offset == Py_None || offset == NULL)
876 return offset;
877 if (PyDelta_Check(offset)) {
878 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
879 Py_DECREF(offset);
880 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
881 " representing a whole number of minutes");
882 return NULL;
883 }
884 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
885 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
886 Py_DECREF(offset);
887 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
888 " strictly between -timedelta(hours=24) and"
889 " timedelta(hours=24).");
890 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 }
892 }
893 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000894 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 PyErr_Format(PyExc_TypeError,
896 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000897 "timedelta, not '%.200s'",
898 name, Py_TYPE(offset)->tp_name);
899 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000901
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000902 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000903}
904
905/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
906 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
907 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000908 * doesn't return None or timedelta, TypeError is raised and this returns -1.
909 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
910 * # of minutes), ValueError is raised and this returns -1. Else *none is
911 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000912 */
Tim Peters855fe882002-12-22 03:43:39 +0000913static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000914call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
915{
916 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000917}
918
Tim Peters2a799bf2002-12-16 20:18:38 +0000919/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
920 * result. tzinfo must be an instance of the tzinfo class. If dst()
921 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000922 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000923 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000924 * ValueError is raised and this returns -1. Else *none is set to 0 and
925 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000926 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000927static PyObject *
928call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000929{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000930 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000931}
932
Tim Petersbad8ff02002-12-30 20:52:32 +0000933/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000934 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000935 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000936 * returns NULL. If the result is a string, we ensure it is a Unicode
937 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000938 */
939static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000940call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000941{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200943 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 assert(tzinfo != NULL);
946 assert(check_tzinfo_subclass(tzinfo) >= 0);
947 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000950 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000951
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200952 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000953
954 if (result == NULL || result == Py_None)
955 return result;
956
957 if (!PyUnicode_Check(result)) {
958 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
959 "return None or a string, not '%s'",
960 Py_TYPE(result)->tp_name);
961 Py_DECREF(result);
962 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000964
965 return result;
Tim Peters00237032002-12-27 02:21:51 +0000966}
967
Tim Peters2a799bf2002-12-16 20:18:38 +0000968/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
969 * stuff
970 * ", tzinfo=" + repr(tzinfo)
971 * before the closing ")".
972 */
973static PyObject *
974append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 assert(PyUnicode_Check(repr));
979 assert(tzinfo);
980 if (tzinfo == Py_None)
981 return repr;
982 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200983 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
984 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 Py_DECREF(repr);
986 if (temp == NULL)
987 return NULL;
988 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
989 Py_DECREF(temp);
990 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +0000991}
992
993/* ---------------------------------------------------------------------------
994 * String format helpers.
995 */
996
997static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +0000998format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000999{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 static const char *DayNames[] = {
1001 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1002 };
1003 static const char *MonthNames[] = {
1004 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1005 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1006 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1011 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1012 GET_DAY(date), hours, minutes, seconds,
1013 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001014}
1015
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001016static PyObject *delta_negative(PyDateTime_Delta *self);
1017
Tim Peters2a799bf2002-12-16 20:18:38 +00001018/* Add an hours & minutes UTC offset string to buf. buf has no more than
1019 * buflen bytes remaining. The UTC offset is gotten by calling
1020 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1021 * *buf, and that's all. Else the returned value is checked for sanity (an
1022 * integer in range), and if that's OK it's converted to an hours & minutes
1023 * string of the form
1024 * sign HH sep MM
1025 * Returns 0 if everything is OK. If the return value from utcoffset() is
1026 * bogus, an appropriate exception is set and -1 is returned.
1027 */
1028static int
Tim Peters328fff72002-12-20 01:31:27 +00001029format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001031{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001032 PyObject *offset;
1033 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001037
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001038 offset = call_utcoffset(tzinfo, tzinfoarg);
1039 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001041 if (offset == Py_None) {
1042 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 *buf = '\0';
1044 return 0;
1045 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001046 /* Offset is normalized, so it is negative if days < 0 */
1047 if (GET_TD_DAYS(offset) < 0) {
1048 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001050 offset = delta_negative((PyDateTime_Delta *)offset);
1051 Py_DECREF(temp);
1052 if (offset == NULL)
1053 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001055 else {
1056 sign = '+';
1057 }
1058 /* Offset is not negative here. */
1059 seconds = GET_TD_SECONDS(offset);
1060 Py_DECREF(offset);
1061 minutes = divmod(seconds, 60, &seconds);
1062 hours = divmod(minutes, 60, &minutes);
1063 assert(seconds == 0);
1064 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001068}
1069
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001070static PyObject *
1071make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 PyObject *temp;
1074 PyObject *tzinfo = get_tzinfo_member(object);
1075 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001076 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 if (Zreplacement == NULL)
1079 return NULL;
1080 if (tzinfo == Py_None || tzinfo == NULL)
1081 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 assert(tzinfoarg != NULL);
1084 temp = call_tzname(tzinfo, tzinfoarg);
1085 if (temp == NULL)
1086 goto Error;
1087 if (temp == Py_None) {
1088 Py_DECREF(temp);
1089 return Zreplacement;
1090 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 assert(PyUnicode_Check(temp));
1093 /* Since the tzname is getting stuffed into the
1094 * format, we have to double any % signs so that
1095 * strftime doesn't treat them as format codes.
1096 */
1097 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001098 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 Py_DECREF(temp);
1100 if (Zreplacement == NULL)
1101 return NULL;
1102 if (!PyUnicode_Check(Zreplacement)) {
1103 PyErr_SetString(PyExc_TypeError,
1104 "tzname.replace() did not return a string");
1105 goto Error;
1106 }
1107 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001108
1109 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 Py_DECREF(Zreplacement);
1111 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001112}
1113
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001114static PyObject *
1115make_freplacement(PyObject *object)
1116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 char freplacement[64];
1118 if (PyTime_Check(object))
1119 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1120 else if (PyDateTime_Check(object))
1121 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1122 else
1123 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001126}
1127
Tim Peters2a799bf2002-12-16 20:18:38 +00001128/* I sure don't want to reproduce the strftime code from the time module,
1129 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001130 * giving special meanings to the %z, %Z and %f format codes via a
1131 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001132 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1133 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001134 */
1135static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001136wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001138{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1142 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1143 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 const char *pin; /* pointer to next char in input format */
1146 Py_ssize_t flen; /* length of input format */
1147 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 PyObject *newfmt = NULL; /* py string, the output format */
1150 char *pnew; /* pointer to available byte in output format */
1151 size_t totalnew; /* number bytes total in output format buffer,
1152 exclusive of trailing \0 */
1153 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 const char *ptoappend; /* ptr to string to append to output buffer */
1156 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 assert(object && format && timetuple);
1159 assert(PyUnicode_Check(format));
1160 /* Convert the input format to a C string and size */
1161 pin = _PyUnicode_AsStringAndSize(format, &flen);
1162 if (!pin)
1163 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 /* Scan the input format, looking for %z/%Z/%f escapes, building
1166 * a new format. Since computing the replacements for those codes
1167 * is expensive, don't unless they're actually used.
1168 */
1169 if (flen > INT_MAX - 1) {
1170 PyErr_NoMemory();
1171 goto Done;
1172 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 totalnew = flen + 1; /* realistic if no %z/%Z */
1175 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1176 if (newfmt == NULL) goto Done;
1177 pnew = PyBytes_AsString(newfmt);
1178 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 while ((ch = *pin++) != '\0') {
1181 if (ch != '%') {
1182 ptoappend = pin - 1;
1183 ntoappend = 1;
1184 }
1185 else if ((ch = *pin++) == '\0') {
1186 /* There's a lone trailing %; doesn't make sense. */
1187 PyErr_SetString(PyExc_ValueError, "strftime format "
1188 "ends with raw %");
1189 goto Done;
1190 }
1191 /* A % has been seen and ch is the character after it. */
1192 else if (ch == 'z') {
1193 if (zreplacement == NULL) {
1194 /* format utcoffset */
1195 char buf[100];
1196 PyObject *tzinfo = get_tzinfo_member(object);
1197 zreplacement = PyBytes_FromStringAndSize("", 0);
1198 if (zreplacement == NULL) goto Done;
1199 if (tzinfo != Py_None && tzinfo != NULL) {
1200 assert(tzinfoarg != NULL);
1201 if (format_utcoffset(buf,
1202 sizeof(buf),
1203 "",
1204 tzinfo,
1205 tzinfoarg) < 0)
1206 goto Done;
1207 Py_DECREF(zreplacement);
1208 zreplacement =
1209 PyBytes_FromStringAndSize(buf,
1210 strlen(buf));
1211 if (zreplacement == NULL)
1212 goto Done;
1213 }
1214 }
1215 assert(zreplacement != NULL);
1216 ptoappend = PyBytes_AS_STRING(zreplacement);
1217 ntoappend = PyBytes_GET_SIZE(zreplacement);
1218 }
1219 else if (ch == 'Z') {
1220 /* format tzname */
1221 if (Zreplacement == NULL) {
1222 Zreplacement = make_Zreplacement(object,
1223 tzinfoarg);
1224 if (Zreplacement == NULL)
1225 goto Done;
1226 }
1227 assert(Zreplacement != NULL);
1228 assert(PyUnicode_Check(Zreplacement));
1229 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1230 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001231 if (ptoappend == NULL)
1232 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 }
1234 else if (ch == 'f') {
1235 /* format microseconds */
1236 if (freplacement == NULL) {
1237 freplacement = make_freplacement(object);
1238 if (freplacement == NULL)
1239 goto Done;
1240 }
1241 assert(freplacement != NULL);
1242 assert(PyBytes_Check(freplacement));
1243 ptoappend = PyBytes_AS_STRING(freplacement);
1244 ntoappend = PyBytes_GET_SIZE(freplacement);
1245 }
1246 else {
1247 /* percent followed by neither z nor Z */
1248 ptoappend = pin - 2;
1249 ntoappend = 2;
1250 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 /* Append the ntoappend chars starting at ptoappend to
1253 * the new format.
1254 */
1255 if (ntoappend == 0)
1256 continue;
1257 assert(ptoappend != NULL);
1258 assert(ntoappend > 0);
1259 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001260 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 PyErr_NoMemory();
1262 goto Done;
1263 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001264 totalnew <<= 1;
1265 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 pnew = PyBytes_AsString(newfmt) + usednew;
1268 }
1269 memcpy(pnew, ptoappend, ntoappend);
1270 pnew += ntoappend;
1271 usednew += ntoappend;
1272 assert(usednew <= totalnew);
1273 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1276 goto Done;
1277 {
1278 PyObject *format;
1279 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 if (time == NULL)
1282 goto Done;
1283 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1284 if (format != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001285 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1286 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 Py_DECREF(format);
1288 }
1289 Py_DECREF(time);
1290 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001291 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 Py_XDECREF(freplacement);
1293 Py_XDECREF(zreplacement);
1294 Py_XDECREF(Zreplacement);
1295 Py_XDECREF(newfmt);
1296 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001297}
1298
Tim Peters2a799bf2002-12-16 20:18:38 +00001299/* ---------------------------------------------------------------------------
1300 * Wrap functions from the time module. These aren't directly available
1301 * from C. Perhaps they should be.
1302 */
1303
1304/* Call time.time() and return its result (a Python float). */
1305static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001306time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 PyObject *result = NULL;
1309 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001312 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001313
1314 result = _PyObject_CallMethodId(time, &PyId_time, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 Py_DECREF(time);
1316 }
1317 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001318}
1319
1320/* Build a time.struct_time. The weekday and day number are automatically
1321 * computed from the y,m,d args.
1322 */
1323static PyObject *
1324build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 PyObject *time;
1327 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 time = PyImport_ImportModuleNoBlock("time");
1330 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001331 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001332
1333 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1334 "((iiiiiiiii))",
1335 y, m, d,
1336 hh, mm, ss,
1337 weekday(y, m, d),
1338 days_before_month(y, m) + d,
1339 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 Py_DECREF(time);
1341 }
1342 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001343}
1344
1345/* ---------------------------------------------------------------------------
1346 * Miscellaneous helpers.
1347 */
1348
Mark Dickinsone94c6792009-02-02 20:36:42 +00001349/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001350 * The comparisons here all most naturally compute a cmp()-like result.
1351 * This little helper turns that into a bool result for rich comparisons.
1352 */
1353static PyObject *
1354diff_to_bool(int diff, int op)
1355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 PyObject *result;
1357 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 switch (op) {
1360 case Py_EQ: istrue = diff == 0; break;
1361 case Py_NE: istrue = diff != 0; break;
1362 case Py_LE: istrue = diff <= 0; break;
1363 case Py_GE: istrue = diff >= 0; break;
1364 case Py_LT: istrue = diff < 0; break;
1365 case Py_GT: istrue = diff > 0; break;
1366 default:
1367 assert(! "op unknown");
1368 istrue = 0; /* To shut up compiler */
1369 }
1370 result = istrue ? Py_True : Py_False;
1371 Py_INCREF(result);
1372 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001373}
1374
Tim Peters07534a62003-02-07 22:50:28 +00001375/* Raises a "can't compare" TypeError and returns NULL. */
1376static PyObject *
1377cmperror(PyObject *a, PyObject *b)
1378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 PyErr_Format(PyExc_TypeError,
1380 "can't compare %s to %s",
1381 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1382 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001383}
1384
Tim Peters2a799bf2002-12-16 20:18:38 +00001385/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001386 * Cached Python objects; these are set by the module init function.
1387 */
1388
1389/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001390static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391static PyObject *us_per_ms = NULL; /* 1000 */
1392static PyObject *us_per_second = NULL; /* 1000000 */
1393static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001394static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1395static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1396static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001397static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1398
Tim Peters2a799bf2002-12-16 20:18:38 +00001399/* ---------------------------------------------------------------------------
1400 * Class implementations.
1401 */
1402
1403/*
1404 * PyDateTime_Delta implementation.
1405 */
1406
1407/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001409 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001410 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1411 * due to ubiquitous overflow possibilities.
1412 */
1413static PyObject *
1414delta_to_microseconds(PyDateTime_Delta *self)
1415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 PyObject *x1 = NULL;
1417 PyObject *x2 = NULL;
1418 PyObject *x3 = NULL;
1419 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1422 if (x1 == NULL)
1423 goto Done;
1424 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1425 if (x2 == NULL)
1426 goto Done;
1427 Py_DECREF(x1);
1428 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 /* x2 has days in seconds */
1431 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1432 if (x1 == NULL)
1433 goto Done;
1434 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1435 if (x3 == NULL)
1436 goto Done;
1437 Py_DECREF(x1);
1438 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001439 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 /* x3 has days+seconds in seconds */
1442 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1443 if (x1 == NULL)
1444 goto Done;
1445 Py_DECREF(x3);
1446 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 /* x1 has days+seconds in us */
1449 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1450 if (x2 == NULL)
1451 goto Done;
1452 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001453
1454Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 Py_XDECREF(x1);
1456 Py_XDECREF(x2);
1457 Py_XDECREF(x3);
1458 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001459}
1460
Serhiy Storchaka95949422013-08-27 19:40:23 +03001461/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001462 */
1463static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001464microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 int us;
1467 int s;
1468 int d;
1469 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 PyObject *tuple = NULL;
1472 PyObject *num = NULL;
1473 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 tuple = PyNumber_Divmod(pyus, us_per_second);
1476 if (tuple == NULL)
1477 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 num = PyTuple_GetItem(tuple, 1); /* us */
1480 if (num == NULL)
1481 goto Done;
1482 temp = PyLong_AsLong(num);
1483 num = NULL;
1484 if (temp == -1 && PyErr_Occurred())
1485 goto Done;
1486 assert(0 <= temp && temp < 1000000);
1487 us = (int)temp;
1488 if (us < 0) {
1489 /* The divisor was positive, so this must be an error. */
1490 assert(PyErr_Occurred());
1491 goto Done;
1492 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1495 if (num == NULL)
1496 goto Done;
1497 Py_INCREF(num);
1498 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 tuple = PyNumber_Divmod(num, seconds_per_day);
1501 if (tuple == NULL)
1502 goto Done;
1503 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 num = PyTuple_GetItem(tuple, 1); /* seconds */
1506 if (num == NULL)
1507 goto Done;
1508 temp = PyLong_AsLong(num);
1509 num = NULL;
1510 if (temp == -1 && PyErr_Occurred())
1511 goto Done;
1512 assert(0 <= temp && temp < 24*3600);
1513 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 if (s < 0) {
1516 /* The divisor was positive, so this must be an error. */
1517 assert(PyErr_Occurred());
1518 goto Done;
1519 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1522 if (num == NULL)
1523 goto Done;
1524 Py_INCREF(num);
1525 temp = PyLong_AsLong(num);
1526 if (temp == -1 && PyErr_Occurred())
1527 goto Done;
1528 d = (int)temp;
1529 if ((long)d != temp) {
1530 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1531 "large to fit in a C int");
1532 goto Done;
1533 }
1534 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001535
1536Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 Py_XDECREF(tuple);
1538 Py_XDECREF(num);
1539 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001540}
1541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542#define microseconds_to_delta(pymicros) \
1543 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001544
Tim Peters2a799bf2002-12-16 20:18:38 +00001545static PyObject *
1546multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 PyObject *pyus_in;
1549 PyObject *pyus_out;
1550 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 pyus_in = delta_to_microseconds(delta);
1553 if (pyus_in == NULL)
1554 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1557 Py_DECREF(pyus_in);
1558 if (pyus_out == NULL)
1559 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 result = microseconds_to_delta(pyus_out);
1562 Py_DECREF(pyus_out);
1563 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001564}
1565
1566static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001567multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1568{
1569 PyObject *result = NULL;
1570 PyObject *pyus_in = NULL, *temp, *pyus_out;
1571 PyObject *ratio = NULL;
1572
1573 pyus_in = delta_to_microseconds(delta);
1574 if (pyus_in == NULL)
1575 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001576 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001577 if (ratio == NULL)
1578 goto error;
1579 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1580 Py_DECREF(pyus_in);
1581 pyus_in = NULL;
1582 if (temp == NULL)
1583 goto error;
1584 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1585 Py_DECREF(temp);
1586 if (pyus_out == NULL)
1587 goto error;
1588 result = microseconds_to_delta(pyus_out);
1589 Py_DECREF(pyus_out);
1590 error:
1591 Py_XDECREF(pyus_in);
1592 Py_XDECREF(ratio);
1593
1594 return result;
1595}
1596
1597static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001598divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 PyObject *pyus_in;
1601 PyObject *pyus_out;
1602 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 pyus_in = delta_to_microseconds(delta);
1605 if (pyus_in == NULL)
1606 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1609 Py_DECREF(pyus_in);
1610 if (pyus_out == NULL)
1611 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 result = microseconds_to_delta(pyus_out);
1614 Py_DECREF(pyus_out);
1615 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001616}
1617
1618static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001619divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyObject *pyus_left;
1622 PyObject *pyus_right;
1623 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 pyus_left = delta_to_microseconds(left);
1626 if (pyus_left == NULL)
1627 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 pyus_right = delta_to_microseconds(right);
1630 if (pyus_right == NULL) {
1631 Py_DECREF(pyus_left);
1632 return NULL;
1633 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1636 Py_DECREF(pyus_left);
1637 Py_DECREF(pyus_right);
1638 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001639}
1640
1641static PyObject *
1642truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 PyObject *pyus_left;
1645 PyObject *pyus_right;
1646 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 pyus_left = delta_to_microseconds(left);
1649 if (pyus_left == NULL)
1650 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 pyus_right = delta_to_microseconds(right);
1653 if (pyus_right == NULL) {
1654 Py_DECREF(pyus_left);
1655 return NULL;
1656 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1659 Py_DECREF(pyus_left);
1660 Py_DECREF(pyus_right);
1661 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001662}
1663
1664static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001665truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1666{
1667 PyObject *result = NULL;
1668 PyObject *pyus_in = NULL, *temp, *pyus_out;
1669 PyObject *ratio = NULL;
1670
1671 pyus_in = delta_to_microseconds(delta);
1672 if (pyus_in == NULL)
1673 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001674 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001675 if (ratio == NULL)
1676 goto error;
1677 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1678 Py_DECREF(pyus_in);
1679 pyus_in = NULL;
1680 if (temp == NULL)
1681 goto error;
1682 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1683 Py_DECREF(temp);
1684 if (pyus_out == NULL)
1685 goto error;
1686 result = microseconds_to_delta(pyus_out);
1687 Py_DECREF(pyus_out);
1688 error:
1689 Py_XDECREF(pyus_in);
1690 Py_XDECREF(ratio);
1691
1692 return result;
1693}
1694
1695static PyObject *
1696truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1697{
1698 PyObject *result;
1699 PyObject *pyus_in, *pyus_out;
1700 pyus_in = delta_to_microseconds(delta);
1701 if (pyus_in == NULL)
1702 return NULL;
1703 pyus_out = divide_nearest(pyus_in, i);
1704 Py_DECREF(pyus_in);
1705 if (pyus_out == NULL)
1706 return NULL;
1707 result = microseconds_to_delta(pyus_out);
1708 Py_DECREF(pyus_out);
1709
1710 return result;
1711}
1712
1713static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001714delta_add(PyObject *left, PyObject *right)
1715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1719 /* delta + delta */
1720 /* The C-level additions can't overflow because of the
1721 * invariant bounds.
1722 */
1723 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1724 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1725 int microseconds = GET_TD_MICROSECONDS(left) +
1726 GET_TD_MICROSECONDS(right);
1727 result = new_delta(days, seconds, microseconds, 1);
1728 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 if (result == Py_NotImplemented)
1731 Py_INCREF(result);
1732 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001733}
1734
1735static PyObject *
1736delta_negative(PyDateTime_Delta *self)
1737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 return new_delta(-GET_TD_DAYS(self),
1739 -GET_TD_SECONDS(self),
1740 -GET_TD_MICROSECONDS(self),
1741 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001742}
1743
1744static PyObject *
1745delta_positive(PyDateTime_Delta *self)
1746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 /* Could optimize this (by returning self) if this isn't a
1748 * subclass -- but who uses unary + ? Approximately nobody.
1749 */
1750 return new_delta(GET_TD_DAYS(self),
1751 GET_TD_SECONDS(self),
1752 GET_TD_MICROSECONDS(self),
1753 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001754}
1755
1756static PyObject *
1757delta_abs(PyDateTime_Delta *self)
1758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 assert(GET_TD_MICROSECONDS(self) >= 0);
1762 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 if (GET_TD_DAYS(self) < 0)
1765 result = delta_negative(self);
1766 else
1767 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001770}
1771
1772static PyObject *
1773delta_subtract(PyObject *left, PyObject *right)
1774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1778 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001779 /* The C-level additions can't overflow because of the
1780 * invariant bounds.
1781 */
1782 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1783 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1784 int microseconds = GET_TD_MICROSECONDS(left) -
1785 GET_TD_MICROSECONDS(right);
1786 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 if (result == Py_NotImplemented)
1790 Py_INCREF(result);
1791 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001792}
1793
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001794static int
1795delta_cmp(PyObject *self, PyObject *other)
1796{
1797 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1798 if (diff == 0) {
1799 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1800 if (diff == 0)
1801 diff = GET_TD_MICROSECONDS(self) -
1802 GET_TD_MICROSECONDS(other);
1803 }
1804 return diff;
1805}
1806
Tim Peters2a799bf2002-12-16 20:18:38 +00001807static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001808delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001811 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 return diff_to_bool(diff, op);
1813 }
1814 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001815 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001817}
1818
1819static PyObject *delta_getstate(PyDateTime_Delta *self);
1820
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001821static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001822delta_hash(PyDateTime_Delta *self)
1823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 if (self->hashcode == -1) {
1825 PyObject *temp = delta_getstate(self);
1826 if (temp != NULL) {
1827 self->hashcode = PyObject_Hash(temp);
1828 Py_DECREF(temp);
1829 }
1830 }
1831 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001832}
1833
1834static PyObject *
1835delta_multiply(PyObject *left, PyObject *right)
1836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 if (PyDelta_Check(left)) {
1840 /* delta * ??? */
1841 if (PyLong_Check(right))
1842 result = multiply_int_timedelta(right,
1843 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001844 else if (PyFloat_Check(right))
1845 result = multiply_float_timedelta(right,
1846 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 }
1848 else if (PyLong_Check(left))
1849 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001850 (PyDateTime_Delta *) right);
1851 else if (PyFloat_Check(left))
1852 result = multiply_float_timedelta(left,
1853 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 if (result == Py_NotImplemented)
1856 Py_INCREF(result);
1857 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001858}
1859
1860static PyObject *
1861delta_divide(PyObject *left, PyObject *right)
1862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 if (PyDelta_Check(left)) {
1866 /* delta * ??? */
1867 if (PyLong_Check(right))
1868 result = divide_timedelta_int(
1869 (PyDateTime_Delta *)left,
1870 right);
1871 else if (PyDelta_Check(right))
1872 result = divide_timedelta_timedelta(
1873 (PyDateTime_Delta *)left,
1874 (PyDateTime_Delta *)right);
1875 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 if (result == Py_NotImplemented)
1878 Py_INCREF(result);
1879 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001880}
1881
Mark Dickinson7c186e22010-04-20 22:32:49 +00001882static PyObject *
1883delta_truedivide(PyObject *left, PyObject *right)
1884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 if (PyDelta_Check(left)) {
1888 if (PyDelta_Check(right))
1889 result = truedivide_timedelta_timedelta(
1890 (PyDateTime_Delta *)left,
1891 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001892 else if (PyFloat_Check(right))
1893 result = truedivide_timedelta_float(
1894 (PyDateTime_Delta *)left, right);
1895 else if (PyLong_Check(right))
1896 result = truedivide_timedelta_int(
1897 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 if (result == Py_NotImplemented)
1901 Py_INCREF(result);
1902 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001903}
1904
1905static PyObject *
1906delta_remainder(PyObject *left, PyObject *right)
1907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 PyObject *pyus_left;
1909 PyObject *pyus_right;
1910 PyObject *pyus_remainder;
1911 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001912
Brian Curtindfc80e32011-08-10 20:28:54 -05001913 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1914 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1917 if (pyus_left == NULL)
1918 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1921 if (pyus_right == NULL) {
1922 Py_DECREF(pyus_left);
1923 return NULL;
1924 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1927 Py_DECREF(pyus_left);
1928 Py_DECREF(pyus_right);
1929 if (pyus_remainder == NULL)
1930 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 remainder = microseconds_to_delta(pyus_remainder);
1933 Py_DECREF(pyus_remainder);
1934 if (remainder == NULL)
1935 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001938}
1939
1940static PyObject *
1941delta_divmod(PyObject *left, PyObject *right)
1942{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 PyObject *pyus_left;
1944 PyObject *pyus_right;
1945 PyObject *divmod;
1946 PyObject *delta;
1947 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001948
Brian Curtindfc80e32011-08-10 20:28:54 -05001949 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1950 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1953 if (pyus_left == NULL)
1954 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1957 if (pyus_right == NULL) {
1958 Py_DECREF(pyus_left);
1959 return NULL;
1960 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1963 Py_DECREF(pyus_left);
1964 Py_DECREF(pyus_right);
1965 if (divmod == NULL)
1966 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 assert(PyTuple_Size(divmod) == 2);
1969 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1970 if (delta == NULL) {
1971 Py_DECREF(divmod);
1972 return NULL;
1973 }
1974 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1975 Py_DECREF(delta);
1976 Py_DECREF(divmod);
1977 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001978}
1979
Tim Peters2a799bf2002-12-16 20:18:38 +00001980/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1981 * timedelta constructor. sofar is the # of microseconds accounted for
1982 * so far, and there are factor microseconds per current unit, the number
1983 * of which is given by num. num * factor is added to sofar in a
1984 * numerically careful way, and that's the result. Any fractional
1985 * microseconds left over (this can happen if num is a float type) are
1986 * added into *leftover.
1987 * Note that there are many ways this can give an error (NULL) return.
1988 */
1989static PyObject *
1990accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1991 double *leftover)
1992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 PyObject *prod;
1994 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00001995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 if (PyLong_Check(num)) {
1999 prod = PyNumber_Multiply(num, factor);
2000 if (prod == NULL)
2001 return NULL;
2002 sum = PyNumber_Add(sofar, prod);
2003 Py_DECREF(prod);
2004 return sum;
2005 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 if (PyFloat_Check(num)) {
2008 double dnum;
2009 double fracpart;
2010 double intpart;
2011 PyObject *x;
2012 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 /* The Plan: decompose num into an integer part and a
2015 * fractional part, num = intpart + fracpart.
2016 * Then num * factor ==
2017 * intpart * factor + fracpart * factor
2018 * and the LHS can be computed exactly in long arithmetic.
2019 * The RHS is again broken into an int part and frac part.
2020 * and the frac part is added into *leftover.
2021 */
2022 dnum = PyFloat_AsDouble(num);
2023 if (dnum == -1.0 && PyErr_Occurred())
2024 return NULL;
2025 fracpart = modf(dnum, &intpart);
2026 x = PyLong_FromDouble(intpart);
2027 if (x == NULL)
2028 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 prod = PyNumber_Multiply(x, factor);
2031 Py_DECREF(x);
2032 if (prod == NULL)
2033 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 sum = PyNumber_Add(sofar, prod);
2036 Py_DECREF(prod);
2037 if (sum == NULL)
2038 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 if (fracpart == 0.0)
2041 return sum;
2042 /* So far we've lost no information. Dealing with the
2043 * fractional part requires float arithmetic, and may
2044 * lose a little info.
2045 */
2046 assert(PyLong_Check(factor));
2047 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 dnum *= fracpart;
2050 fracpart = modf(dnum, &intpart);
2051 x = PyLong_FromDouble(intpart);
2052 if (x == NULL) {
2053 Py_DECREF(sum);
2054 return NULL;
2055 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002057 y = PyNumber_Add(sum, x);
2058 Py_DECREF(sum);
2059 Py_DECREF(x);
2060 *leftover += fracpart;
2061 return y;
2062 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 PyErr_Format(PyExc_TypeError,
2065 "unsupported type for timedelta %s component: %s",
2066 tag, Py_TYPE(num)->tp_name);
2067 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002068}
2069
2070static PyObject *
2071delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 /* Argument objects. */
2076 PyObject *day = NULL;
2077 PyObject *second = NULL;
2078 PyObject *us = NULL;
2079 PyObject *ms = NULL;
2080 PyObject *minute = NULL;
2081 PyObject *hour = NULL;
2082 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 PyObject *x = NULL; /* running sum of microseconds */
2085 PyObject *y = NULL; /* temp sum of microseconds */
2086 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 static char *keywords[] = {
2089 "days", "seconds", "microseconds", "milliseconds",
2090 "minutes", "hours", "weeks", NULL
2091 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2094 keywords,
2095 &day, &second, &us,
2096 &ms, &minute, &hour, &week) == 0)
2097 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 x = PyLong_FromLong(0);
2100 if (x == NULL)
2101 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103#define CLEANUP \
2104 Py_DECREF(x); \
2105 x = y; \
2106 if (x == NULL) \
2107 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002110 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 CLEANUP;
2112 }
2113 if (ms) {
2114 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2115 CLEANUP;
2116 }
2117 if (second) {
2118 y = accum("seconds", x, second, us_per_second, &leftover_us);
2119 CLEANUP;
2120 }
2121 if (minute) {
2122 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2123 CLEANUP;
2124 }
2125 if (hour) {
2126 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2127 CLEANUP;
2128 }
2129 if (day) {
2130 y = accum("days", x, day, us_per_day, &leftover_us);
2131 CLEANUP;
2132 }
2133 if (week) {
2134 y = accum("weeks", x, week, us_per_week, &leftover_us);
2135 CLEANUP;
2136 }
2137 if (leftover_us) {
2138 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002139 double whole_us = round(leftover_us);
2140 int x_is_odd;
2141 PyObject *temp;
2142
2143 whole_us = round(leftover_us);
2144 if (fabs(whole_us - leftover_us) == 0.5) {
2145 /* We're exactly halfway between two integers. In order
2146 * to do round-half-to-even, we must determine whether x
2147 * is odd. Note that x is odd when it's last bit is 1. The
2148 * code below uses bitwise and operation to check the last
2149 * bit. */
2150 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2151 if (temp == NULL) {
2152 Py_DECREF(x);
2153 goto Done;
2154 }
2155 x_is_odd = PyObject_IsTrue(temp);
2156 Py_DECREF(temp);
2157 if (x_is_odd == -1) {
2158 Py_DECREF(x);
2159 goto Done;
2160 }
2161 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2162 }
2163
Victor Stinner36a5a062013-08-28 01:53:39 +02002164 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 if (temp == NULL) {
2167 Py_DECREF(x);
2168 goto Done;
2169 }
2170 y = PyNumber_Add(x, temp);
2171 Py_DECREF(temp);
2172 CLEANUP;
2173 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 self = microseconds_to_delta_ex(x, type);
2176 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002177Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002179
2180#undef CLEANUP
2181}
2182
2183static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002184delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002185{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 return (GET_TD_DAYS(self) != 0
2187 || GET_TD_SECONDS(self) != 0
2188 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002189}
2190
2191static PyObject *
2192delta_repr(PyDateTime_Delta *self)
2193{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 if (GET_TD_MICROSECONDS(self) != 0)
2195 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2196 Py_TYPE(self)->tp_name,
2197 GET_TD_DAYS(self),
2198 GET_TD_SECONDS(self),
2199 GET_TD_MICROSECONDS(self));
2200 if (GET_TD_SECONDS(self) != 0)
2201 return PyUnicode_FromFormat("%s(%d, %d)",
2202 Py_TYPE(self)->tp_name,
2203 GET_TD_DAYS(self),
2204 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 return PyUnicode_FromFormat("%s(%d)",
2207 Py_TYPE(self)->tp_name,
2208 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002209}
2210
2211static PyObject *
2212delta_str(PyDateTime_Delta *self)
2213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002214 int us = GET_TD_MICROSECONDS(self);
2215 int seconds = GET_TD_SECONDS(self);
2216 int minutes = divmod(seconds, 60, &seconds);
2217 int hours = divmod(minutes, 60, &minutes);
2218 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 if (days) {
2221 if (us)
2222 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2223 days, (days == 1 || days == -1) ? "" : "s",
2224 hours, minutes, seconds, us);
2225 else
2226 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2227 days, (days == 1 || days == -1) ? "" : "s",
2228 hours, minutes, seconds);
2229 } else {
2230 if (us)
2231 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2232 hours, minutes, seconds, us);
2233 else
2234 return PyUnicode_FromFormat("%d:%02d:%02d",
2235 hours, minutes, seconds);
2236 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002237
Tim Peters2a799bf2002-12-16 20:18:38 +00002238}
2239
Tim Peters371935f2003-02-01 01:52:50 +00002240/* Pickle support, a simple use of __reduce__. */
2241
Tim Petersb57f8f02003-02-01 02:54:15 +00002242/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002243static PyObject *
2244delta_getstate(PyDateTime_Delta *self)
2245{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 return Py_BuildValue("iii", GET_TD_DAYS(self),
2247 GET_TD_SECONDS(self),
2248 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002249}
2250
Tim Peters2a799bf2002-12-16 20:18:38 +00002251static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002252delta_total_seconds(PyObject *self)
2253{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 PyObject *total_seconds;
2255 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2258 if (total_microseconds == NULL)
2259 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002260
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002261 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002265}
2266
2267static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002268delta_reduce(PyDateTime_Delta* self)
2269{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002271}
2272
2273#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2274
2275static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 {"days", T_INT, OFFSET(days), READONLY,
2278 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 {"seconds", T_INT, OFFSET(seconds), READONLY,
2281 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2284 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2285 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002286};
2287
2288static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2290 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2293 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002296};
2297
2298static char delta_doc[] =
2299PyDoc_STR("Difference between two datetime values.");
2300
2301static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 delta_add, /* nb_add */
2303 delta_subtract, /* nb_subtract */
2304 delta_multiply, /* nb_multiply */
2305 delta_remainder, /* nb_remainder */
2306 delta_divmod, /* nb_divmod */
2307 0, /* nb_power */
2308 (unaryfunc)delta_negative, /* nb_negative */
2309 (unaryfunc)delta_positive, /* nb_positive */
2310 (unaryfunc)delta_abs, /* nb_absolute */
2311 (inquiry)delta_bool, /* nb_bool */
2312 0, /*nb_invert*/
2313 0, /*nb_lshift*/
2314 0, /*nb_rshift*/
2315 0, /*nb_and*/
2316 0, /*nb_xor*/
2317 0, /*nb_or*/
2318 0, /*nb_int*/
2319 0, /*nb_reserved*/
2320 0, /*nb_float*/
2321 0, /*nb_inplace_add*/
2322 0, /*nb_inplace_subtract*/
2323 0, /*nb_inplace_multiply*/
2324 0, /*nb_inplace_remainder*/
2325 0, /*nb_inplace_power*/
2326 0, /*nb_inplace_lshift*/
2327 0, /*nb_inplace_rshift*/
2328 0, /*nb_inplace_and*/
2329 0, /*nb_inplace_xor*/
2330 0, /*nb_inplace_or*/
2331 delta_divide, /* nb_floor_divide */
2332 delta_truedivide, /* nb_true_divide */
2333 0, /* nb_inplace_floor_divide */
2334 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002335};
2336
2337static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002338 PyVarObject_HEAD_INIT(NULL, 0)
2339 "datetime.timedelta", /* tp_name */
2340 sizeof(PyDateTime_Delta), /* tp_basicsize */
2341 0, /* tp_itemsize */
2342 0, /* tp_dealloc */
2343 0, /* tp_print */
2344 0, /* tp_getattr */
2345 0, /* tp_setattr */
2346 0, /* tp_reserved */
2347 (reprfunc)delta_repr, /* tp_repr */
2348 &delta_as_number, /* tp_as_number */
2349 0, /* tp_as_sequence */
2350 0, /* tp_as_mapping */
2351 (hashfunc)delta_hash, /* tp_hash */
2352 0, /* tp_call */
2353 (reprfunc)delta_str, /* tp_str */
2354 PyObject_GenericGetAttr, /* tp_getattro */
2355 0, /* tp_setattro */
2356 0, /* tp_as_buffer */
2357 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2358 delta_doc, /* tp_doc */
2359 0, /* tp_traverse */
2360 0, /* tp_clear */
2361 delta_richcompare, /* tp_richcompare */
2362 0, /* tp_weaklistoffset */
2363 0, /* tp_iter */
2364 0, /* tp_iternext */
2365 delta_methods, /* tp_methods */
2366 delta_members, /* tp_members */
2367 0, /* tp_getset */
2368 0, /* tp_base */
2369 0, /* tp_dict */
2370 0, /* tp_descr_get */
2371 0, /* tp_descr_set */
2372 0, /* tp_dictoffset */
2373 0, /* tp_init */
2374 0, /* tp_alloc */
2375 delta_new, /* tp_new */
2376 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002377};
2378
2379/*
2380 * PyDateTime_Date implementation.
2381 */
2382
2383/* Accessor properties. */
2384
2385static PyObject *
2386date_year(PyDateTime_Date *self, void *unused)
2387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002389}
2390
2391static PyObject *
2392date_month(PyDateTime_Date *self, void *unused)
2393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002395}
2396
2397static PyObject *
2398date_day(PyDateTime_Date *self, void *unused)
2399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002401}
2402
2403static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 {"year", (getter)date_year},
2405 {"month", (getter)date_month},
2406 {"day", (getter)date_day},
2407 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002408};
2409
2410/* Constructors. */
2411
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002412static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002413
Tim Peters2a799bf2002-12-16 20:18:38 +00002414static PyObject *
2415date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 PyObject *self = NULL;
2418 PyObject *state;
2419 int year;
2420 int month;
2421 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 /* Check for invocation from pickle with __getstate__ state */
2424 if (PyTuple_GET_SIZE(args) == 1 &&
2425 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2426 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2427 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2428 {
2429 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2432 if (me != NULL) {
2433 char *pdata = PyBytes_AS_STRING(state);
2434 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2435 me->hashcode = -1;
2436 }
2437 return (PyObject *)me;
2438 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002440 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2441 &year, &month, &day)) {
2442 if (check_date_args(year, month, day) < 0)
2443 return NULL;
2444 self = new_date_ex(year, month, day, type);
2445 }
2446 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002447}
2448
2449/* Return new date from localtime(t). */
2450static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002451date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002452{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 struct tm *tm;
2454 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002455
Victor Stinner5d272cc2012-03-13 13:35:55 +01002456 if (_PyTime_ObjectToTime_t(obj, &t) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002459 tm = localtime(&t);
Victor Stinner21f58932012-03-14 00:15:40 +01002460 if (tm == NULL) {
2461 /* unconvertible time */
2462#ifdef EINVAL
2463 if (errno == 0)
2464 errno = EINVAL;
2465#endif
2466 PyErr_SetFromErrno(PyExc_OSError);
2467 return NULL;
2468 }
2469
2470 return PyObject_CallFunction(cls, "iii",
2471 tm->tm_year + 1900,
2472 tm->tm_mon + 1,
2473 tm->tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002474}
2475
2476/* Return new date from current time.
2477 * We say this is equivalent to fromtimestamp(time.time()), and the
2478 * only way to be sure of that is to *call* time.time(). That's not
2479 * generally the same as calling C's time.
2480 */
2481static PyObject *
2482date_today(PyObject *cls, PyObject *dummy)
2483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002484 PyObject *time;
2485 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002486 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002488 time = time_time();
2489 if (time == NULL)
2490 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 /* Note well: today() is a class method, so this may not call
2493 * date.fromtimestamp. For example, it may call
2494 * datetime.fromtimestamp. That's why we need all the accuracy
2495 * time.time() delivers; if someone were gonzo about optimization,
2496 * date.today() could get away with plain C time().
2497 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002498 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 Py_DECREF(time);
2500 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002501}
2502
2503/* Return new date from given timestamp (Python timestamp -- a double). */
2504static PyObject *
2505date_fromtimestamp(PyObject *cls, PyObject *args)
2506{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002507 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002508 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002509
Victor Stinner5d272cc2012-03-13 13:35:55 +01002510 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2511 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002513}
2514
2515/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2516 * the ordinal is out of range.
2517 */
2518static PyObject *
2519date_fromordinal(PyObject *cls, PyObject *args)
2520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002521 PyObject *result = NULL;
2522 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2525 int year;
2526 int month;
2527 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 if (ordinal < 1)
2530 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2531 ">= 1");
2532 else {
2533 ord_to_ymd(ordinal, &year, &month, &day);
2534 result = PyObject_CallFunction(cls, "iii",
2535 year, month, day);
2536 }
2537 }
2538 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002539}
2540
2541/*
2542 * Date arithmetic.
2543 */
2544
2545/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2546 * instead.
2547 */
2548static PyObject *
2549add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2550{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 PyObject *result = NULL;
2552 int year = GET_YEAR(date);
2553 int month = GET_MONTH(date);
2554 int deltadays = GET_TD_DAYS(delta);
2555 /* C-level overflow is impossible because |deltadays| < 1e9. */
2556 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558 if (normalize_date(&year, &month, &day) >= 0)
2559 result = new_date(year, month, day);
2560 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002561}
2562
2563static PyObject *
2564date_add(PyObject *left, PyObject *right)
2565{
Brian Curtindfc80e32011-08-10 20:28:54 -05002566 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2567 Py_RETURN_NOTIMPLEMENTED;
2568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002569 if (PyDate_Check(left)) {
2570 /* date + ??? */
2571 if (PyDelta_Check(right))
2572 /* date + delta */
2573 return add_date_timedelta((PyDateTime_Date *) left,
2574 (PyDateTime_Delta *) right,
2575 0);
2576 }
2577 else {
2578 /* ??? + date
2579 * 'right' must be one of us, or we wouldn't have been called
2580 */
2581 if (PyDelta_Check(left))
2582 /* delta + date */
2583 return add_date_timedelta((PyDateTime_Date *) right,
2584 (PyDateTime_Delta *) left,
2585 0);
2586 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002587 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002588}
2589
2590static PyObject *
2591date_subtract(PyObject *left, PyObject *right)
2592{
Brian Curtindfc80e32011-08-10 20:28:54 -05002593 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2594 Py_RETURN_NOTIMPLEMENTED;
2595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002596 if (PyDate_Check(left)) {
2597 if (PyDate_Check(right)) {
2598 /* date - date */
2599 int left_ord = ymd_to_ord(GET_YEAR(left),
2600 GET_MONTH(left),
2601 GET_DAY(left));
2602 int right_ord = ymd_to_ord(GET_YEAR(right),
2603 GET_MONTH(right),
2604 GET_DAY(right));
2605 return new_delta(left_ord - right_ord, 0, 0, 0);
2606 }
2607 if (PyDelta_Check(right)) {
2608 /* date - delta */
2609 return add_date_timedelta((PyDateTime_Date *) left,
2610 (PyDateTime_Delta *) right,
2611 1);
2612 }
2613 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002614 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002615}
2616
2617
2618/* Various ways to turn a date into a string. */
2619
2620static PyObject *
2621date_repr(PyDateTime_Date *self)
2622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002623 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2624 Py_TYPE(self)->tp_name,
2625 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002626}
2627
2628static PyObject *
2629date_isoformat(PyDateTime_Date *self)
2630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 return PyUnicode_FromFormat("%04d-%02d-%02d",
2632 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002633}
2634
Tim Peterse2df5ff2003-05-02 18:39:55 +00002635/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002636static PyObject *
2637date_str(PyDateTime_Date *self)
2638{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002639 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002640}
2641
2642
2643static PyObject *
2644date_ctime(PyDateTime_Date *self)
2645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002647}
2648
2649static PyObject *
2650date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002652 /* This method can be inherited, and needs to call the
2653 * timetuple() method appropriate to self's class.
2654 */
2655 PyObject *result;
2656 PyObject *tuple;
2657 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002658 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002661 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2662 &format))
2663 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002664
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002665 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002666 if (tuple == NULL)
2667 return NULL;
2668 result = wrap_strftime((PyObject *)self, format, tuple,
2669 (PyObject *)self);
2670 Py_DECREF(tuple);
2671 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002672}
2673
Eric Smith1ba31142007-09-11 18:06:02 +00002674static PyObject *
2675date_format(PyDateTime_Date *self, PyObject *args)
2676{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002677 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002679 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2680 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002682 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002683 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002684 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002685
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002686 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002687}
2688
Tim Peters2a799bf2002-12-16 20:18:38 +00002689/* ISO methods. */
2690
2691static PyObject *
2692date_isoweekday(PyDateTime_Date *self)
2693{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002694 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002695
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002696 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002697}
2698
2699static PyObject *
2700date_isocalendar(PyDateTime_Date *self)
2701{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002702 int year = GET_YEAR(self);
2703 int week1_monday = iso_week1_monday(year);
2704 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2705 int week;
2706 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002708 week = divmod(today - week1_monday, 7, &day);
2709 if (week < 0) {
2710 --year;
2711 week1_monday = iso_week1_monday(year);
2712 week = divmod(today - week1_monday, 7, &day);
2713 }
2714 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2715 ++year;
2716 week = 0;
2717 }
2718 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002719}
2720
2721/* Miscellaneous methods. */
2722
Tim Peters2a799bf2002-12-16 20:18:38 +00002723static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002724date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002726 if (PyDate_Check(other)) {
2727 int diff = memcmp(((PyDateTime_Date *)self)->data,
2728 ((PyDateTime_Date *)other)->data,
2729 _PyDateTime_DATE_DATASIZE);
2730 return diff_to_bool(diff, op);
2731 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002732 else
2733 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002734}
2735
2736static PyObject *
2737date_timetuple(PyDateTime_Date *self)
2738{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002739 return build_struct_time(GET_YEAR(self),
2740 GET_MONTH(self),
2741 GET_DAY(self),
2742 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002743}
2744
Tim Peters12bf3392002-12-24 05:41:27 +00002745static PyObject *
2746date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002748 PyObject *clone;
2749 PyObject *tuple;
2750 int year = GET_YEAR(self);
2751 int month = GET_MONTH(self);
2752 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002754 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2755 &year, &month, &day))
2756 return NULL;
2757 tuple = Py_BuildValue("iii", year, month, day);
2758 if (tuple == NULL)
2759 return NULL;
2760 clone = date_new(Py_TYPE(self), tuple, NULL);
2761 Py_DECREF(tuple);
2762 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002763}
2764
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002765static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002766generic_hash(unsigned char *data, int len)
2767{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002768 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002769}
2770
2771
2772static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002773
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002774static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002775date_hash(PyDateTime_Date *self)
2776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002777 if (self->hashcode == -1)
2778 self->hashcode = generic_hash(
2779 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002781 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002782}
2783
2784static PyObject *
2785date_toordinal(PyDateTime_Date *self)
2786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002787 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2788 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002789}
2790
2791static PyObject *
2792date_weekday(PyDateTime_Date *self)
2793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002794 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002797}
2798
Tim Peters371935f2003-02-01 01:52:50 +00002799/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002800
Tim Petersb57f8f02003-02-01 02:54:15 +00002801/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002802static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002803date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 PyObject* field;
2806 field = PyBytes_FromStringAndSize((char*)self->data,
2807 _PyDateTime_DATE_DATASIZE);
2808 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002809}
2810
2811static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002812date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002815}
2816
2817static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002819 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002821 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2822 METH_CLASS,
2823 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2824 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002826 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2827 METH_CLASS,
2828 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2829 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2832 PyDoc_STR("Current date or datetime: same as "
2833 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002835 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2838 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002840 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2841 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002843 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2844 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002846 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2847 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2850 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2851 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2854 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2857 PyDoc_STR("Return the day of the week represented by the date.\n"
2858 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002860 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2861 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2862 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2865 PyDoc_STR("Return the day of the week represented by the date.\n"
2866 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2869 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002871 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2872 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002874 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002875};
2876
2877static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002878PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002879
2880static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002881 date_add, /* nb_add */
2882 date_subtract, /* nb_subtract */
2883 0, /* nb_multiply */
2884 0, /* nb_remainder */
2885 0, /* nb_divmod */
2886 0, /* nb_power */
2887 0, /* nb_negative */
2888 0, /* nb_positive */
2889 0, /* nb_absolute */
2890 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002891};
2892
2893static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002894 PyVarObject_HEAD_INIT(NULL, 0)
2895 "datetime.date", /* tp_name */
2896 sizeof(PyDateTime_Date), /* tp_basicsize */
2897 0, /* tp_itemsize */
2898 0, /* tp_dealloc */
2899 0, /* tp_print */
2900 0, /* tp_getattr */
2901 0, /* tp_setattr */
2902 0, /* tp_reserved */
2903 (reprfunc)date_repr, /* tp_repr */
2904 &date_as_number, /* tp_as_number */
2905 0, /* tp_as_sequence */
2906 0, /* tp_as_mapping */
2907 (hashfunc)date_hash, /* tp_hash */
2908 0, /* tp_call */
2909 (reprfunc)date_str, /* tp_str */
2910 PyObject_GenericGetAttr, /* tp_getattro */
2911 0, /* tp_setattro */
2912 0, /* tp_as_buffer */
2913 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2914 date_doc, /* tp_doc */
2915 0, /* tp_traverse */
2916 0, /* tp_clear */
2917 date_richcompare, /* tp_richcompare */
2918 0, /* tp_weaklistoffset */
2919 0, /* tp_iter */
2920 0, /* tp_iternext */
2921 date_methods, /* tp_methods */
2922 0, /* tp_members */
2923 date_getset, /* tp_getset */
2924 0, /* tp_base */
2925 0, /* tp_dict */
2926 0, /* tp_descr_get */
2927 0, /* tp_descr_set */
2928 0, /* tp_dictoffset */
2929 0, /* tp_init */
2930 0, /* tp_alloc */
2931 date_new, /* tp_new */
2932 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002933};
2934
2935/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002936 * PyDateTime_TZInfo implementation.
2937 */
2938
2939/* This is a pure abstract base class, so doesn't do anything beyond
2940 * raising NotImplemented exceptions. Real tzinfo classes need
2941 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002942 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002943 * be subclasses of this tzinfo class, which is easy and quick to check).
2944 *
2945 * Note: For reasons having to do with pickling of subclasses, we have
2946 * to allow tzinfo objects to be instantiated. This wasn't an issue
2947 * in the Python implementation (__init__() could raise NotImplementedError
2948 * there without ill effect), but doing so in the C implementation hit a
2949 * brick wall.
2950 */
2951
2952static PyObject *
2953tzinfo_nogo(const char* methodname)
2954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002955 PyErr_Format(PyExc_NotImplementedError,
2956 "a tzinfo subclass must implement %s()",
2957 methodname);
2958 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002959}
2960
2961/* Methods. A subclass must implement these. */
2962
Tim Peters52dcce22003-01-23 16:36:11 +00002963static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002964tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2965{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002966 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002967}
2968
Tim Peters52dcce22003-01-23 16:36:11 +00002969static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002970tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002972 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002973}
2974
Tim Peters52dcce22003-01-23 16:36:11 +00002975static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002976tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002978 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002979}
2980
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002981
2982static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2983 PyDateTime_Delta *delta,
2984 int factor);
2985static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2986static PyObject *datetime_dst(PyObject *self, PyObject *);
2987
Tim Peters52dcce22003-01-23 16:36:11 +00002988static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002989tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002990{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002991 PyObject *result = NULL;
2992 PyObject *off = NULL, *dst = NULL;
2993 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002994
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002995 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002996 PyErr_SetString(PyExc_TypeError,
2997 "fromutc: argument must be a datetime");
2998 return NULL;
2999 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003000 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003001 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3002 "is not self");
3003 return NULL;
3004 }
Tim Peters52dcce22003-01-23 16:36:11 +00003005
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003006 off = datetime_utcoffset(dt, NULL);
3007 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003008 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003009 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003010 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3011 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003012 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003013 }
Tim Peters52dcce22003-01-23 16:36:11 +00003014
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003015 dst = datetime_dst(dt, NULL);
3016 if (dst == NULL)
3017 goto Fail;
3018 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003019 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3020 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003021 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003022 }
Tim Peters52dcce22003-01-23 16:36:11 +00003023
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003024 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3025 if (delta == NULL)
3026 goto Fail;
3027 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003028 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003029 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003030
3031 Py_DECREF(dst);
3032 dst = call_dst(GET_DT_TZINFO(dt), result);
3033 if (dst == NULL)
3034 goto Fail;
3035 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003036 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003037 if (delta_bool(delta) != 0) {
3038 PyObject *temp = result;
3039 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3040 (PyDateTime_Delta *)dst, 1);
3041 Py_DECREF(temp);
3042 if (result == NULL)
3043 goto Fail;
3044 }
3045 Py_DECREF(delta);
3046 Py_DECREF(dst);
3047 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003048 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003049
3050Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003051 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3052 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003054 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003055Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003056 Py_XDECREF(off);
3057 Py_XDECREF(dst);
3058 Py_XDECREF(delta);
3059 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003060 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003061}
3062
Tim Peters2a799bf2002-12-16 20:18:38 +00003063/*
3064 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003065 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003066 */
3067
Guido van Rossum177e41a2003-01-30 22:06:23 +00003068static PyObject *
3069tzinfo_reduce(PyObject *self)
3070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003071 PyObject *args, *state, *tmp;
3072 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003073 _Py_IDENTIFIER(__getinitargs__);
3074 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003076 tmp = PyTuple_New(0);
3077 if (tmp == NULL)
3078 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003079
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003080 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003081 if (getinitargs != NULL) {
3082 args = PyObject_CallObject(getinitargs, tmp);
3083 Py_DECREF(getinitargs);
3084 if (args == NULL) {
3085 Py_DECREF(tmp);
3086 return NULL;
3087 }
3088 }
3089 else {
3090 PyErr_Clear();
3091 args = tmp;
3092 Py_INCREF(args);
3093 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003094
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003095 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003096 if (getstate != NULL) {
3097 state = PyObject_CallObject(getstate, tmp);
3098 Py_DECREF(getstate);
3099 if (state == NULL) {
3100 Py_DECREF(args);
3101 Py_DECREF(tmp);
3102 return NULL;
3103 }
3104 }
3105 else {
3106 PyObject **dictptr;
3107 PyErr_Clear();
3108 state = Py_None;
3109 dictptr = _PyObject_GetDictPtr(self);
3110 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3111 state = *dictptr;
3112 Py_INCREF(state);
3113 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003115 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003117 if (state == Py_None) {
3118 Py_DECREF(state);
3119 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3120 }
3121 else
3122 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003123}
Tim Peters2a799bf2002-12-16 20:18:38 +00003124
3125static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003127 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3128 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003130 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003131 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3132 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003134 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3135 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003137 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003138 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003140 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3141 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003144};
3145
3146static char tzinfo_doc[] =
3147PyDoc_STR("Abstract base class for time zone info objects.");
3148
Neal Norwitz227b5332006-03-22 09:28:35 +00003149static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003150 PyVarObject_HEAD_INIT(NULL, 0)
3151 "datetime.tzinfo", /* tp_name */
3152 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3153 0, /* tp_itemsize */
3154 0, /* tp_dealloc */
3155 0, /* tp_print */
3156 0, /* tp_getattr */
3157 0, /* tp_setattr */
3158 0, /* tp_reserved */
3159 0, /* tp_repr */
3160 0, /* tp_as_number */
3161 0, /* tp_as_sequence */
3162 0, /* tp_as_mapping */
3163 0, /* tp_hash */
3164 0, /* tp_call */
3165 0, /* tp_str */
3166 PyObject_GenericGetAttr, /* tp_getattro */
3167 0, /* tp_setattro */
3168 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003169 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003170 tzinfo_doc, /* tp_doc */
3171 0, /* tp_traverse */
3172 0, /* tp_clear */
3173 0, /* tp_richcompare */
3174 0, /* tp_weaklistoffset */
3175 0, /* tp_iter */
3176 0, /* tp_iternext */
3177 tzinfo_methods, /* tp_methods */
3178 0, /* tp_members */
3179 0, /* tp_getset */
3180 0, /* tp_base */
3181 0, /* tp_dict */
3182 0, /* tp_descr_get */
3183 0, /* tp_descr_set */
3184 0, /* tp_dictoffset */
3185 0, /* tp_init */
3186 0, /* tp_alloc */
3187 PyType_GenericNew, /* tp_new */
3188 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003189};
3190
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003191static char *timezone_kws[] = {"offset", "name", NULL};
3192
3193static PyObject *
3194timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3195{
3196 PyObject *offset;
3197 PyObject *name = NULL;
3198 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3199 &PyDateTime_DeltaType, &offset,
3200 &PyUnicode_Type, &name))
3201 return new_timezone(offset, name);
3202
3203 return NULL;
3204}
3205
3206static void
3207timezone_dealloc(PyDateTime_TimeZone *self)
3208{
3209 Py_CLEAR(self->offset);
3210 Py_CLEAR(self->name);
3211 Py_TYPE(self)->tp_free((PyObject *)self);
3212}
3213
3214static PyObject *
3215timezone_richcompare(PyDateTime_TimeZone *self,
3216 PyDateTime_TimeZone *other, int op)
3217{
Brian Curtindfc80e32011-08-10 20:28:54 -05003218 if (op != Py_EQ && op != Py_NE)
3219 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003220 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
3221 if (op == Py_EQ)
3222 Py_RETURN_FALSE;
3223 else
3224 Py_RETURN_TRUE;
3225 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003226 return delta_richcompare(self->offset, other->offset, op);
3227}
3228
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003229static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003230timezone_hash(PyDateTime_TimeZone *self)
3231{
3232 return delta_hash((PyDateTime_Delta *)self->offset);
3233}
3234
3235/* Check argument type passed to tzname, utcoffset, or dst methods.
3236 Returns 0 for good argument. Returns -1 and sets exception info
3237 otherwise.
3238 */
3239static int
3240_timezone_check_argument(PyObject *dt, const char *meth)
3241{
3242 if (dt == Py_None || PyDateTime_Check(dt))
3243 return 0;
3244 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3245 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3246 return -1;
3247}
3248
3249static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003250timezone_repr(PyDateTime_TimeZone *self)
3251{
3252 /* Note that although timezone is not subclassable, it is convenient
3253 to use Py_TYPE(self)->tp_name here. */
3254 const char *type_name = Py_TYPE(self)->tp_name;
3255
3256 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3257 return PyUnicode_FromFormat("%s.utc", type_name);
3258
3259 if (self->name == NULL)
3260 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3261
3262 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3263 self->name);
3264}
3265
3266
3267static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003268timezone_str(PyDateTime_TimeZone *self)
3269{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003270 int hours, minutes, seconds;
3271 PyObject *offset;
3272 char sign;
3273
3274 if (self->name != NULL) {
3275 Py_INCREF(self->name);
3276 return self->name;
3277 }
3278 /* Offset is normalized, so it is negative if days < 0 */
3279 if (GET_TD_DAYS(self->offset) < 0) {
3280 sign = '-';
3281 offset = delta_negative((PyDateTime_Delta *)self->offset);
3282 if (offset == NULL)
3283 return NULL;
3284 }
3285 else {
3286 sign = '+';
3287 offset = self->offset;
3288 Py_INCREF(offset);
3289 }
3290 /* Offset is not negative here. */
3291 seconds = GET_TD_SECONDS(offset);
3292 Py_DECREF(offset);
3293 minutes = divmod(seconds, 60, &seconds);
3294 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003295 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003296 assert(seconds == 0);
3297 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003298}
3299
3300static PyObject *
3301timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3302{
3303 if (_timezone_check_argument(dt, "tzname") == -1)
3304 return NULL;
3305
3306 return timezone_str(self);
3307}
3308
3309static PyObject *
3310timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3311{
3312 if (_timezone_check_argument(dt, "utcoffset") == -1)
3313 return NULL;
3314
3315 Py_INCREF(self->offset);
3316 return self->offset;
3317}
3318
3319static PyObject *
3320timezone_dst(PyObject *self, PyObject *dt)
3321{
3322 if (_timezone_check_argument(dt, "dst") == -1)
3323 return NULL;
3324
3325 Py_RETURN_NONE;
3326}
3327
3328static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003329timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3330{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003331 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003332 PyErr_SetString(PyExc_TypeError,
3333 "fromutc: argument must be a datetime");
3334 return NULL;
3335 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003336 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003337 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3338 "is not self");
3339 return NULL;
3340 }
3341
3342 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3343}
3344
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003345static PyObject *
3346timezone_getinitargs(PyDateTime_TimeZone *self)
3347{
3348 if (self->name == NULL)
3349 return Py_BuildValue("(O)", self->offset);
3350 return Py_BuildValue("(OO)", self->offset, self->name);
3351}
3352
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003353static PyMethodDef timezone_methods[] = {
3354 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3355 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003356 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003357
3358 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003359 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003360
3361 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003362 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003363
3364 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3365 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3366
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003367 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3368 PyDoc_STR("pickle support")},
3369
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003370 {NULL, NULL}
3371};
3372
3373static char timezone_doc[] =
3374PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3375
3376static PyTypeObject PyDateTime_TimeZoneType = {
3377 PyVarObject_HEAD_INIT(NULL, 0)
3378 "datetime.timezone", /* tp_name */
3379 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3380 0, /* tp_itemsize */
3381 (destructor)timezone_dealloc, /* tp_dealloc */
3382 0, /* tp_print */
3383 0, /* tp_getattr */
3384 0, /* tp_setattr */
3385 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003386 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003387 0, /* tp_as_number */
3388 0, /* tp_as_sequence */
3389 0, /* tp_as_mapping */
3390 (hashfunc)timezone_hash, /* tp_hash */
3391 0, /* tp_call */
3392 (reprfunc)timezone_str, /* tp_str */
3393 0, /* tp_getattro */
3394 0, /* tp_setattro */
3395 0, /* tp_as_buffer */
3396 Py_TPFLAGS_DEFAULT, /* tp_flags */
3397 timezone_doc, /* tp_doc */
3398 0, /* tp_traverse */
3399 0, /* tp_clear */
3400 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3401 0, /* tp_weaklistoffset */
3402 0, /* tp_iter */
3403 0, /* tp_iternext */
3404 timezone_methods, /* tp_methods */
3405 0, /* tp_members */
3406 0, /* tp_getset */
3407 &PyDateTime_TZInfoType, /* tp_base */
3408 0, /* tp_dict */
3409 0, /* tp_descr_get */
3410 0, /* tp_descr_set */
3411 0, /* tp_dictoffset */
3412 0, /* tp_init */
3413 0, /* tp_alloc */
3414 timezone_new, /* tp_new */
3415};
3416
Tim Peters2a799bf2002-12-16 20:18:38 +00003417/*
Tim Peters37f39822003-01-10 03:49:02 +00003418 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003419 */
3420
Tim Peters37f39822003-01-10 03:49:02 +00003421/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003422 */
3423
3424static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003425time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003427 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003428}
3429
Tim Peters37f39822003-01-10 03:49:02 +00003430static PyObject *
3431time_minute(PyDateTime_Time *self, void *unused)
3432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003433 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003434}
3435
3436/* The name time_second conflicted with some platform header file. */
3437static PyObject *
3438py_time_second(PyDateTime_Time *self, void *unused)
3439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003440 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003441}
3442
3443static PyObject *
3444time_microsecond(PyDateTime_Time *self, void *unused)
3445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003446 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003447}
3448
3449static PyObject *
3450time_tzinfo(PyDateTime_Time *self, void *unused)
3451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003452 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3453 Py_INCREF(result);
3454 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003455}
3456
3457static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003458 {"hour", (getter)time_hour},
3459 {"minute", (getter)time_minute},
3460 {"second", (getter)py_time_second},
3461 {"microsecond", (getter)time_microsecond},
3462 {"tzinfo", (getter)time_tzinfo},
3463 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003464};
3465
3466/*
3467 * Constructors.
3468 */
3469
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003470static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003471 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003472
Tim Peters2a799bf2002-12-16 20:18:38 +00003473static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003474time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003476 PyObject *self = NULL;
3477 PyObject *state;
3478 int hour = 0;
3479 int minute = 0;
3480 int second = 0;
3481 int usecond = 0;
3482 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003484 /* Check for invocation from pickle with __getstate__ state */
3485 if (PyTuple_GET_SIZE(args) >= 1 &&
3486 PyTuple_GET_SIZE(args) <= 2 &&
3487 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3488 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3489 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3490 {
3491 PyDateTime_Time *me;
3492 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003494 if (PyTuple_GET_SIZE(args) == 2) {
3495 tzinfo = PyTuple_GET_ITEM(args, 1);
3496 if (check_tzinfo_subclass(tzinfo) < 0) {
3497 PyErr_SetString(PyExc_TypeError, "bad "
3498 "tzinfo state arg");
3499 return NULL;
3500 }
3501 }
3502 aware = (char)(tzinfo != Py_None);
3503 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3504 if (me != NULL) {
3505 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003507 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3508 me->hashcode = -1;
3509 me->hastzinfo = aware;
3510 if (aware) {
3511 Py_INCREF(tzinfo);
3512 me->tzinfo = tzinfo;
3513 }
3514 }
3515 return (PyObject *)me;
3516 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003518 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3519 &hour, &minute, &second, &usecond,
3520 &tzinfo)) {
3521 if (check_time_args(hour, minute, second, usecond) < 0)
3522 return NULL;
3523 if (check_tzinfo_subclass(tzinfo) < 0)
3524 return NULL;
3525 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3526 type);
3527 }
3528 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003529}
3530
3531/*
3532 * Destructor.
3533 */
3534
3535static void
Tim Peters37f39822003-01-10 03:49:02 +00003536time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003538 if (HASTZINFO(self)) {
3539 Py_XDECREF(self->tzinfo);
3540 }
3541 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003542}
3543
3544/*
Tim Peters855fe882002-12-22 03:43:39 +00003545 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003546 */
3547
Tim Peters2a799bf2002-12-16 20:18:38 +00003548/* These are all METH_NOARGS, so don't need to check the arglist. */
3549static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003550time_utcoffset(PyObject *self, PyObject *unused) {
3551 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003552}
3553
3554static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003555time_dst(PyObject *self, PyObject *unused) {
3556 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003557}
3558
3559static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003560time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003561 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003562}
3563
3564/*
Tim Peters37f39822003-01-10 03:49:02 +00003565 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003566 */
3567
3568static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003569time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003570{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003571 const char *type_name = Py_TYPE(self)->tp_name;
3572 int h = TIME_GET_HOUR(self);
3573 int m = TIME_GET_MINUTE(self);
3574 int s = TIME_GET_SECOND(self);
3575 int us = TIME_GET_MICROSECOND(self);
3576 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003578 if (us)
3579 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3580 type_name, h, m, s, us);
3581 else if (s)
3582 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3583 type_name, h, m, s);
3584 else
3585 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3586 if (result != NULL && HASTZINFO(self))
3587 result = append_keyword_tzinfo(result, self->tzinfo);
3588 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003589}
3590
Tim Peters37f39822003-01-10 03:49:02 +00003591static PyObject *
3592time_str(PyDateTime_Time *self)
3593{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003594 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003595}
Tim Peters2a799bf2002-12-16 20:18:38 +00003596
3597static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003598time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003600 char buf[100];
3601 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003602 int us = TIME_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003604 if (us)
3605 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3606 TIME_GET_HOUR(self),
3607 TIME_GET_MINUTE(self),
3608 TIME_GET_SECOND(self),
3609 us);
3610 else
3611 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3612 TIME_GET_HOUR(self),
3613 TIME_GET_MINUTE(self),
3614 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003615
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003616 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003617 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003619 /* We need to append the UTC offset. */
3620 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3621 Py_None) < 0) {
3622 Py_DECREF(result);
3623 return NULL;
3624 }
3625 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3626 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003627}
3628
Tim Peters37f39822003-01-10 03:49:02 +00003629static PyObject *
3630time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003632 PyObject *result;
3633 PyObject *tuple;
3634 PyObject *format;
3635 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003637 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3638 &format))
3639 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003641 /* Python's strftime does insane things with the year part of the
3642 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003643 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003644 */
3645 tuple = Py_BuildValue("iiiiiiiii",
3646 1900, 1, 1, /* year, month, day */
3647 TIME_GET_HOUR(self),
3648 TIME_GET_MINUTE(self),
3649 TIME_GET_SECOND(self),
3650 0, 1, -1); /* weekday, daynum, dst */
3651 if (tuple == NULL)
3652 return NULL;
3653 assert(PyTuple_Size(tuple) == 9);
3654 result = wrap_strftime((PyObject *)self, format, tuple,
3655 Py_None);
3656 Py_DECREF(tuple);
3657 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003658}
Tim Peters2a799bf2002-12-16 20:18:38 +00003659
3660/*
3661 * Miscellaneous methods.
3662 */
3663
Tim Peters37f39822003-01-10 03:49:02 +00003664static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003665time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003666{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003667 PyObject *result = NULL;
3668 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003669 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003670
Brian Curtindfc80e32011-08-10 20:28:54 -05003671 if (! PyTime_Check(other))
3672 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003673
3674 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003675 diff = memcmp(((PyDateTime_Time *)self)->data,
3676 ((PyDateTime_Time *)other)->data,
3677 _PyDateTime_TIME_DATASIZE);
3678 return diff_to_bool(diff, op);
3679 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003680 offset1 = time_utcoffset(self, NULL);
3681 if (offset1 == NULL)
3682 return NULL;
3683 offset2 = time_utcoffset(other, NULL);
3684 if (offset2 == NULL)
3685 goto done;
3686 /* If they're both naive, or both aware and have the same offsets,
3687 * we get off cheap. Note that if they're both naive, offset1 ==
3688 * offset2 == Py_None at this point.
3689 */
3690 if ((offset1 == offset2) ||
3691 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3692 delta_cmp(offset1, offset2) == 0)) {
3693 diff = memcmp(((PyDateTime_Time *)self)->data,
3694 ((PyDateTime_Time *)other)->data,
3695 _PyDateTime_TIME_DATASIZE);
3696 result = diff_to_bool(diff, op);
3697 }
3698 /* The hard case: both aware with different UTC offsets */
3699 else if (offset1 != Py_None && offset2 != Py_None) {
3700 int offsecs1, offsecs2;
3701 assert(offset1 != offset2); /* else last "if" handled it */
3702 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3703 TIME_GET_MINUTE(self) * 60 +
3704 TIME_GET_SECOND(self) -
3705 GET_TD_DAYS(offset1) * 86400 -
3706 GET_TD_SECONDS(offset1);
3707 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3708 TIME_GET_MINUTE(other) * 60 +
3709 TIME_GET_SECOND(other) -
3710 GET_TD_DAYS(offset2) * 86400 -
3711 GET_TD_SECONDS(offset2);
3712 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003713 if (diff == 0)
3714 diff = TIME_GET_MICROSECOND(self) -
3715 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003716 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003717 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003718 else if (op == Py_EQ) {
3719 result = Py_False;
3720 Py_INCREF(result);
3721 }
3722 else if (op == Py_NE) {
3723 result = Py_True;
3724 Py_INCREF(result);
3725 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003726 else {
3727 PyErr_SetString(PyExc_TypeError,
3728 "can't compare offset-naive and "
3729 "offset-aware times");
3730 }
3731 done:
3732 Py_DECREF(offset1);
3733 Py_XDECREF(offset2);
3734 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003735}
3736
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003737static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003738time_hash(PyDateTime_Time *self)
3739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003740 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003741 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003742
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003743 offset = time_utcoffset((PyObject *)self, NULL);
3744
3745 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003746 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003748 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003749 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003750 self->hashcode = generic_hash(
3751 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003752 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003753 PyObject *temp1, *temp2;
3754 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003755 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003756 seconds = TIME_GET_HOUR(self) * 3600 +
3757 TIME_GET_MINUTE(self) * 60 +
3758 TIME_GET_SECOND(self);
3759 microseconds = TIME_GET_MICROSECOND(self);
3760 temp1 = new_delta(0, seconds, microseconds, 1);
3761 if (temp1 == NULL) {
3762 Py_DECREF(offset);
3763 return -1;
3764 }
3765 temp2 = delta_subtract(temp1, offset);
3766 Py_DECREF(temp1);
3767 if (temp2 == NULL) {
3768 Py_DECREF(offset);
3769 return -1;
3770 }
3771 self->hashcode = PyObject_Hash(temp2);
3772 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003773 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003774 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003775 }
3776 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003777}
Tim Peters2a799bf2002-12-16 20:18:38 +00003778
Tim Peters12bf3392002-12-24 05:41:27 +00003779static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003780time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003782 PyObject *clone;
3783 PyObject *tuple;
3784 int hh = TIME_GET_HOUR(self);
3785 int mm = TIME_GET_MINUTE(self);
3786 int ss = TIME_GET_SECOND(self);
3787 int us = TIME_GET_MICROSECOND(self);
3788 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003790 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3791 time_kws,
3792 &hh, &mm, &ss, &us, &tzinfo))
3793 return NULL;
3794 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3795 if (tuple == NULL)
3796 return NULL;
3797 clone = time_new(Py_TYPE(self), tuple, NULL);
3798 Py_DECREF(tuple);
3799 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003800}
3801
Tim Peters2a799bf2002-12-16 20:18:38 +00003802static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003803time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003804{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003805 PyObject *offset, *tzinfo;
3806 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003808 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3809 /* Since utcoffset is in whole minutes, nothing can
3810 * alter the conclusion that this is nonzero.
3811 */
3812 return 1;
3813 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003814 tzinfo = GET_TIME_TZINFO(self);
3815 if (tzinfo != Py_None) {
3816 offset = call_utcoffset(tzinfo, Py_None);
3817 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003818 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003819 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3820 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003821 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003822 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003823}
3824
Tim Peters371935f2003-02-01 01:52:50 +00003825/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003826
Tim Peters33e0f382003-01-10 02:05:14 +00003827/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003828 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3829 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003830 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003831 */
3832static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003833time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 PyObject *basestate;
3836 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003838 basestate = PyBytes_FromStringAndSize((char *)self->data,
3839 _PyDateTime_TIME_DATASIZE);
3840 if (basestate != NULL) {
3841 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3842 result = PyTuple_Pack(1, basestate);
3843 else
3844 result = PyTuple_Pack(2, basestate, self->tzinfo);
3845 Py_DECREF(basestate);
3846 }
3847 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003848}
3849
3850static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003851time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003852{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003853 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003854}
3855
Tim Peters37f39822003-01-10 03:49:02 +00003856static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3859 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3860 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003862 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3863 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003865 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3866 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003868 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3869 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003871 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3872 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003874 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3875 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003877 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3878 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003880 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3881 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003884};
3885
Tim Peters37f39822003-01-10 03:49:02 +00003886static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003887PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3888\n\
3889All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03003890a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003891
Tim Peters37f39822003-01-10 03:49:02 +00003892static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003893 0, /* nb_add */
3894 0, /* nb_subtract */
3895 0, /* nb_multiply */
3896 0, /* nb_remainder */
3897 0, /* nb_divmod */
3898 0, /* nb_power */
3899 0, /* nb_negative */
3900 0, /* nb_positive */
3901 0, /* nb_absolute */
3902 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003903};
3904
Neal Norwitz227b5332006-03-22 09:28:35 +00003905static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003906 PyVarObject_HEAD_INIT(NULL, 0)
3907 "datetime.time", /* tp_name */
3908 sizeof(PyDateTime_Time), /* tp_basicsize */
3909 0, /* tp_itemsize */
3910 (destructor)time_dealloc, /* tp_dealloc */
3911 0, /* tp_print */
3912 0, /* tp_getattr */
3913 0, /* tp_setattr */
3914 0, /* tp_reserved */
3915 (reprfunc)time_repr, /* tp_repr */
3916 &time_as_number, /* tp_as_number */
3917 0, /* tp_as_sequence */
3918 0, /* tp_as_mapping */
3919 (hashfunc)time_hash, /* tp_hash */
3920 0, /* tp_call */
3921 (reprfunc)time_str, /* tp_str */
3922 PyObject_GenericGetAttr, /* tp_getattro */
3923 0, /* tp_setattro */
3924 0, /* tp_as_buffer */
3925 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3926 time_doc, /* tp_doc */
3927 0, /* tp_traverse */
3928 0, /* tp_clear */
3929 time_richcompare, /* tp_richcompare */
3930 0, /* tp_weaklistoffset */
3931 0, /* tp_iter */
3932 0, /* tp_iternext */
3933 time_methods, /* tp_methods */
3934 0, /* tp_members */
3935 time_getset, /* tp_getset */
3936 0, /* tp_base */
3937 0, /* tp_dict */
3938 0, /* tp_descr_get */
3939 0, /* tp_descr_set */
3940 0, /* tp_dictoffset */
3941 0, /* tp_init */
3942 time_alloc, /* tp_alloc */
3943 time_new, /* tp_new */
3944 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003945};
3946
3947/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003948 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003949 */
3950
Tim Petersa9bc1682003-01-11 03:39:11 +00003951/* Accessor properties. Properties for day, month, and year are inherited
3952 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003953 */
3954
3955static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003956datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003958 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003959}
3960
Tim Petersa9bc1682003-01-11 03:39:11 +00003961static PyObject *
3962datetime_minute(PyDateTime_DateTime *self, void *unused)
3963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003964 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003965}
3966
3967static PyObject *
3968datetime_second(PyDateTime_DateTime *self, void *unused)
3969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003970 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003971}
3972
3973static PyObject *
3974datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003976 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003977}
3978
3979static PyObject *
3980datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003982 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3983 Py_INCREF(result);
3984 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003985}
3986
3987static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003988 {"hour", (getter)datetime_hour},
3989 {"minute", (getter)datetime_minute},
3990 {"second", (getter)datetime_second},
3991 {"microsecond", (getter)datetime_microsecond},
3992 {"tzinfo", (getter)datetime_tzinfo},
3993 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003994};
3995
3996/*
3997 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003998 */
3999
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004000static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 "year", "month", "day", "hour", "minute", "second",
4002 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004003};
4004
Tim Peters2a799bf2002-12-16 20:18:38 +00004005static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004006datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004007{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004008 PyObject *self = NULL;
4009 PyObject *state;
4010 int year;
4011 int month;
4012 int day;
4013 int hour = 0;
4014 int minute = 0;
4015 int second = 0;
4016 int usecond = 0;
4017 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004019 /* Check for invocation from pickle with __getstate__ state */
4020 if (PyTuple_GET_SIZE(args) >= 1 &&
4021 PyTuple_GET_SIZE(args) <= 2 &&
4022 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4023 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4024 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4025 {
4026 PyDateTime_DateTime *me;
4027 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004029 if (PyTuple_GET_SIZE(args) == 2) {
4030 tzinfo = PyTuple_GET_ITEM(args, 1);
4031 if (check_tzinfo_subclass(tzinfo) < 0) {
4032 PyErr_SetString(PyExc_TypeError, "bad "
4033 "tzinfo state arg");
4034 return NULL;
4035 }
4036 }
4037 aware = (char)(tzinfo != Py_None);
4038 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4039 if (me != NULL) {
4040 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004042 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4043 me->hashcode = -1;
4044 me->hastzinfo = aware;
4045 if (aware) {
4046 Py_INCREF(tzinfo);
4047 me->tzinfo = tzinfo;
4048 }
4049 }
4050 return (PyObject *)me;
4051 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004053 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4054 &year, &month, &day, &hour, &minute,
4055 &second, &usecond, &tzinfo)) {
4056 if (check_date_args(year, month, day) < 0)
4057 return NULL;
4058 if (check_time_args(hour, minute, second, usecond) < 0)
4059 return NULL;
4060 if (check_tzinfo_subclass(tzinfo) < 0)
4061 return NULL;
4062 self = new_datetime_ex(year, month, day,
4063 hour, minute, second, usecond,
4064 tzinfo, type);
4065 }
4066 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004067}
4068
Tim Petersa9bc1682003-01-11 03:39:11 +00004069/* TM_FUNC is the shared type of localtime() and gmtime(). */
4070typedef struct tm *(*TM_FUNC)(const time_t *timer);
4071
4072/* Internal helper.
4073 * Build datetime from a time_t and a distinct count of microseconds.
4074 * Pass localtime or gmtime for f, to control the interpretation of timet.
4075 */
4076static PyObject *
4077datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004078 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004080 struct tm *tm;
Tim Petersa9bc1682003-01-11 03:39:11 +00004081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004082 tm = f(&timet);
Victor Stinner21f58932012-03-14 00:15:40 +01004083 if (tm == NULL) {
4084#ifdef EINVAL
4085 if (errno == 0)
4086 errno = EINVAL;
4087#endif
4088 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004089 }
Victor Stinner21f58932012-03-14 00:15:40 +01004090
4091 /* The platform localtime/gmtime may insert leap seconds,
4092 * indicated by tm->tm_sec > 59. We don't care about them,
4093 * except to the extent that passing them on to the datetime
4094 * constructor would raise ValueError for a reason that
4095 * made no sense to the user.
4096 */
4097 if (tm->tm_sec > 59)
4098 tm->tm_sec = 59;
4099 return PyObject_CallFunction(cls, "iiiiiiiO",
4100 tm->tm_year + 1900,
4101 tm->tm_mon + 1,
4102 tm->tm_mday,
4103 tm->tm_hour,
4104 tm->tm_min,
4105 tm->tm_sec,
4106 us,
4107 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004108}
4109
4110/* Internal helper.
4111 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4112 * to control the interpretation of the timestamp. Since a double doesn't
4113 * have enough bits to cover a datetime's full range of precision, it's
4114 * better to call datetime_from_timet_and_us provided you have a way
4115 * to get that much precision (e.g., C time() isn't good enough).
4116 */
4117static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004118datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004119 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004121 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004122 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004123
Victor Stinner5d272cc2012-03-13 13:35:55 +01004124 if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004125 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004126 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004127}
4128
4129/* Internal helper.
4130 * Build most accurate possible datetime for current time. Pass localtime or
4131 * gmtime for f as appropriate.
4132 */
4133static PyObject *
4134datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4135{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004136 _PyTime_timeval t;
4137 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004138 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4139 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004140}
4141
Larry Hastings31826802013-10-19 00:09:25 -07004142/*[clinic]
4143module datetime
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004144class datetime.datetime
Larry Hastings31826802013-10-19 00:09:25 -07004145
4146@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004147datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004148
4149 tz: object = None
4150 Timezone object.
4151
4152Returns new datetime object representing current time local to tz.
4153
4154If no tz is specified, uses local timezone.
4155[clinic]*/
4156
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004157PyDoc_STRVAR(datetime_datetime_now__doc__,
Larry Hastings31826802013-10-19 00:09:25 -07004158"Returns new datetime object representing current time local to tz.\n"
4159"\n"
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004160"datetime.datetime.now(tz=None)\n"
Larry Hastings31826802013-10-19 00:09:25 -07004161" tz\n"
4162" Timezone object.\n"
4163"\n"
4164"If no tz is specified, uses local timezone.");
4165
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004166#define DATETIME_DATETIME_NOW_METHODDEF \
4167 {"now", (PyCFunction)datetime_datetime_now, METH_VARARGS|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__},
Larry Hastings31826802013-10-19 00:09:25 -07004168
Tim Peters2a799bf2002-12-16 20:18:38 +00004169static PyObject *
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004170datetime_datetime_now_impl(PyObject *cls, PyObject *tz);
Larry Hastings31826802013-10-19 00:09:25 -07004171
4172static PyObject *
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004173datetime_datetime_now(PyObject *cls, PyObject *args, PyObject *kwargs)
Larry Hastings31826802013-10-19 00:09:25 -07004174{
4175 PyObject *return_value = NULL;
4176 static char *_keywords[] = {"tz", NULL};
4177 PyObject *tz = Py_None;
4178
4179 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4180 "|O:now", _keywords,
4181 &tz))
4182 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004183 return_value = datetime_datetime_now_impl(cls, tz);
Larry Hastings31826802013-10-19 00:09:25 -07004184
4185exit:
4186 return return_value;
4187}
4188
4189static PyObject *
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004190datetime_datetime_now_impl(PyObject *cls, PyObject *tz)
4191/*[clinic checksum: cde1daca68c9b7dca6df51759db2de1d43a39774]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004194
Larry Hastings31826802013-10-19 00:09:25 -07004195 /* Return best possible local time -- this isn't constrained by the
4196 * precision of a timestamp.
4197 */
4198 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004199 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004201 self = datetime_best_possible(cls,
Larry Hastings31826802013-10-19 00:09:25 -07004202 tz == Py_None ? localtime : gmtime,
4203 tz);
4204 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004205 /* Convert UTC to tzinfo's zone. */
4206 PyObject *temp = self;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004207
Larry Hastings31826802013-10-19 00:09:25 -07004208 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004209 Py_DECREF(temp);
4210 }
4211 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004212}
4213
Tim Petersa9bc1682003-01-11 03:39:11 +00004214/* Return best possible UTC time -- this isn't constrained by the
4215 * precision of a timestamp.
4216 */
4217static PyObject *
4218datetime_utcnow(PyObject *cls, PyObject *dummy)
4219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004220 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004221}
4222
Tim Peters2a799bf2002-12-16 20:18:38 +00004223/* Return new local datetime from timestamp (Python timestamp -- a double). */
4224static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004225datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004226{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004227 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004228 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004229 PyObject *tzinfo = Py_None;
4230 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004231
Victor Stinner5d272cc2012-03-13 13:35:55 +01004232 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004233 keywords, &timestamp, &tzinfo))
4234 return NULL;
4235 if (check_tzinfo_subclass(tzinfo) < 0)
4236 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004238 self = datetime_from_timestamp(cls,
4239 tzinfo == Py_None ? localtime : gmtime,
4240 timestamp,
4241 tzinfo);
4242 if (self != NULL && tzinfo != Py_None) {
4243 /* Convert UTC to tzinfo's zone. */
4244 PyObject *temp = self;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004245
4246 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004247 Py_DECREF(temp);
4248 }
4249 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004250}
4251
Tim Petersa9bc1682003-01-11 03:39:11 +00004252/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4253static PyObject *
4254datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4255{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004256 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004257 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004258
Victor Stinner5d272cc2012-03-13 13:35:55 +01004259 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004260 result = datetime_from_timestamp(cls, gmtime, timestamp,
4261 Py_None);
4262 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004263}
4264
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004265/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004266static PyObject *
4267datetime_strptime(PyObject *cls, PyObject *args)
4268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004269 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004270 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004271 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004272
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004273 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004274 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004275
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004276 if (module == NULL) {
4277 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004278 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004279 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004280 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004281 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4282 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004283}
4284
Tim Petersa9bc1682003-01-11 03:39:11 +00004285/* Return new datetime from date/datetime and time arguments. */
4286static PyObject *
4287datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4288{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004289 static char *keywords[] = {"date", "time", NULL};
4290 PyObject *date;
4291 PyObject *time;
4292 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004294 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4295 &PyDateTime_DateType, &date,
4296 &PyDateTime_TimeType, &time)) {
4297 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004299 if (HASTZINFO(time))
4300 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4301 result = PyObject_CallFunction(cls, "iiiiiiiO",
4302 GET_YEAR(date),
4303 GET_MONTH(date),
4304 GET_DAY(date),
4305 TIME_GET_HOUR(time),
4306 TIME_GET_MINUTE(time),
4307 TIME_GET_SECOND(time),
4308 TIME_GET_MICROSECOND(time),
4309 tzinfo);
4310 }
4311 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004312}
Tim Peters2a799bf2002-12-16 20:18:38 +00004313
4314/*
4315 * Destructor.
4316 */
4317
4318static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004319datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004320{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004321 if (HASTZINFO(self)) {
4322 Py_XDECREF(self->tzinfo);
4323 }
4324 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004325}
4326
4327/*
4328 * Indirect access to tzinfo methods.
4329 */
4330
Tim Peters2a799bf2002-12-16 20:18:38 +00004331/* These are all METH_NOARGS, so don't need to check the arglist. */
4332static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004333datetime_utcoffset(PyObject *self, PyObject *unused) {
4334 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004335}
4336
4337static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004338datetime_dst(PyObject *self, PyObject *unused) {
4339 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004340}
4341
4342static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004343datetime_tzname(PyObject *self, PyObject *unused) {
4344 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004345}
4346
4347/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004348 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004349 */
4350
Tim Petersa9bc1682003-01-11 03:39:11 +00004351/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4352 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004353 */
4354static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004355add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004356 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004358 /* Note that the C-level additions can't overflow, because of
4359 * invariant bounds on the member values.
4360 */
4361 int year = GET_YEAR(date);
4362 int month = GET_MONTH(date);
4363 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4364 int hour = DATE_GET_HOUR(date);
4365 int minute = DATE_GET_MINUTE(date);
4366 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4367 int microsecond = DATE_GET_MICROSECOND(date) +
4368 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004370 assert(factor == 1 || factor == -1);
4371 if (normalize_datetime(&year, &month, &day,
4372 &hour, &minute, &second, &microsecond) < 0)
4373 return NULL;
4374 else
4375 return new_datetime(year, month, day,
4376 hour, minute, second, microsecond,
4377 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004378}
4379
4380static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004381datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004383 if (PyDateTime_Check(left)) {
4384 /* datetime + ??? */
4385 if (PyDelta_Check(right))
4386 /* datetime + delta */
4387 return add_datetime_timedelta(
4388 (PyDateTime_DateTime *)left,
4389 (PyDateTime_Delta *)right,
4390 1);
4391 }
4392 else if (PyDelta_Check(left)) {
4393 /* delta + datetime */
4394 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4395 (PyDateTime_Delta *) left,
4396 1);
4397 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004398 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004399}
4400
4401static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004402datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004404 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004406 if (PyDateTime_Check(left)) {
4407 /* datetime - ??? */
4408 if (PyDateTime_Check(right)) {
4409 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004410 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004412
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004413 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4414 offset2 = offset1 = Py_None;
4415 Py_INCREF(offset1);
4416 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004417 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004418 else {
4419 offset1 = datetime_utcoffset(left, NULL);
4420 if (offset1 == NULL)
4421 return NULL;
4422 offset2 = datetime_utcoffset(right, NULL);
4423 if (offset2 == NULL) {
4424 Py_DECREF(offset1);
4425 return NULL;
4426 }
4427 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4428 PyErr_SetString(PyExc_TypeError,
4429 "can't subtract offset-naive and "
4430 "offset-aware datetimes");
4431 Py_DECREF(offset1);
4432 Py_DECREF(offset2);
4433 return NULL;
4434 }
4435 }
4436 if ((offset1 != offset2) &&
4437 delta_cmp(offset1, offset2) != 0) {
4438 offdiff = delta_subtract(offset1, offset2);
4439 if (offdiff == NULL) {
4440 Py_DECREF(offset1);
4441 Py_DECREF(offset2);
4442 return NULL;
4443 }
4444 }
4445 Py_DECREF(offset1);
4446 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004447 delta_d = ymd_to_ord(GET_YEAR(left),
4448 GET_MONTH(left),
4449 GET_DAY(left)) -
4450 ymd_to_ord(GET_YEAR(right),
4451 GET_MONTH(right),
4452 GET_DAY(right));
4453 /* These can't overflow, since the values are
4454 * normalized. At most this gives the number of
4455 * seconds in one day.
4456 */
4457 delta_s = (DATE_GET_HOUR(left) -
4458 DATE_GET_HOUR(right)) * 3600 +
4459 (DATE_GET_MINUTE(left) -
4460 DATE_GET_MINUTE(right)) * 60 +
4461 (DATE_GET_SECOND(left) -
4462 DATE_GET_SECOND(right));
4463 delta_us = DATE_GET_MICROSECOND(left) -
4464 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004465 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004466 if (result == NULL)
4467 return NULL;
4468
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004469 if (offdiff != NULL) {
4470 PyObject *temp = result;
4471 result = delta_subtract(result, offdiff);
4472 Py_DECREF(temp);
4473 Py_DECREF(offdiff);
4474 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004475 }
4476 else if (PyDelta_Check(right)) {
4477 /* datetime - delta */
4478 result = add_datetime_timedelta(
4479 (PyDateTime_DateTime *)left,
4480 (PyDateTime_Delta *)right,
4481 -1);
4482 }
4483 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004485 if (result == Py_NotImplemented)
4486 Py_INCREF(result);
4487 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004488}
4489
4490/* Various ways to turn a datetime into a string. */
4491
4492static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004493datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004495 const char *type_name = Py_TYPE(self)->tp_name;
4496 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004498 if (DATE_GET_MICROSECOND(self)) {
4499 baserepr = PyUnicode_FromFormat(
4500 "%s(%d, %d, %d, %d, %d, %d, %d)",
4501 type_name,
4502 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4503 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4504 DATE_GET_SECOND(self),
4505 DATE_GET_MICROSECOND(self));
4506 }
4507 else if (DATE_GET_SECOND(self)) {
4508 baserepr = PyUnicode_FromFormat(
4509 "%s(%d, %d, %d, %d, %d, %d)",
4510 type_name,
4511 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4512 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4513 DATE_GET_SECOND(self));
4514 }
4515 else {
4516 baserepr = PyUnicode_FromFormat(
4517 "%s(%d, %d, %d, %d, %d)",
4518 type_name,
4519 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4520 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4521 }
4522 if (baserepr == NULL || ! HASTZINFO(self))
4523 return baserepr;
4524 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004525}
4526
Tim Petersa9bc1682003-01-11 03:39:11 +00004527static PyObject *
4528datetime_str(PyDateTime_DateTime *self)
4529{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004530 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004531}
Tim Peters2a799bf2002-12-16 20:18:38 +00004532
4533static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004534datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004535{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004536 int sep = 'T';
4537 static char *keywords[] = {"sep", NULL};
4538 char buffer[100];
4539 PyObject *result;
4540 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004542 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4543 return NULL;
4544 if (us)
4545 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4546 GET_YEAR(self), GET_MONTH(self),
4547 GET_DAY(self), (int)sep,
4548 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4549 DATE_GET_SECOND(self), us);
4550 else
4551 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4552 GET_YEAR(self), GET_MONTH(self),
4553 GET_DAY(self), (int)sep,
4554 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4555 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004557 if (!result || !HASTZINFO(self))
4558 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004560 /* We need to append the UTC offset. */
4561 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4562 (PyObject *)self) < 0) {
4563 Py_DECREF(result);
4564 return NULL;
4565 }
4566 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4567 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004568}
4569
Tim Petersa9bc1682003-01-11 03:39:11 +00004570static PyObject *
4571datetime_ctime(PyDateTime_DateTime *self)
4572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 return format_ctime((PyDateTime_Date *)self,
4574 DATE_GET_HOUR(self),
4575 DATE_GET_MINUTE(self),
4576 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004577}
4578
Tim Peters2a799bf2002-12-16 20:18:38 +00004579/* Miscellaneous methods. */
4580
Tim Petersa9bc1682003-01-11 03:39:11 +00004581static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004582datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004583{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004584 PyObject *result = NULL;
4585 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004586 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004588 if (! PyDateTime_Check(other)) {
4589 if (PyDate_Check(other)) {
4590 /* Prevent invocation of date_richcompare. We want to
4591 return NotImplemented here to give the other object
4592 a chance. But since DateTime is a subclass of
4593 Date, if the other object is a Date, it would
4594 compute an ordering based on the date part alone,
4595 and we don't want that. So force unequal or
4596 uncomparable here in that case. */
4597 if (op == Py_EQ)
4598 Py_RETURN_FALSE;
4599 if (op == Py_NE)
4600 Py_RETURN_TRUE;
4601 return cmperror(self, other);
4602 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004603 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004604 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004605
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004606 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004607 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4608 ((PyDateTime_DateTime *)other)->data,
4609 _PyDateTime_DATETIME_DATASIZE);
4610 return diff_to_bool(diff, op);
4611 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004612 offset1 = datetime_utcoffset(self, NULL);
4613 if (offset1 == NULL)
4614 return NULL;
4615 offset2 = datetime_utcoffset(other, NULL);
4616 if (offset2 == NULL)
4617 goto done;
4618 /* If they're both naive, or both aware and have the same offsets,
4619 * we get off cheap. Note that if they're both naive, offset1 ==
4620 * offset2 == Py_None at this point.
4621 */
4622 if ((offset1 == offset2) ||
4623 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4624 delta_cmp(offset1, offset2) == 0)) {
4625 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4626 ((PyDateTime_DateTime *)other)->data,
4627 _PyDateTime_DATETIME_DATASIZE);
4628 result = diff_to_bool(diff, op);
4629 }
4630 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004632
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004633 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004634 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4635 other);
4636 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004637 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004638 diff = GET_TD_DAYS(delta);
4639 if (diff == 0)
4640 diff = GET_TD_SECONDS(delta) |
4641 GET_TD_MICROSECONDS(delta);
4642 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004643 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004644 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004645 else if (op == Py_EQ) {
4646 result = Py_False;
4647 Py_INCREF(result);
4648 }
4649 else if (op == Py_NE) {
4650 result = Py_True;
4651 Py_INCREF(result);
4652 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004653 else {
4654 PyErr_SetString(PyExc_TypeError,
4655 "can't compare offset-naive and "
4656 "offset-aware datetimes");
4657 }
4658 done:
4659 Py_DECREF(offset1);
4660 Py_XDECREF(offset2);
4661 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004662}
4663
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004664static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004665datetime_hash(PyDateTime_DateTime *self)
4666{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004667 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004668 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004669
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004670 offset = datetime_utcoffset((PyObject *)self, NULL);
4671
4672 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004673 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004675 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004676 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004677 self->hashcode = generic_hash(
4678 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004679 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004680 PyObject *temp1, *temp2;
4681 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 assert(HASTZINFO(self));
4684 days = ymd_to_ord(GET_YEAR(self),
4685 GET_MONTH(self),
4686 GET_DAY(self));
4687 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004688 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004689 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004690 temp1 = new_delta(days, seconds,
4691 DATE_GET_MICROSECOND(self),
4692 1);
4693 if (temp1 == NULL) {
4694 Py_DECREF(offset);
4695 return -1;
4696 }
4697 temp2 = delta_subtract(temp1, offset);
4698 Py_DECREF(temp1);
4699 if (temp2 == NULL) {
4700 Py_DECREF(offset);
4701 return -1;
4702 }
4703 self->hashcode = PyObject_Hash(temp2);
4704 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004705 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004706 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004707 }
4708 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004709}
Tim Peters2a799bf2002-12-16 20:18:38 +00004710
4711static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004712datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004714 PyObject *clone;
4715 PyObject *tuple;
4716 int y = GET_YEAR(self);
4717 int m = GET_MONTH(self);
4718 int d = GET_DAY(self);
4719 int hh = DATE_GET_HOUR(self);
4720 int mm = DATE_GET_MINUTE(self);
4721 int ss = DATE_GET_SECOND(self);
4722 int us = DATE_GET_MICROSECOND(self);
4723 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004725 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4726 datetime_kws,
4727 &y, &m, &d, &hh, &mm, &ss, &us,
4728 &tzinfo))
4729 return NULL;
4730 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4731 if (tuple == NULL)
4732 return NULL;
4733 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4734 Py_DECREF(tuple);
4735 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004736}
4737
4738static PyObject *
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004739local_timezone(PyDateTime_DateTime *utc_time)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004740{
4741 PyObject *result = NULL;
4742 struct tm *timep;
4743 time_t timestamp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004744 PyObject *delta;
4745 PyObject *one_second;
4746 PyObject *seconds;
4747 PyObject *nameo = NULL;
4748 const char *zone = NULL;
4749
4750 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
4751 if (delta == NULL)
4752 return NULL;
4753 one_second = new_delta(0, 1, 0, 0);
4754 if (one_second == NULL)
4755 goto error;
4756 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
4757 (PyDateTime_Delta *)one_second);
4758 Py_DECREF(one_second);
4759 if (seconds == NULL)
4760 goto error;
4761 Py_DECREF(delta);
4762 timestamp = PyLong_AsLong(seconds);
4763 Py_DECREF(seconds);
4764 if (timestamp == -1 && PyErr_Occurred())
4765 return NULL;
4766 timep = localtime(&timestamp);
4767#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004768 zone = timep->tm_zone;
4769 delta = new_delta(0, timep->tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004770#else /* HAVE_STRUCT_TM_TM_ZONE */
4771 {
4772 PyObject *local_time;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004773 local_time = new_datetime(timep->tm_year + 1900, timep->tm_mon + 1,
4774 timep->tm_mday, timep->tm_hour, timep->tm_min,
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004775 timep->tm_sec, DATE_GET_MICROSECOND(utc_time),
4776 utc_time->tzinfo);
4777 if (local_time == NULL)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004778 goto error;
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004779 delta = datetime_subtract(local_time, (PyObject*)utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004780 /* XXX: before relying on tzname, we should compare delta
4781 to the offset implied by timezone/altzone */
4782 if (daylight && timep->tm_isdst >= 0)
4783 zone = tzname[timep->tm_isdst % 2];
4784 else
4785 zone = tzname[0];
4786 Py_DECREF(local_time);
4787 }
4788#endif /* HAVE_STRUCT_TM_TM_ZONE */
4789 if (zone != NULL) {
4790 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
4791 if (nameo == NULL)
4792 goto error;
4793 }
4794 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02004795 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004796 error:
4797 Py_DECREF(delta);
4798 return result;
4799}
4800
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004801static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00004802datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004803{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004804 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004805 PyObject *offset;
4806 PyObject *temp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004807 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004808 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004809
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004810 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
4811 &tzinfo))
4812 return NULL;
4813
4814 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004815 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004817 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4818 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004820 /* Conversion to self's own time zone is a NOP. */
4821 if (self->tzinfo == tzinfo) {
4822 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004823 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004824 }
Tim Peters521fc152002-12-31 17:36:56 +00004825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004826 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004827 offset = datetime_utcoffset((PyObject *)self, NULL);
4828 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004829 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004830 if (offset == Py_None) {
4831 Py_DECREF(offset);
4832 NeedAware:
4833 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4834 "a naive datetime");
4835 return NULL;
4836 }
Tim Petersf3615152003-01-01 21:51:37 +00004837
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004838 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004839 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4840 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004841 Py_DECREF(offset);
4842 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004843 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004845 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004846 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004847 if (tzinfo == Py_None) {
4848 tzinfo = local_timezone(result);
4849 if (tzinfo == NULL) {
4850 Py_DECREF(result);
4851 return NULL;
4852 }
4853 }
4854 else
4855 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004856 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004857 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004858
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004859 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004860 result = (PyDateTime_DateTime *)
4861 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004862 Py_DECREF(temp);
4863
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004864 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004865}
4866
4867static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004868datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004869{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004870 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004872 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004873 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004874
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004875 dst = call_dst(self->tzinfo, (PyObject *)self);
4876 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004877 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004878
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004879 if (dst != Py_None)
4880 dstflag = delta_bool((PyDateTime_Delta *)dst);
4881 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 }
4883 return build_struct_time(GET_YEAR(self),
4884 GET_MONTH(self),
4885 GET_DAY(self),
4886 DATE_GET_HOUR(self),
4887 DATE_GET_MINUTE(self),
4888 DATE_GET_SECOND(self),
4889 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004890}
4891
4892static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04004893datetime_timestamp(PyDateTime_DateTime *self)
4894{
4895 PyObject *result;
4896
4897 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4898 PyObject *delta;
4899 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
4900 if (delta == NULL)
4901 return NULL;
4902 result = delta_total_seconds(delta);
4903 Py_DECREF(delta);
4904 }
4905 else {
4906 struct tm time;
4907 time_t timestamp;
4908 memset((void *) &time, '\0', sizeof(struct tm));
4909 time.tm_year = GET_YEAR(self) - 1900;
4910 time.tm_mon = GET_MONTH(self) - 1;
4911 time.tm_mday = GET_DAY(self);
4912 time.tm_hour = DATE_GET_HOUR(self);
4913 time.tm_min = DATE_GET_MINUTE(self);
4914 time.tm_sec = DATE_GET_SECOND(self);
4915 time.tm_wday = -1;
4916 time.tm_isdst = -1;
4917 timestamp = mktime(&time);
Victor Stinner93037492013-06-25 22:54:35 +02004918 if (timestamp == (time_t)(-1)
4919#ifndef _AIX
4920 /* Return value of -1 does not necessarily mean an error,
4921 * but tm_wday cannot remain set to -1 if mktime succeeded. */
4922 && time.tm_wday == -1
4923#else
4924 /* on AIX, tm_wday is always sets, even on error */
4925#endif
4926 )
4927 {
Alexander Belopolskya4415142012-06-08 12:33:09 -04004928 PyErr_SetString(PyExc_OverflowError,
4929 "timestamp out of range");
4930 return NULL;
4931 }
4932 result = PyFloat_FromDouble(timestamp + DATE_GET_MICROSECOND(self) / 1e6);
4933 }
4934 return result;
4935}
4936
4937static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004938datetime_getdate(PyDateTime_DateTime *self)
4939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004940 return new_date(GET_YEAR(self),
4941 GET_MONTH(self),
4942 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004943}
4944
4945static PyObject *
4946datetime_gettime(PyDateTime_DateTime *self)
4947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004948 return new_time(DATE_GET_HOUR(self),
4949 DATE_GET_MINUTE(self),
4950 DATE_GET_SECOND(self),
4951 DATE_GET_MICROSECOND(self),
4952 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004953}
4954
4955static PyObject *
4956datetime_gettimetz(PyDateTime_DateTime *self)
4957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004958 return new_time(DATE_GET_HOUR(self),
4959 DATE_GET_MINUTE(self),
4960 DATE_GET_SECOND(self),
4961 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004962 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004963}
4964
4965static PyObject *
4966datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004967{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004968 int y, m, d, hh, mm, ss;
4969 PyObject *tzinfo;
4970 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004971
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004972 tzinfo = GET_DT_TZINFO(self);
4973 if (tzinfo == Py_None) {
4974 utcself = self;
4975 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004976 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004977 else {
4978 PyObject *offset;
4979 offset = call_utcoffset(tzinfo, (PyObject *)self);
4980 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004981 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004982 if (offset == Py_None) {
4983 Py_DECREF(offset);
4984 utcself = self;
4985 Py_INCREF(utcself);
4986 }
4987 else {
4988 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4989 (PyDateTime_Delta *)offset, -1);
4990 Py_DECREF(offset);
4991 if (utcself == NULL)
4992 return NULL;
4993 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004994 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004995 y = GET_YEAR(utcself);
4996 m = GET_MONTH(utcself);
4997 d = GET_DAY(utcself);
4998 hh = DATE_GET_HOUR(utcself);
4999 mm = DATE_GET_MINUTE(utcself);
5000 ss = DATE_GET_SECOND(utcself);
5001
5002 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005003 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005004}
5005
Tim Peters371935f2003-02-01 01:52:50 +00005006/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005007
Tim Petersa9bc1682003-01-11 03:39:11 +00005008/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005009 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5010 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005011 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005012 */
5013static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005014datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005015{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005016 PyObject *basestate;
5017 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005019 basestate = PyBytes_FromStringAndSize((char *)self->data,
5020 _PyDateTime_DATETIME_DATASIZE);
5021 if (basestate != NULL) {
5022 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5023 result = PyTuple_Pack(1, basestate);
5024 else
5025 result = PyTuple_Pack(2, basestate, self->tzinfo);
5026 Py_DECREF(basestate);
5027 }
5028 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005029}
5030
5031static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00005032datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00005033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005034 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00005035}
5036
Tim Petersa9bc1682003-01-11 03:39:11 +00005037static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005039 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005040
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005041 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005043 {"utcnow", (PyCFunction)datetime_utcnow,
5044 METH_NOARGS | METH_CLASS,
5045 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005047 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5048 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5049 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005051 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5052 METH_VARARGS | METH_CLASS,
5053 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
5054 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005056 {"strptime", (PyCFunction)datetime_strptime,
5057 METH_VARARGS | METH_CLASS,
5058 PyDoc_STR("string, format -> new datetime parsed from a string "
5059 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005061 {"combine", (PyCFunction)datetime_combine,
5062 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5063 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005065 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005067 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5068 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005070 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5071 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005073 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5074 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005076 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5077 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005079 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5080 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005081
Alexander Belopolskya4415142012-06-08 12:33:09 -04005082 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5083 PyDoc_STR("Return POSIX timestamp as float.")},
5084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005085 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5086 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005088 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5089 PyDoc_STR("[sep] -> string in ISO 8601 format, "
5090 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
5091 "sep is used to separate the year from the time, and "
5092 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005094 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5095 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005097 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5098 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005100 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5101 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005103 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5104 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005106 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5107 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005109 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5110 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005112 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005113};
5114
Tim Petersa9bc1682003-01-11 03:39:11 +00005115static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005116PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5117\n\
5118The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005119instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005120
Tim Petersa9bc1682003-01-11 03:39:11 +00005121static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005122 datetime_add, /* nb_add */
5123 datetime_subtract, /* nb_subtract */
5124 0, /* nb_multiply */
5125 0, /* nb_remainder */
5126 0, /* nb_divmod */
5127 0, /* nb_power */
5128 0, /* nb_negative */
5129 0, /* nb_positive */
5130 0, /* nb_absolute */
5131 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005132};
5133
Neal Norwitz227b5332006-03-22 09:28:35 +00005134static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005135 PyVarObject_HEAD_INIT(NULL, 0)
5136 "datetime.datetime", /* tp_name */
5137 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5138 0, /* tp_itemsize */
5139 (destructor)datetime_dealloc, /* tp_dealloc */
5140 0, /* tp_print */
5141 0, /* tp_getattr */
5142 0, /* tp_setattr */
5143 0, /* tp_reserved */
5144 (reprfunc)datetime_repr, /* tp_repr */
5145 &datetime_as_number, /* tp_as_number */
5146 0, /* tp_as_sequence */
5147 0, /* tp_as_mapping */
5148 (hashfunc)datetime_hash, /* tp_hash */
5149 0, /* tp_call */
5150 (reprfunc)datetime_str, /* tp_str */
5151 PyObject_GenericGetAttr, /* tp_getattro */
5152 0, /* tp_setattro */
5153 0, /* tp_as_buffer */
5154 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5155 datetime_doc, /* tp_doc */
5156 0, /* tp_traverse */
5157 0, /* tp_clear */
5158 datetime_richcompare, /* tp_richcompare */
5159 0, /* tp_weaklistoffset */
5160 0, /* tp_iter */
5161 0, /* tp_iternext */
5162 datetime_methods, /* tp_methods */
5163 0, /* tp_members */
5164 datetime_getset, /* tp_getset */
5165 &PyDateTime_DateType, /* tp_base */
5166 0, /* tp_dict */
5167 0, /* tp_descr_get */
5168 0, /* tp_descr_set */
5169 0, /* tp_dictoffset */
5170 0, /* tp_init */
5171 datetime_alloc, /* tp_alloc */
5172 datetime_new, /* tp_new */
5173 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005174};
5175
5176/* ---------------------------------------------------------------------------
5177 * Module methods and initialization.
5178 */
5179
5180static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005181 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005182};
5183
Tim Peters9ddf40b2004-06-20 22:41:32 +00005184/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5185 * datetime.h.
5186 */
5187static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005188 &PyDateTime_DateType,
5189 &PyDateTime_DateTimeType,
5190 &PyDateTime_TimeType,
5191 &PyDateTime_DeltaType,
5192 &PyDateTime_TZInfoType,
5193 new_date_ex,
5194 new_datetime_ex,
5195 new_time_ex,
5196 new_delta_ex,
5197 datetime_fromtimestamp,
5198 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005199};
5200
5201
Martin v. Löwis1a214512008-06-11 05:26:20 +00005202
5203static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005204 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005205 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005206 "Fast implementation of the datetime type.",
5207 -1,
5208 module_methods,
5209 NULL,
5210 NULL,
5211 NULL,
5212 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005213};
5214
Tim Peters2a799bf2002-12-16 20:18:38 +00005215PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005216PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005218 PyObject *m; /* a module object */
5219 PyObject *d; /* its dict */
5220 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005221 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005223 m = PyModule_Create(&datetimemodule);
5224 if (m == NULL)
5225 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005227 if (PyType_Ready(&PyDateTime_DateType) < 0)
5228 return NULL;
5229 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5230 return NULL;
5231 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5232 return NULL;
5233 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5234 return NULL;
5235 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5236 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005237 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5238 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005240 /* timedelta values */
5241 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 x = new_delta(0, 0, 1, 0);
5244 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5245 return NULL;
5246 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005248 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5249 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5250 return NULL;
5251 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005253 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5254 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5255 return NULL;
5256 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005258 /* date values */
5259 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005261 x = new_date(1, 1, 1);
5262 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5263 return NULL;
5264 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005266 x = new_date(MAXYEAR, 12, 31);
5267 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5268 return NULL;
5269 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005271 x = new_delta(1, 0, 0, 0);
5272 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5273 return NULL;
5274 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005276 /* time values */
5277 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005279 x = new_time(0, 0, 0, 0, Py_None);
5280 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5281 return NULL;
5282 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005284 x = new_time(23, 59, 59, 999999, Py_None);
5285 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5286 return NULL;
5287 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005289 x = new_delta(0, 0, 1, 0);
5290 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5291 return NULL;
5292 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005294 /* datetime values */
5295 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005297 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5298 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5299 return NULL;
5300 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005302 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5303 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5304 return NULL;
5305 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005307 x = new_delta(0, 0, 1, 0);
5308 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5309 return NULL;
5310 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005311
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005312 /* timezone values */
5313 d = PyDateTime_TimeZoneType.tp_dict;
5314
5315 delta = new_delta(0, 0, 0, 0);
5316 if (delta == NULL)
5317 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005318 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005319 Py_DECREF(delta);
5320 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5321 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005322 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005323
5324 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5325 if (delta == NULL)
5326 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005327 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005328 Py_DECREF(delta);
5329 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5330 return NULL;
5331 Py_DECREF(x);
5332
5333 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5334 if (delta == NULL)
5335 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005336 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005337 Py_DECREF(delta);
5338 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5339 return NULL;
5340 Py_DECREF(x);
5341
Alexander Belopolskya4415142012-06-08 12:33:09 -04005342 /* Epoch */
5343 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
5344 PyDateTime_TimeZone_UTC);
5345 if (PyDateTime_Epoch == NULL)
5346 return NULL;
5347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005348 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005349 PyModule_AddIntMacro(m, MINYEAR);
5350 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005352 Py_INCREF(&PyDateTime_DateType);
5353 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005355 Py_INCREF(&PyDateTime_DateTimeType);
5356 PyModule_AddObject(m, "datetime",
5357 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005359 Py_INCREF(&PyDateTime_TimeType);
5360 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005362 Py_INCREF(&PyDateTime_DeltaType);
5363 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005365 Py_INCREF(&PyDateTime_TZInfoType);
5366 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005367
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005368 Py_INCREF(&PyDateTime_TimeZoneType);
5369 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005371 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5372 if (x == NULL)
5373 return NULL;
5374 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005376 /* A 4-year cycle has an extra leap day over what we'd get from
5377 * pasting together 4 single years.
5378 */
5379 assert(DI4Y == 4 * 365 + 1);
5380 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005382 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5383 * get from pasting together 4 100-year cycles.
5384 */
5385 assert(DI400Y == 4 * DI100Y + 1);
5386 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005388 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5389 * pasting together 25 4-year cycles.
5390 */
5391 assert(DI100Y == 25 * DI4Y - 1);
5392 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005393
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005394 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005395 us_per_ms = PyLong_FromLong(1000);
5396 us_per_second = PyLong_FromLong(1000000);
5397 us_per_minute = PyLong_FromLong(60000000);
5398 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005399 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005400 us_per_minute == NULL || seconds_per_day == NULL)
5401 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005403 /* The rest are too big for 32-bit ints, but even
5404 * us_per_week fits in 40 bits, so doubles should be exact.
5405 */
5406 us_per_hour = PyLong_FromDouble(3600000000.0);
5407 us_per_day = PyLong_FromDouble(86400000000.0);
5408 us_per_week = PyLong_FromDouble(604800000000.0);
5409 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5410 return NULL;
5411 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005412}
Tim Petersf3615152003-01-01 21:51:37 +00005413
5414/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005415Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005416 x.n = x stripped of its timezone -- its naive time.
5417 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005418 return None
Tim Petersf3615152003-01-01 21:51:37 +00005419 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005420 return None
Tim Petersf3615152003-01-01 21:51:37 +00005421 x.s = x's standard offset, x.o - x.d
5422
5423Now some derived rules, where k is a duration (timedelta).
5424
54251. x.o = x.s + x.d
5426 This follows from the definition of x.s.
5427
Tim Petersc5dc4da2003-01-02 17:55:03 +000054282. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005429 This is actually a requirement, an assumption we need to make about
5430 sane tzinfo classes.
5431
54323. The naive UTC time corresponding to x is x.n - x.o.
5433 This is again a requirement for a sane tzinfo class.
5434
54354. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005436 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005437
Tim Petersc5dc4da2003-01-02 17:55:03 +000054385. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005439 Again follows from how arithmetic is defined.
5440
Tim Peters8bb5ad22003-01-24 02:44:45 +00005441Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005442(meaning that the various tzinfo methods exist, and don't blow up or return
5443None when called).
5444
Tim Petersa9bc1682003-01-11 03:39:11 +00005445The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005446x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005447
5448By #3, we want
5449
Tim Peters8bb5ad22003-01-24 02:44:45 +00005450 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005451
5452The algorithm starts by attaching tz to x.n, and calling that y. So
5453x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5454becomes true; in effect, we want to solve [2] for k:
5455
Tim Peters8bb5ad22003-01-24 02:44:45 +00005456 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005457
5458By #1, this is the same as
5459
Tim Peters8bb5ad22003-01-24 02:44:45 +00005460 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005461
5462By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5463Substituting that into [3],
5464
Tim Peters8bb5ad22003-01-24 02:44:45 +00005465 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5466 k - (y+k).s - (y+k).d = 0; rearranging,
5467 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5468 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005469
Tim Peters8bb5ad22003-01-24 02:44:45 +00005470On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5471approximate k by ignoring the (y+k).d term at first. Note that k can't be
5472very large, since all offset-returning methods return a duration of magnitude
5473less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5474be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005475
5476In any case, the new value is
5477
Tim Peters8bb5ad22003-01-24 02:44:45 +00005478 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005479
Tim Peters8bb5ad22003-01-24 02:44:45 +00005480It's helpful to step back at look at [4] from a higher level: it's simply
5481mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005482
5483At this point, if
5484
Tim Peters8bb5ad22003-01-24 02:44:45 +00005485 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005486
5487we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005488at the start of daylight time. Picture US Eastern for concreteness. The wall
5489time 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 +00005490sense then. The docs ask that an Eastern tzinfo class consider such a time to
5491be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5492on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005493the only spelling that makes sense on the local wall clock.
5494
Tim Petersc5dc4da2003-01-02 17:55:03 +00005495In fact, if [5] holds at this point, we do have the standard-time spelling,
5496but that takes a bit of proof. We first prove a stronger result. What's the
5497difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005498
Tim Peters8bb5ad22003-01-24 02:44:45 +00005499 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005500
Tim Petersc5dc4da2003-01-02 17:55:03 +00005501Now
5502 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005503 (y + y.s).n = by #5
5504 y.n + y.s = since y.n = x.n
5505 x.n + y.s = since z and y are have the same tzinfo member,
5506 y.s = z.s by #2
5507 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005508
Tim Petersc5dc4da2003-01-02 17:55:03 +00005509Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005510
Tim Petersc5dc4da2003-01-02 17:55:03 +00005511 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005512 x.n - ((x.n + z.s) - z.o) = expanding
5513 x.n - x.n - z.s + z.o = cancelling
5514 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005515 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005516
Tim Petersc5dc4da2003-01-02 17:55:03 +00005517So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005518
Tim Petersc5dc4da2003-01-02 17:55:03 +00005519If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005520spelling we wanted in the endcase described above. We're done. Contrarily,
5521if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005522
Tim Petersc5dc4da2003-01-02 17:55:03 +00005523If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5524add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005525local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005526
Tim Petersc5dc4da2003-01-02 17:55:03 +00005527Let
Tim Petersf3615152003-01-01 21:51:37 +00005528
Tim Peters4fede1a2003-01-04 00:26:59 +00005529 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005530
Tim Peters4fede1a2003-01-04 00:26:59 +00005531and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005532
Tim Peters8bb5ad22003-01-24 02:44:45 +00005533 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005534
Tim Peters8bb5ad22003-01-24 02:44:45 +00005535If so, we're done. If not, the tzinfo class is insane, according to the
5536assumptions we've made. This also requires a bit of proof. As before, let's
5537compute the difference between the LHS and RHS of [8] (and skipping some of
5538the justifications for the kinds of substitutions we've done several times
5539already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005540
Tim Peters8bb5ad22003-01-24 02:44:45 +00005541 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005542 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5543 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5544 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5545 - z.n + z.n - z.o + z'.o = cancel z.n
5546 - z.o + z'.o = #1 twice
5547 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5548 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005549
5550So 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 +00005551we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5552return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005553
Tim Peters8bb5ad22003-01-24 02:44:45 +00005554How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5555a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5556would have to change the result dst() returns: we start in DST, and moving
5557a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005558
Tim Peters8bb5ad22003-01-24 02:44:45 +00005559There isn't a sane case where this can happen. The closest it gets is at
5560the end of DST, where there's an hour in UTC with no spelling in a hybrid
5561tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5562that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5563UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5564time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5565clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5566standard time. Since that's what the local clock *does*, we want to map both
5567UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005568in local time, but so it goes -- it's the way the local clock works.
5569
Tim Peters8bb5ad22003-01-24 02:44:45 +00005570When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5571so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5572z' = 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 +00005573(correctly) concludes that z' is not UTC-equivalent to x.
5574
5575Because we know z.d said z was in daylight time (else [5] would have held and
5576we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005577and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005578return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5579but the reasoning doesn't depend on the example -- it depends on there being
5580two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005581z' must be in standard time, and is the spelling we want in this case.
5582
5583Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5584concerned (because it takes z' as being in standard time rather than the
5585daylight time we intend here), but returning it gives the real-life "local
5586clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5587tz.
5588
5589When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5590the 1:MM standard time spelling we want.
5591
5592So how can this break? One of the assumptions must be violated. Two
5593possibilities:
5594
55951) [2] effectively says that y.s is invariant across all y belong to a given
5596 time zone. This isn't true if, for political reasons or continental drift,
5597 a region decides to change its base offset from UTC.
5598
55992) There may be versions of "double daylight" time where the tail end of
5600 the analysis gives up a step too early. I haven't thought about that
5601 enough to say.
5602
5603In any case, it's clear that the default fromutc() is strong enough to handle
5604"almost all" time zones: so long as the standard offset is invariant, it
5605doesn't matter if daylight time transition points change from year to year, or
5606if daylight time is skipped in some years; it doesn't matter how large or
5607small dst() may get within its bounds; and it doesn't even matter if some
5608perverse time zone returns a negative dst()). So a breaking case must be
5609pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005610--------------------------------------------------------------------------- */